微信企業號開發-如何建立連線
1、企業應用呼叫企業號提供的介面,管理或查詢企業號後臺所管理的資源、或給成員傳送訊息等,以下稱主動呼叫模式。
2、企業號把使用者傳送的訊息或使用者觸發的事件推送給企業應用,由企業應用處理,以下稱回撥模式。
3、使用者在微信中閱讀企業應用下發的H5頁面,該頁面可以呼叫微信提供的原生介面,使用微信開放的終端能力,以下稱JSAPI模式。
通過這三種連線方式的結合,你可以在企業號中建立功能強大的移動輕應用,並依託微信數億活躍使用者,幫助企業方便、快捷地實現應用的部署,並確保應用的活躍度。
一、主動呼叫
1、簡述
主動呼叫是最基本的連線模式,當你的應用呼叫企業號時,需。
在每次主動呼叫企業號介面時需要帶上AccessToken引數。AccessToken引數由CorpID和Secret換取。
CorpID是企業號的標識,每個企業號擁有一個唯一的CorpID;Secret是管理組憑證金鑰。
系統管理員可通過管理端的許可權管理功能建立管理組,分配管理組對應用、通訊錄、介面的訪問許可權。完成後,管理組即可獲得唯一的secret。系統管理員可通過許可權管理檢視所有管理組的secret,其他管理員可通過設定中的開發者憑據檢視。
當企業應用呼叫企業號介面時,企業號後臺為根據此次訪問的AccessToken,校驗訪問的合法性以及所對應的管理組的管理許可權以返回相應的結果。
注:你應該審慎配置管理組的許可權,夠用即好,許可權過大會增加誤操作可能性及資訊保安隱患。
2、獲取AccessToken
AccessToken是企業號的全域性唯一票據,呼叫介面時需攜帶AccessToken。
AccessToken需要用CorpID和Secret來換取,不同的Secret會返回不同的AccessToken。正 常情況下AccessToken有效期為7200秒,有效期內重複獲取返回相同結果,並自動續期。由於獲取access_token的api呼叫次數非常 有限,建議企業全域性儲存與更新access_token,頻繁重新整理access_token會導致api呼叫受限,影響自身業務
- 請求說明
Https請求方式: GET
- 引數說明
- 許可權說明
每個secret代表了對應用、通訊錄、介面的不同許可權;不同的管理組擁有不同的secret。
- 返回說明
a)正確的Json返回結果:
- {
- "access_token": "accesstoken000001",
- }
引數 | 說明 |
---|---|
access_token | 獲取到的憑證 |
b)錯誤的Json返回示例:
- {
- "errcode": 43003,
- "errmsg": "require https"
- }
3、主動呼叫的頻率限制
當你獲取到AccessToken時,你的應用就可以成功呼叫企業號後臺所提供的各種介面以管理或訪問企業號後臺的資源或給企業號成員發訊息。
為了防止企業應用的程式錯誤而引發企業號伺服器負載異常,預設情況下,每個企業號呼叫介面都有一定的頻率限制,當超過此限制時,呼叫對應介面會收到相應錯誤碼。
以下是當前預設的頻率限制,企業號後臺可能會根據運營情況調整此閾值:
- 基礎頻率
每企業呼叫單個cgi/api不可超過1000次/分,30000次/小時
每ip呼叫單個cgi/api不可超過2000次/分,60000次/小時
每ip獲取AccessToken不可超過300次/小時
- 發訊息頻率
每企業不可超過200次/分鐘;不可超過帳號上限數*30人次/天
- 建立帳號頻率
每企業建立帳號數不可超過帳號上限數*3/月
二、回撥模式
官方解釋
1、開啟應用的回撥模式
在回撥模式下,企業不僅可以主動呼叫企業號介面,還可以接收使用者的訊息或事件。接收的資訊使用XML資料格式、UTF8編碼,並以AES方式加密.
企業號的每個應用都有自己的回撥模式開關。在管理端開啟並設定好相關引數後,此應用的回撥模式才生效。
針對加解密的處理,微信提供了各種語言的庫,企業可以在附錄中下載。
當你開啟應用的回撥模式時,企業號會要求你填寫應用的URL、Token、EncodingAESKey三個引數。
URL是企業應用接收企業號推送請求的訪問協議和地址,支援http或https協議。
Token可由企業任意填寫,用於生成簽名。
EncodingAESKey用於訊息體的加密,是AES金鑰的Base64編碼。
驗證URL、Token以及加密的詳細處理請參考後續'接收訊息時的加解密處理'的部分。
驗證URL有效性
當你提交以上資訊時,企業號將傳送GET請求到填寫的URL上,GET請求攜帶四個引數,企業在獲取時需要做urldecode處理,否則會驗證不成功
引數 | 描述 | 是否必帶 |
---|---|---|
msg_signature | 微信加密簽名,msg_signature結合了企業填寫的token、請求中的timestamp、nonce引數、加密的訊息體 | 是 |
timestamp | 時間戳 | 是 |
nonce | 隨機數 | 是 |
echostr | 加密的隨機字串,以msg_encrypt格式提供。需要解密並返回echostr明文,解密後有random、msg_len、msg、$CorpID四個欄位,其中msg即為echostr明文 | 首次校驗時必帶 |
企業通過引數msg_signature對請求進行校驗,如果確認此次GET請求來自企業號,那麼企業應用對echostr引數解密並原樣返回echostr明文(不能加引號),則接入驗證生效,回撥模式才能開啟。
後續回撥企業時都會在請求URL中帶上以上引數(echostr除外),校驗方式與首次驗證URL一致。
2、使用回撥模式
企業號在回撥企業URL時,會對訊息體本身做AES加密,以XML格式POST到企業應用的URL上;企業在被動回覆時,也需要對資料加密,以XML格式返回給微信。企業的回覆支援文字、圖片、語音、視訊、圖文等格式。
微信伺服器在五秒內收不到響應會斷掉連線,並且重新發起請求,總共重試三次。如果在除錯中,發現員工無法收到響應的訊息,可以檢查是否訊息處理超時。
關於重試的訊息排重,有msgid的訊息推薦使用msgid排重。事件型別訊息推薦使用FromUserName + CreateTime排重。
假如企業無法保證在五秒內處理並回復,可以直接回復空串,企業號不會對此作任何處理,並且不會發起重試。這種情況下,可以使用發訊息介面進行非同步回覆。
- 請求說明:
- 回撥資料格式:
- <xml>
- <ToUserName><![CDATA[toUser]]</ToUserName>
- <AgentID><![CDATA[toAgentID]]</AgentID>
- <Encrypt><![CDATA[msg_encrypt]]</Encrypt>
- </xml>
1.msg_encrypt為經過加密的密文 2.AgentID為接收的應用id,可在應用的設定頁面獲取 3.ToUserName為企業號的CorpID
企業需要對msg_signature進行校驗,並解密msg_encrypt,得出msg的原文。
- 回覆給微信的資料格式:
- <xml>
- <Encrypt><![CDATA[msg_encrypt]]></Encrypt>
- <MsgSignature><![CDATA[msg_signature]]></MsgSignature>
- <TimeStamp>timestamp</TimeStamp>
- <Nonce><![CDATA[nonce]]></Nonce>
- </xml>
3、接收訊息時的加解密處理
企業可以直接使用微信提供的庫進行加解密的處理,目前提供的有c++/python/php/java/c#等語言版本。程式碼提供瞭解密、加密、驗 證URL三個介面,企業可根據自身需要下載(參見附錄)。以下為庫函式的使用說明(以c++為例),更詳細的加解密方案請參考附錄。
1)解密函式
- int DecryptMsg(const string &sMsgSignature, const string &sTimeStamp, const string &sNonce, const string &sPostData, string &sMsg);
- 引數說明
引數 | 必須 | 說明 |
---|---|---|
sMsgSignature | 是 | 從回撥URL中獲取的msg_signature引數 |
sTimeStamp | 是 | 從回撥URL中獲取的timestamp引數 |
sNonce | 是 | 從回撥URL中獲取的nonce引數 |
sPostData | 是 | 從回撥URL中獲取的整個post資料 |
sMsg | 是 | 用於返回解密後的msg,以xml組織 |
- 返回說明
請參閱附錄加密部分。
2)加密函式
- int EncryptMsg(const string &sReplyMsg, const string &sTimeStamp, const string &sNonce, string &sEncryptMsg);
- 引數說明
引數 | 必須 | 說明 |
---|---|---|
sReplyMsg | 是 | 返回的訊息體原文 |
sTimeStamp | 是 | 時間戳,呼叫方生成 |
sNonce | 是 | 隨機數,呼叫方生成 |
sEncryptMsg | 是 | 用於返回的密文,以xml組織 |
- 返回說明
請參閱附錄加密部分。
3)驗證URL函式
- int VerifyURL(const string &sMsgSignature, const string &sTimeStamp, const string &sNonce, const string &sEchoStr, string &sReplyEchoStr);
- 引數說明
引數 | 必須 | 說明 |
---|---|---|
sMsgSignature | 是 | 從回撥URL中獲取的msg_signature引數 |
sTimeStamp | 是 | 從回撥URL中獲取的timestamp引數 |
sNonce | 是 | 從回撥URL中獲取的nonce引數 |
sEchoStr | 是 | 從回撥URL中獲取的echostr引數。注意,此引數必須是urldecode後的值 |
sReplyEchoStr | 是 | 解密後的echostr,用於回包。注意,必須原樣返回,不要做加引號或其它處理 |
- 返回說明
請參閱附錄加密部分。
詳細步驟
在配置上有幾個注意的地方。
1、首要要有一個ICP備案的域名,一定要有ICP備案,後面需要;
2、EncodeAESKey不能隨機生成,之前官網提供是不能使用的,目前不知道,EncodeAESKey生成規則是32位明文經過base64加密後,去掉“=”,形成的43位金鑰;
3、替換JCE包,重啟服務
4、JDK版本要大於等於1.6
5、回撥模式和主動呼叫模式在訊息傳送上也有很大不同:
A:回撥模式下,被動傳送的訊息需要時xml格式並進行加密,加密規則是首先進行AES加密,然後進行base64加密。
B:主動傳送訊息,格式為json格式,不需要加密,但需要token
6、回撥模式接受到真正的訊息內容之後,注意回覆,空訊息即可,否則微信會認為訊息接受失敗,會再次傳送同一訊息
7、在接受訊息上,回撥模式先通過配置的連結,以Get形式傳送一個密文,我們需要在Get中解析密文,返回給微信,微信接受訊息無誤之後,才會以Post形式將加密的真正內容傳送過來,
8、主動呼叫模式是企業號給員工發訊息,回撥模式則是員工向企業號傳送訊息,
訊息通過第三方伺服器處理,最後經過微信伺服器把訊息傳送給使用者
要開啟企業號的回撥模式,首先要進行URL驗證,也就是說,你必須要有一個伺服器,來保證在公網環境下能夠訪問你的這個URL,然後才能接著往下走。(如果沒有伺服器的話,建議使用BAE比較好)。
2. 建立一個web專案,(注意必須是Dynamic Web Project專案),然後建立一個servlet類,來處理企業號傳送的請求,命名任意,程式碼如下:
Java code
package org.yhxz.weixin.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.qq.weixin.mp.aes.AesException;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;
/**
* 核心請求處理類
*/
public class CoreServlet extends HttpServlet {
private static final long serialVersionUID = 4440739483644821986L;
String sToken = "5XaQ8cG6x2pULd";//這個Token是隨機生成,但是必須跟企業號上的相同
String sCorpID = "wx4edd47d3a6r4r991";//這裡是你企業號的CorpID
String sEncodingAESKey = "jWmYm7qjusnxu65ZRjGtBxmz3KA1tkAj3ykkR6q2B2C";//這個EncodingAESKey是隨機生成,但是必須跟企業號上的相同
/**
* 確認請求來自微信伺服器
* @throws IOException
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
// 微信加密簽名
String sVerifyMsgSig = request.getParameter("msg_signature");
// 時間戳
String sVerifyTimeStamp = request.getParameter("timestamp");
// 隨機數
String sVerifyNonce = request.getParameter("nonce");
// 隨機字串
String sVerifyEchoStr = request.getParameter("echostr");
String sEchoStr; //需要返回的明文
PrintWriter out = response.getWriter();
WXBizMsgCrypt wxcpt;
try {
wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,sVerifyNonce, sVerifyEchoStr);
// 驗證URL成功,將sEchoStr返回
out.print(sEchoStr);
} catch (AesException e1) {
e1.printStackTrace();
}
}
/**
* 處理微信伺服器發來的訊息
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO 訊息的接收、處理、響應
}
}
聯絡QQ877507054索要完整版程式碼
3. 接下來就要匯入官方的業務類了,然後將其匯入到你的專案中。這個可以在官方文件上下載到(注意,雖然官方下載的例項程式碼中也有驗證的程式碼,但是不建議使用哪個Sample.java,如果不信的可以試試看,反正我用這個是沒通)
下載地址是:
http://qydev.weixin.qq.com/java.zip,
請開發者使用jdk1.6或以上的版本。針對org.apache.commons.codec.binary.Base64,需要匯入jar包commons-codec-1.9(或comm ons-codec-1.8等其他版本),我們有提供,官方下載地址:
http://commons.apache.org/proper/commons-codec/download_codec.cgi。
4. 如果出現異常java.security.InvalidKeyException:illegal Key Size的解決方案:
在官方網站下載JCE無限制許可權策略檔案(JDK7的下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
下載後解壓,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。如果安裝了JRE,將兩個jar檔案放到%JRE_HOME% \lib\security目錄下覆蓋原來的檔案,如果安裝了JDK,將兩個jar檔案放到%JDK_HOME%\jre\lib\security目錄下覆蓋原來檔案。
5. 下來就是對web.xml檔案的配置,程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version= "1.0" encoding= "UTF-8" ?>
<web-app version= "2.5" xmlns= "http://java.sun.com/xml/ns/javaee"
xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http: //java.sun.com/xml/ns/javaee
http: //java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>coreServlet</servlet-name>
<servlet- class >
org.yhxz.course.servlet.CoreServlet
</servlet- class >
</servlet>
<!-- url-pattern中配置的/coreServlet用於指定該Servlet的訪問路徑 -->
<servlet-mapping>
<servlet-name>coreServlet</servlet-name>
<url-pattern>/coreServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
|
6. 然後將你的專案釋出到伺服器上,在瀏覽器中輸入URL,如果在你的Tomcat的控制檯上出現NullPointException異常,就說明沒有問題(出現的原因是:請求的資料為空,這個你懂得)。
7. 接下來就在企業號後臺上的操作了,開啟回撥模式,輸入你的URL,隨機生成token和EncodingAESKey,點選提交就可以驗證通過,注意一定要程式碼中的和企業號上的token和EncodingAESKey是要一致的。
三、Weixin JS介面
Weixin JS介面是微信為你的H5應用提供開放原生能力的介面,你的應用可以利用這些介面使用更多的微信原生能力和微信的操控能力, 以使得你的應用有更強大的智慧,更好的使用者體驗。
除了以下章節所描述的各類介面。拍照、上傳圖片、掃碼、微信支付、地理位置上報等更多的介面已經或正在抓緊開放中,更多資訊也請參考微信相關網站了解.
1、隱藏微信中網頁右上角按鈕
企業號在有需要時(如不需要使用者分享某個頁面),可在網頁中通過JavaScript程式碼隱藏網頁右上角按鈕。
- 介面呼叫程式碼(JavaScript)
- function onBridgeReady(){
- WeixinJSBridge.call('hideOptionMenu');
- }
- if (typeof WeixinJSBridge == "undefined"){
- if( document.addEventListener ){
- document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
- }else if (document.attachEvent){
- document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
- document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
- }
- }else{
- onBridgeReady();
- }
- 返回說明
隱藏底部導航欄沒有返回值。(需要顯示請把hideOptionMenu換成showOptionMenu)
2、隱藏微信中網頁底部導航欄
企業號在有需要時(如認為使用者在該頁面不會用到瀏覽器前進後退功能),可在網頁中通過JavaScript程式碼隱藏網頁底部導航欄。
- 介面呼叫程式碼(JavaScript)
- function onBridgeReady(){
- WeixinJSBridge.call('hideToolbar');
- }
- if (typeof WeixinJSBridge == "undefined"){
- if( document.addEventListener ){
- document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
- }else if (document.attachEvent){
- document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
- document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
- }
- }else{
- onBridgeReady();
- }
- 返回說明
隱藏底部導航欄沒有返回值。(需要顯示頂部導航欄,請把hideToolbar換成showToolbar)
3、網頁獲取使用者網路狀態
為了方便開發者根據使用者的網路狀態來提供不同質量的服務,企業號可以在企業號內部的網頁中使用JavaScript程式碼呼叫來獲取網路狀態。
- 介面呼叫程式碼(JavaScript)
- function onBridgeReady(){
- WeixinJSBridge.invoke('getNetworkType',{},
- function(e){
- WeixinJSBridge.log(e.err_msg);
- });
- }
- if (typeof WeixinJSBridge == "undefined"){
- if( document.addEventListener ){
- document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
- }else if (document.attachEvent){
- document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
- document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
- }
- }else{
- onBridgeReady();
- }
- 返回說明
獲取使用者網路狀態的返回值如下:
- network_type:wifi wifi網路
- network_type:edge 非wifi,包含3G/2G
- network_type:fail 網路斷開連線
- network_type:wwan(2g或者3g)
4、關閉當前網頁視窗
在微信內建瀏覽器中被訪問的網頁,可使用該JavaScript程式碼關閉當前網頁。
主要使用場景: 微信使用者在企業號會話中點選外鏈到達企業號的網頁,在使用者完成操作後,企業號(網頁方)可呼叫此介面關閉當前網頁視窗,使使用者返回會話。
- 介面呼叫程式碼(JavaScript)
- WeixinJSBridge.invoke('closeWindow',{},function(res){
- //alert(res.err_msg);
- });
- 返回說明
返回值 | 說明 |
---|---|
err_msg | 關閉成功返回“close_window:ok”,關閉失敗返回“close_window:error”。 |
【編輯推薦】