微信公眾平台是運營者通過公眾號為微信用戶提供資訊和服務的平台,而公眾平台開發接口則是提供服務的基礎,開發者在公眾平台網站中創建公眾號、獲取接口權限后,才可以進行開發。
公眾平台開發接口簡單說,是微信公眾平台向第三方開發者提供的一個用戶資源數據及功能的訪問/使用權限。通過對開發者提供開放統一的API接口環境,來幫助微信第三方開發者訪問微信公眾平台的功能和資源,以達到充分自由的運用微信公眾平台用戶資源及功能的目的。
1.開發前准備
1.1微信公眾平台開發者文檔
微信公眾平台開發者文檔是微信公眾平台為開發者提供的幫助文檔,開發者在開發中遇到的問題都可以在此文檔中找到解決辦法,開發中所有需要特別注意的事項在文檔中均有提及,因此開發者需以其為准則。
網址:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432&token=&lang=zh_CN
1.2AppID和AppSecret
需要有一個公眾號,從公眾號中獲取AppID和AppSecret。
AppID:是公眾號的編號;
AppSecret:是公眾號的密鑰。
獲取步驟:登錄公眾號-基本配置,會有如下提示:
1.3回調域名(獲取用戶信息時使用)
進入公眾號開發者中心頁配置授權回調域名。具體位置:登錄公眾號-接口權限-網頁服務-網頁賬號-網頁授權獲取用戶基本信息-修改
注意,這里僅需填寫全域名(如www.qq.com、www.baidu.com),勿加 http:// 等協議頭及具體的地址字段;
這個域名需要是一個備案過的域名。
1.4測試工具
如果嫌手機上測試麻煩,可以使用微信官方提供的web開發者工具直接在瀏覽器中進行調試。
前提是需要在微信公眾號中綁定開發者賬號:登錄公眾號-開發者工具-進入web開發者工具-綁定web開發者微信賬號
使用說明及下載地址:
https://mp.weixin.qq.com/wiki?action=doc&id=mp1455784140&t=0.7272727088156665&token=&lang=zh_CN#6
2.公眾號功能的開發步驟
(1)獲取access_token(公眾號全局唯一接口調用憑據);
(2)頁面中引入js文件;
(3)通過config接口注入權限驗證配置;
(4)通過ready接口處理成功驗證;
(5)通過error接口處理失敗驗證;
(6)接口調用;
2.1獲取acces_token(公眾號全局唯一接口調用憑據)
2.1.1概述
access_token是公眾號的全局唯一接口調用憑據,公眾號調用各接口時都需使用access_token。開發者需要進行妥善保存。access_token的存儲至少要保留512個字符空間。access_token的有效期目前為7200秒,需定時刷新,重復獲取將導致上次獲取的access_token失效。
2.1.2access_token的管理
為了保密appsecrect,第三方需要一個access_token獲取和刷新的中控服務器;由於目前access_token的有效期為7200秒,因此需要定時刷新。
在這里有一個wechat4j框架,它的內部封裝了對access_token的管理,包括獲取access_token和access_token中控服務器的實現。
2.1.2.1wechat4j的配置
(1)創建一個web工程,導入jdk和相關的web工程jar包。
(2)下載wechat4j.jar包及其依賴jar包:
http://files.cnblogs.com/files/shuilangyizu/wechat4j-lib.rar
(3)創建wechat4j配置文件,配置你微信公眾號的相關信息。
文件名稱:wechat4j.properties;內容如下:
2.1.2.2access_token的獲取
要獲取access_token可以使用如下的方法:
String accessToken = TokenProxy.accessToken();
2.1.2.3access_token中控服務器
由中控服務器定時去刷新access_token,wechat4j的默認中控服務器是內存模式,即將access_token保存在內存中,定時刷新任務會提前200秒運行,防止到有效期之后運行過程中新access_token沒有取得舊的access_token過期的情況發生,獲得后會將其緩存為全局的。
2.2頁面中引入js文件
在需要調用JS接口的頁面引入如下JS文件,(支持https):
http://res.wx.qq.com/open/js/jweixin-1.0.0.js
如需使用搖一搖周邊功能,請引入
http://res.wx.qq.com/open/js/jweixin-1.1.0.js
2.3通過config接口注入權限驗證配置
微信JS-SDK是微信公眾平台面向網頁開發者提供的基於微信內的網頁開發工具包。
微信JS SDK Demo 官方案例:
http://my.oschina.net/superkangning/blog/367484?fromerr=z6LEPSI3
通過使用微信JS-SDK,網頁開發者可借助微信高效地使用拍照、選圖、語音、位置等手機系統的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信用戶提供更優質的網頁體驗。
所有需要使用JS-SDK的頁面必須先注入配置信息,否則將無法調用。
wx.config({ debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。 appId: '', // 必填,公眾號的唯一標識 timestamp: , // 必填,生成簽名的時間戳 nonceStr: '', // 必填,生成簽名的隨機串 signature: '',// 必填,簽名 jsApiList: ['checkJsApi','getLocation'] // 必填,需要使用的JS接口列表,多個以逗號“,”隔開,最后一個不需要加逗號 });
2.3.1JS-SDK使用權限簽名(signature)算法
2.3.1.1jsapi_ticket
生成簽名之前必須先了解一下jsapi_ticket,jsapi_ticket是公眾號用於調用微信JS接口的臨時票據。正常情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。由於獲取jsapi_ticket的api調用次數非常有限,頻繁刷新jsapi_ticket會導致api調用受限,影響自身業務,開發者必須在自己的服務全局緩存jsapi_ticket 。同樣的wechat4j框架提供了對jsapi_ticket的管理,和access_token的管理機制相同。
2.3.1.2jsapi_ticket的獲取
可以使用如下方法:
String jsapiTicket= TokenProxy.jsApiTicket();
2.3.1.3當前網頁的url
當前網頁的URL,不包含#及其后面部分,通過如下js代碼在頁面上獲得,傳遞到后台進行處理。
var url = window.location.href;
2.3.1.4簽名算法
獲得jsapi_ticket之后,就可以生成JS-SDK權限驗證的簽名了。
簽名生成規則如下:參與簽名的字段包括noncestr(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳), url 。對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。這里需要注意的是所有參數名均為小寫字符。對string1作sha1加密,字段名和字段值都采用原始值,不進行URL 轉義。
即signature=sha1(string1)。 示例:
noncestr=Wm3WZYTPz0wzccnW jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg timestamp=1414587457 url=http://mp.weixin.qq.com?params=value
步驟1. 對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步驟2. 對string1進行sha1簽名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
注意事項
(1)簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。
(2)簽名用的url必須是調用JS接口頁面的完整URL。
(3)出於安全考慮,開發者必須在服務器端實現簽名的邏輯。
2.3.2權限驗證成功
2.4通過ready接口處理成功驗證
wx.ready(function(){ // config信息驗證后會執行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對於用戶觸發時才調用的接口,則可以直接調用,不需要放在ready 函數中。 });
2.5通過error接口處理失敗驗證
wx.error(function(res){ // config信息驗證失敗會執行error函數,如簽名過期導致驗證失敗,具體錯誤信息可以打開config的debug模式查看,也可以在返回的res參數中查看,對於SPA可以在這里更新簽名。 });
2.6接口調用
2.6.1判斷當前客戶端版本是否支持指定JS接口
wx.checkJsApi({ jsApiList: ['chooseImage'], // 需要檢測的JS接口列表, success: function(res) { // 以鍵值對的形式返回,可用的api值true,不可用為false // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"} } });
備注:checkJsApi接口是客戶端6.0.2新引入的一個預留接口,第一期開放的接口均可不使用checkJsApi來檢測。
2.6.2接口調用說明
所有接口通過wx對象(也可使用jWeixin對象)來調用,參數是一個對象,除了每個接口本身需要傳的參數之外,還有以下通用參數:
(1)success:接口調用成功時執行的回調函數。
(2)fail:接口調用失敗時執行的回調函數。
(3)complete:接口調用完成時執行的回調函數,無論成功或失敗都會執行。
(4)cancel:用戶點擊取消時的回調函數,僅部分有用戶取消操作的api才會用到。
(5)trigger: 監聽Menu中的按鈕點擊時觸發的方法,該方法僅支持Menu中的相關接口。
備注:不要嘗試在trigger中使用ajax異步請求修改本次分享的內容,因為客戶端分享操作是一個同步操作,這時候使用ajax的回包會還沒有返回。
以上幾個函數都帶有一個參數,類型為對象,其中除了每個接口本身返回的數據之外,還有一個通用屬性errMsg,其值格式如下:
調用成功時:"xxx:ok" ,其中xxx為調用的接口名
用戶取消時:"xxx:cancel",其中xxx為調用的接口名
調用失敗時:其值為具體錯誤信息
3.微信公眾號開發中所用到的接口
(1)getLocation:獲取定位;
(2)chooseImage:選擇圖片;
(3)uploadImage:上傳圖片;
(4)startRecord:開始錄音;
(5)stopRecord:結束錄音;
(6)playVoice:開始播放錄音;
(7)stopVoice:結束播放錄音;
(8)onVoicePlayEnd:監測語音播放完畢;
(9)uploadVoice:上傳錄音文件;
3.1 getLocation:獲取定位
3.1.1使用場景
當公眾號需要獲取用戶位置信息的時候,就需要使用到此接口,定位成功后可以返回用戶所在位置的經度,緯度,速度和位置精度等信息。
3.1.2使用方法
//調用微信獲取用戶位置信息的接口 wx.getLocation({ type: 'wgs84', // 默認為wgs84的gps坐標,如果要返回直接給openLocation用的火星坐標,可傳入'gcj02' success: function (res) { latitude = res.latitude; // 緯度,浮點數,范圍為90 ~ -90 longitude = res.longitude; // 經度,浮點數,范圍為180 ~ -180。 speed = res.speed; // 速度,以米/每秒計 accuracy = res.accuracy; // 位置精度 }, cancel: function (res) { alert('用戶拒絕授權獲取地理位置'); } });
如果需要顯示在地圖上或者要的到具體的地址信息,那么還需要進一步處理。微信公眾號所使用的是百度地圖,百度地圖的API地址如下:
下面是js示例:
http://developer.baidu.com/map/jsdemo.htm#a1_2
3.2 chooseImage:選擇圖片
3.2.1使用場景
當公眾號需要用戶上傳圖片的時候,首先需要用戶拍照或從手機相冊中選圖,而此接口會調起手機自帶的相冊和相機,選圖成功后返回返回選定照片的本地ID列表。
3.2.2使用方法
wx.chooseImage({ count: 1, // 默認9 sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有 sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有 success: function (res) { var localIds = res.localIds;// 返回選定照片的本地ID列表,localId可以作為img標簽的src屬性顯示圖片 } });
選擇圖片接口使用成功之后返回的選定照片的本地ID列表可以用於上傳圖片,上傳圖片就要調用上傳圖片接口,將圖片上傳至微信服務器上。
3.3 uploadImage:上傳圖片
3.3.1使用場景
當公眾號用戶選擇好圖片之后需要將圖片先上傳至微信服務器,上傳圖片接口需要拿到選擇圖片接口返回的選擇圖片本地ID,根據圖片的本地ID將對應的圖片傳至微信服務器,上傳成功后返回服務器端ID。
3.3.2使用方法
//圖片上傳 wx.uploadImage({ localId: localId,// 需要上傳圖片的本地ID,由chooseImage接口獲得 isShowProgressTips: 1,// 默認為1,顯示進度提示 success: function (res) { var serverId = res.serverId; // 返回圖片的服務器端ID } });
微信只將使用圖片上傳接口上傳的圖片在微信服務器上面保存三天時間,因此如果需要將圖片進行保存在指定的服務器上面就需要將圖片進行下載保存。而通過上傳圖片接口上傳完成返回的服務器端ID可以用於下載圖片,頁面可以直接通過下載圖片接口進行下載圖片,公眾號項目的需求是是要在后台處理下載圖片的,下載完成后通過流的形式寫入到指定目錄下。在后台通過下面網頁中的下載多媒體接口下載圖片:
https://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html
也可以通過下面網頁中的素材管理中的獲取臨時素材接口下載圖片:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738727&token=&lang=zh_CN
3.4 startRecord:開始錄音
3.4.1使用場景
當公眾號需要用戶上傳錄音的時候,這就需要調用觸發開始錄音接口,此接口觸發后開始錄音音頻文件,如果不觸發結束錄音接口,錄音將一直持續。
3.4.2使用方法
wx.startRecord({ success: function(){ localStorage.rainAllowRecord = 'true';//記錄用戶是否授權 }, cancel: function () { alert('用戶拒絕授權錄音'); } });
3.5 stopRecord:結束錄音
3.5.1使用場景
當用戶觸發開始錄音接口之后想要結束錄音就必須觸發結束錄音接口,否則錄音將不會停止,結束錄音接口觸發成功后,返回錄音文件本地ID。
3.5.2使用方法
//結束錄音接口 wx.stopRecord({ success: function (res) { var localId = res.localId; }, fail: function (res) { alert(JSON.stringify(res)); } });
錄音結束之后返回的錄音文件本地ID可以用於上傳錄音,播放錄音;上傳錄音就要調用上傳錄音接口,將錄音文件上傳至微信服務器上;播放錄音需要調用開始播放錄音接口。
3.6 playVoice:開始播放錄音
3.6.1使用場景
當用戶錄制完語音文件之后,需要對所錄制的語音進行試聽,此時就可以調用開始播放錄音接口,調用成功后,如果在播放過程中沒有觸發停止播放錄音或者沒有觸發暫停播放錄音,錄音將一直播放完畢。
3.6.2使用方法
wx.playVoice({ localId: localId // 需要播放的音頻的本地ID,由stopRecord接口獲得 });
如果在錄音播放過程中需要結束播放,可以調用結束播放錄音接口,調用之后就會結束播放錄音,如果不觸發結束播放錄音,而要在錄音結束之后做其他處理,還可以在語音結束之后自動調用監測語音播放完畢接口,進行其他處理。
3.7 stopVoice:結束播放錄音
3.7.1使用場景
當用戶正在試聽錄音文件並且還沒有試聽結束的時候,可能會需要主動的去結束錄音文件的播放,這個時候就可以調用結束播放錄音接口來主動結束錄音文件的播放。
3.7.2使用方法
wx.stopVoice({ localId: data.id // 需要停止的音頻本地ID,由stopRecord接口獲得 });
3.8 onVoicePlayEnd:監測語音播放完畢
3.8.1使用場景
當用戶播放錄音文件的時候,在語音結束后可能需要提示一個語音播放結束或者進行其他的自動的操作,這個時候就可以使用監測語音播放完畢接口來進行監測錄音文件播放結束狀態。
3.8.2使用方法
//監聽語音播放完畢接口 wx.onVoicePlayEnd({ success: function (res) { var localId = res.localId; // 返回音頻的本地ID } });
這個自動監測語音播放完畢接口必須放在wx.ready(function(){ });內。
3.9 uploadVoice:上傳錄音文件
3.9.1使用場景
當用戶用戶選擇好錄音之后就可以調用上傳錄音文件接口,上傳錄音文件接口需要拿到由stopRecord接口獲得的音頻文件本地ID,根據音頻文件的本地ID將對應的音頻文件傳至微信服務器,上傳成功后返回服務器端ID。
3.9.2使用方法
wx.uploadVoice({ localId: voiceLocalId, // 需要上傳的音頻的本地ID,由stopRecord接口獲得 isShowProgressTips: 1, // 默認為1,顯示進度提示 success: function (res) { var voiceServerId = res.serverId; // 返回錄音文件服務器端ID } });
同樣的,微信只將使用上傳錄音文件接口上傳的錄音文件在微信服務器上面保存三天時間,因此如果需要將錄音文件保存在指定的服務器上面就需要將錄音文件下載保存。而通過上傳錄音文件接口上傳完成返回的服務器端ID可以用於下載錄音文件,頁面可以直接通過下載圖片接口進行下載錄音文件,公眾號項目的需求是要在后台處理下載錄音文件的,下載完成后通過流的形式寫入到指定目錄下。在后台通過下面網頁中的下載多媒體接口下載音頻文件:
https://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html
也可以通過下面網頁中的素材管理中的獲取臨時素材接口下載音頻文件:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738727&token=&lang=zh_CN
4.微信公眾號開發中遇到的問題
4.1信息整合問題
這個問題是一開始接觸微信公眾號開發的時候遇到的,當時對微信公眾號開發完全沒有概念,況且身邊沒有人做過這方面的開發,只能在網上去找關於微信公眾號開發的相關信息。網上的信息很龐雜,即使有微信公眾號開發者文檔,但是不知道從哪里着手,不知道怎么組織前后台。最后通過閱讀大量的微信公眾號開發博文,慢慢的摸索到了開發的路徑,通過實踐驗證了以上總結的步驟。
4.2通過微信定位接口獲取用戶定位顯示在百度地圖上顯示定位不准的問題
微信定位接口可以獲取到用戶的經緯度,直接將此經緯度顯示在百度地圖上表現出定位不准的問題。
因為微信定位獲取到的用戶經緯度和百度所使用的經緯度並不是同一個標准,所以出現了偏差,如果想要統一兩者,就需要將微信定位接口獲得的經緯度進行轉換,轉換方式如下:
wx.getLocation({ type: 'wgs84', // 默認為wgs84的gps坐標,如果要返回直接給openLocation用的火星坐標,可傳入'gcj02' success: function (res) { latitude = res.latitude; // 緯度,浮點數,范圍為90 ~ -90 longitude = res.longitude; // 經度,浮點數,范圍為180 ~ -180。 speed = res.speed; // 速度,以米/每秒計 accuracy = res.accuracy; // 位置精度 var map = new BMap.Map("allmap");//初始化百度地圖 var point = new BMap.Point(longitude, latitude);//將經緯度轉化為百度經緯度 var geoc = new BMap.Geocoder(); //獲取百度地址解析器 translateCallback = function(point) { //回調函數 $("#Latitude").attr("value", point.lat); $("#longitude").attr("value", point.lng); geoc.getLocation(point, function(rs) { var addComp = rs.addressComponents; var Address = addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber; $("#locAddress").val(Address); baiduLocation(point); }); } //3: 將經緯度轉換為百度的經緯度 setTimeout(function() { //此轉換方法需要調用百度地圖的一個js:src="http://developer.baidu.com/map/jsdemo/demo/convertor.js" BMap.Convertor.translate(point, 0, translateCallback);//真實經緯度轉成百度坐標 }, 2000); }, cancel: function (res) { alert('用戶拒絕授權獲取地理位置'); } });
4.3公眾號中公眾報災提醒問題(模板消息)
客戶之前提過一個需求,當有新的公眾報災消息的時候用公眾號給指定用戶發送提醒消息。
一直都只以為公眾號不能夠實現此功能,因為公眾號一個月群發消息的條數是有限制的:服務號每個月可以群發四條;訂閱號每天可以群發一條。后來翻看開發者文檔知道公眾號可以在用戶觸發的情況下給用戶發送模板消息;目前在特殊情況下允許主動下發的消息只有故障類和災害警示警告類通知,除此之外都要經過用戶同意或用戶有觸發行為才能下發模板消息。正好公眾報災屬於災害警示警告了通知。符合要求。
從這個問題中體現出來的另外一個問題是微信公眾平台開發者文檔的重要性。