[042] 微信公眾帳號開發教程第18篇-應用例項之音樂搜尋
引言及內容概要
微信公眾平臺支援向用戶回覆音樂訊息,使用者收到音樂訊息後,點選即可播放音樂。通過音樂訊息,公眾賬號可以實現音樂搜尋(歌曲點播)功能,即使用者輸入想聽的音樂名稱,公眾賬號返回對應的音樂(歌曲)。讀者可以關注xiaoqrobot體驗該功能,操作指南及使用如下所示。
考慮到歌曲名稱有重複的情況,使用者還可以同時指定歌曲名稱、演唱者搜尋歌曲。下面就為讀者詳細介紹歌曲點播功能的實現過程。
音樂訊息說明
在微信公眾平臺開發者文件中提到,向用戶回覆音樂訊息需要構造如下格式的XML資料。
上面XML中,需要注意的是<Music>節點中的引數,說明如下:<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[music]]></MsgType> <Music> <Title><![CDATA[TITLE]]></Title> <Description><![CDATA[DESCRIPTION]]></Description> <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl> <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl> <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId> </Music> </xml>
1)引數Title:標題,本例中可以設定為歌曲名稱;
2)引數Description:描述,本例中可以設定為歌曲的演唱者;
3)引數MusicUrl:普通品質的音樂連結;
4)引數HQMusicUrl:高品質的音樂連結,在WIFI環境下會優先使用該連結播放音樂;
5)引數ThumbMediaId:縮圖的媒體ID,通過上傳多媒體檔案獲得;它指向的是一張圖片,最終會作為音樂訊息左側綠色方形區域的背景圖片。
上述5個引數中,最為重要的是MusicUrl和HQMusicUrl,這也是本文的重點,如何根據歌曲名稱獲得歌曲的連結。如果讀者只能得到歌曲的一個連結,可以將MusicUrl和HQMusicUrl設定成一樣的。至於ThumbMediaId引數,必須是通過微信認證的服務號才能得到,普通的服務號與訂閱號可以忽略該引數,也就是說,在回覆給微信伺服器的XML中可以不包含ThumbMediaId引數
百度音樂搜尋API介紹
上面提到,給使用者回覆音樂訊息最關鍵在於如何根據歌曲名稱獲得歌曲的連結,我們必須找一個現成的音樂搜尋API,除非讀者自己有音樂伺服器,或者只向用戶回覆固定的幾首音樂。百度有一個非公開的音樂搜尋API,之所以說非公開,是因為筆者沒有在百度官網的任何地方看到有關該API的介紹,但這並不影響讀者對本例的學習,我們仍然可以呼叫它。百度音樂搜尋API的請求地址如下:
http://box.zhangmen.baidu.com/x?op=12&count=1&title=TITLE$$AUTHOR$$$$
http://box.zhangmen.baidu.com為百度音樂盒的首頁地址,上面的連結中不用管引數op和count,重點關注TITLE和AUTHOR,TITLE表示歌曲名稱,AUTHOR表示演唱者,AUTHOR可以為空,引數TITLE和AUTHOR需要進行URL編碼(UTF-8或GB2312均可)
// GB2312編碼的音樂搜尋連結
http://box.zhangmen.baidu.com/x?op=12&count=1&title=%CF%E0%D0%C5%D7%D4%BC%BA$$%C1%E3%B5%E3%C0%D6%B6%D3$$$$
// UTF-8編碼的音樂搜尋連結
http://box.zhangmen.baidu.com/x?op=12&count=1&title=%E7%9B%B8%E4%BF%A1%E8%87%AA%E5%B7%B1$$%E9%9B%B6%E7%82%B9%E4%B9%90%E9%98%9F$$$$
通過瀏覽器訪問上面的地址,返回的是如下格式的XML資料:<result>
<count>1</count>
<url>
<encode>
<![CDATA[http://zhangmenshiting.baidu.com/data2/music/44277542/ZWZla2xra2pfn6NndK6ap5WXcJVob5puZ2trbWprmnBjZ2xolpeZa2drZmWZmZmdl2hjZWhvnWlpYmRtZmltcGplZFqin5t1YWBobW5qcGxia2NmZ2twbzE$]]>
</encode>
<decode>
<![CDATA[44277542.mp3?xcode=a39c6698955c82594aab36931dcbef60139f180191368931&mid=0.59949419022597]]>
</decode>
<type>8</type>
<lrcid>64644</lrcid>
<flag>1</flag>
</url>
<durl>
<encode>
<![CDATA[http://zhangmenshiting2.baidu.com/data2/music/44277530/ZWZla2xramhfn6NndK6ap5WXcJVob5puZ2trbWprmnBjZ2xolpeZa2drZmWZmZmdl2hjaGhvnZ5qlGRpbpedamJla1qin5t1YWBobW5qcGxia2NmZ2twbzE$]]>
</encode>
<decode>
<![CDATA[44277530.mp3?xcode=a39c6698955c82594aab36931dcbef60439ff9b159af2138&mid=0.59949419022597]]>
</decode>
<type>8</type>
<lrcid>64644</lrcid>
<flag>1</flag>
</durl>
<p2p>
<hash>022bc0fbf66cd19bea96db49634419dc2600393f</hash>
<url>
<![CDATA[ ]]>
</url>
<type>mp3</type>
<size>5236902</size>
<bitrate>192</bitrate>
</p2p>
</result>
返回結果中的主要引數說明如下:
1)<count> 表示搜尋到的音樂數;
2)<url>中包含了普通品質的音樂連結,<durl>中包含了高品質音樂的連結;
3)<encode>中包含了加密後的音樂連結,實際上只是對音樂名稱進行了加密,<decode>中包含了解密後的音樂名稱。因此,要獲取音樂的連結就需要重點分析<encode>和<decode>中的內容,下面會專門為讀者進行介紹。
4)<type>表示音樂檔案的型別,如rm、wma、mp3等;
5)<lrcid>是歌詞的ID,<url>中的歌詞ID為64644,那麼如何得到歌詞呢?本例並不關心歌詞,只是附帶提一下。歌詞的地址如下:
http://box.zhangmen.baidu.com/bdlrc/646/64644.lrc
其中,http://box.zhangmen.baidu.com/bdlrc/是固定值;646為歌詞所在目錄名,計算方法為歌詞ID(64644)除以100,取整數部分;64644.lrc是歌詞檔名。下面來看如何從<encode>和<decode>中得到音樂連結。為了便於說明,筆者將上面搜尋結果中的<url>和<durl>部分抽取出來,並進行了標註,如下圖所示。
上圖中,1和2拼接起來是普通品質音樂的連結,3和4拼接起來是高品質音樂的連結。也就是說,普通品質和高品質的音樂連結如下:
// 普通品質音樂連結
http://zhangmenshiting.baidu.com/data2/music/44277542/44277542.mp3?xcode=a39c6698955c82594aab36931dcbef60139f180191368931
// 高品質音樂連結
http://zhangmenshiting2.baidu.com/data2/music/44277530/44277530.mp3?xcode=a39c6698955c82594aab36931dcbef60439ff9b159af2138
引數xcode可以理解為隨機驗證碼,每次搜尋得到的值都不一樣,如果不帶該引數會報未授權異常“401 Authorization Required”。需要注意的是,xcode是有時間限制的,超過限制再訪問連結會報異常:{"Error":{"code":"2","Message":"object not exists","LogId":"3456414897"}}。在xcode有效的前提下,通過瀏覽器訪問上面的音樂連結,會提示下載音樂。
程式設計呼叫百度音樂搜尋API
知道如何從API返回結果中得到音樂連結後,就可以編寫程式來實現了。筆者將傳送HTTP請求、URL編碼、解析XML等操作全部封裝在BaiduMusicService類中,該類的程式碼如下:
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.liufeng.course.message.resp.Music;
/**
* 百度音樂搜尋API操作類
*
* @author liufeng
* @date 2013-12-09
*/
public class BaiduMusicService {
/**
* 根據名稱和作者搜尋音樂
*
* @param musicTitle 音樂名稱
* @param musicAuthor 音樂作者
* @return Music
*/
public static Music searchMusic(String musicTitle, String musicAuthor) {
// 百度音樂搜尋地址
String requestUrl = "http://box.zhangmen.baidu.com/x?op=12&count=1&title={TITLE}$${AUTHOR}$$$$";
// 對音樂名稱、作者進URL編碼
requestUrl = requestUrl.replace("{TITLE}", urlEncodeUTF8(musicTitle));
requestUrl = requestUrl.replace("{AUTHOR}", urlEncodeUTF8(musicAuthor));
// 處理名稱、作者中間的空格
requestUrl = requestUrl.replaceAll("\\+", "%20");
// 查詢並獲取返回結果
InputStream inputStream = httpRequest(requestUrl);
// 從返回結果中解析出Music
Music music = parseMusic(inputStream);
// 如果music不為null,設定標題和描述
if (null != music) {
music.setTitle(musicTitle);
// 如果作者不為"",將描述設定為作者
if (!"".equals(musicAuthor))
music.setDescription(musicAuthor);
else
music.setDescription("來自百度音樂");
}
return music;
}
/**
* UTF-8編碼
*
* @param source
* @return
*/
private static String urlEncodeUTF8(String source) {
String result = source;
try {
result = java.net.URLEncoder.encode(source, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* 傳送http請求取得返回的輸入流
*
* @param requestUrl 請求地址
* @return InputStream
*/
private static InputStream httpRequest(String requestUrl) {
InputStream inputStream = null;
try {
URL url = new URL(requestUrl);
HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
httpUrlConn.setDoInput(true);
httpUrlConn.setRequestMethod("GET");
httpUrlConn.connect();
// 獲得返回的輸入流
inputStream = httpUrlConn.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
return inputStream;
}
/**
* 解析音樂引數
*
* @param inputStream 百度音樂搜尋API返回的輸入流
* @return Music
*/
@SuppressWarnings("unchecked")
private static Music parseMusic(InputStream inputStream) {
Music music = null;
try {
// 使用dom4j解析xml字串
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// count表示搜尋到的歌曲數
String count = root.element("count").getText();
// 當搜尋到的歌曲數大於0時
if (!"0".equals(count)) {
// 普通品質
List<Element> urlList = root.elements("url");
// 高品質
List<Element> durlList = root.elements("durl");
// 普通品質的encode、decode
String urlEncode = urlList.get(0).element("encode").getText();
String urlDecode = urlList.get(0).element("decode").getText();
// 普通品質音樂的URL
String url = urlEncode.substring(0, urlEncode.lastIndexOf("/") + 1) + urlDecode;
if (-1 != urlDecode.lastIndexOf("&"))
url = urlEncode.substring(0, urlEncode.lastIndexOf("/") + 1) + urlDecode.substring(0, urlDecode.lastIndexOf("&"));
// 預設情況下,高音質音樂的URL 等於 普通品質音樂的URL
String durl = url;
// 判斷高品質節點是否存在
Element durlElement = durlList.get(0).element("encode");
if (null != durlElement) {
// 高品質的encode、decode
String durlEncode = durlList.get(0).element("encode").getText();
String durlDecode = durlList.get(0).element("decode").getText();
// 高品質音樂的URL
durl = durlEncode.substring(0, durlEncode.lastIndexOf("/") + 1) + durlDecode;
if (-1 != durlDecode.lastIndexOf("&"))
durl = durlEncode.substring(0, durlEncode.lastIndexOf("/") + 1) + durlDecode.substring(0, durlDecode.lastIndexOf("&"));
}
music = new Music();
// 設定普通品質音樂連結
music.setMusicUrl(url);
// 設定高品質音樂連結
music.setHQMusicUrl(durl);
}
} catch (Exception e) {
e.printStackTrace();
}
return music;
}
// 測試方法
public static void main(String[] args) {
Music music = searchMusic("相信自己", "零點樂隊");
System.out.println("音樂名稱:" + music.getTitle());
System.out.println("音樂描述:" + music.getDescription());
System.out.println("普通品質連結:" + music.getMusicUrl());
System.out.println("高品質連結:" + music.getHQMusicUrl());
}
}
下面對程式碼進行簡單的說明:
1)程式碼中的Music類是對音樂訊息的封裝(不包括ThumbMediaId引數),讀者可以在本系列教程的第4篇中找到該類的定義;2)執行上述程式碼需要引入dom4j的JAR包,筆者使用的是dom4j-1.6.1.jar;
3)searchMusic()方法是提供給外部呼叫的,在CoreService類中會呼叫該方法獲得音樂訊息需要的Music相關的4個引數(Title、Description、MusicUrl和HQMusicUrl);
4)parseMusic()方法用於解析XML,讀者可以結合程式碼中的註釋和之前對XML的分析進行理解,這裡就不再贅述了。
5)116行、127行中的get(0)表示返回多條音樂結果時預設取第一條。
公眾賬號後臺的實現
在公眾賬號後臺的CoreService類中,需要對使用者傳送的文字訊息進行判斷,如果是以“歌曲”兩個字開頭,就認為使用者是在使用“歌曲點播”功能,此時需要對“歌曲”兩個字之後的內容進行判斷,如果包含“@”符號,就表示需要按演唱者搜尋,否則不指定演唱者。CoreService類的完整程式碼如下:
package org.liufeng.course.service;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.liufeng.course.message.resp.Music;
import org.liufeng.course.message.resp.MusicMessage;
import org.liufeng.course.message.resp.TextMessage;
import org.liufeng.course.util.MessageUtil;
/**
* 核心服務類
*
* @author liufeng
* @date 2013-12-10
*/
public class CoreService {
/**
* 處理微信發來的請求
*
* @param request
* @return
*/
public static String processRequest(HttpServletRequest request) {
// 返回給微信伺服器的xml訊息
String respXml = null;
// 文字訊息內容
String respContent = null;
try {
// xml請求解析
Map<String, String> requestMap = MessageUtil.parseXml(request);
// 傳送方帳號(open_id)
String fromUserName = requestMap.get("FromUserName");
// 公眾帳號
String toUserName = requestMap.get("ToUserName");
// 訊息型別
String msgType = requestMap.get("MsgType");
// 回覆文字訊息
TextMessage textMessage = new TextMessage();
textMessage.setToUserName(fromUserName);
textMessage.setFromUserName(toUserName);
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
// 文字訊息
if (MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(msgType)) {
// 文字訊息內容
String content = requestMap.get("Content").trim();
// 如果以“歌曲”2個字開頭
if (content.startsWith("歌曲")) {
// 將歌曲2個字及歌曲後面的+、空格、-等特殊符號去掉
String keyWord = content.replaceAll("^歌曲[\\+ [email protected]#%^-_=]?", "");
// 如果歌曲名稱為空
if ("".equals(keyWord)) {
respContent = getUsage();
} else {
String[] kwArr = keyWord.split("@");
// 歌曲名稱
String musicTitle = kwArr[0];
// 演唱者預設為空
String musicAuthor = "";
if (2 == kwArr.length)
musicAuthor = kwArr[1];
// 搜尋音樂
Music music = BaiduMusicService.searchMusic(musicTitle, musicAuthor);
// 未搜尋到音樂
if (null == music) {
respContent = "對不起,沒有找到你想聽的歌曲<" + musicTitle + ">。";
} else {
// 音樂訊息
MusicMessage musicMessage = new MusicMessage();
musicMessage.setToUserName(fromUserName);
musicMessage.setFromUserName(toUserName);
musicMessage.setCreateTime(new Date().getTime());
musicMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_MUSIC);
musicMessage.setMusic(music);
respXml = MessageUtil.musicMessageToXml(musicMessage);
}
}
}
}
// 未搜尋到音樂時返回使用指南
if (null == respXml) {
if (null == respContent)
respContent = getUsage();
textMessage.setContent(respContent);
respXml = MessageUtil.textMessageToXml(textMessage);
}
} catch (Exception e) {
e.printStackTrace();
}
return respXml;
}
/**
* 歌曲點播使用指南
*
* @return
*/
public static String getUsage() {
StringBuffer buffer = new StringBuffer();
buffer.append("歌曲點播操作指南").append("\n\n");
buffer.append("回覆:歌曲+歌名").append("\n");
buffer.append("例如:歌曲存在").append("\n");
buffer.append("或者:歌曲存在@汪峰").append("\n\n");
buffer.append("回覆“?”顯示主選單");
return buffer.toString();
}
}
上述程式碼的邏輯比較簡單,使用者傳送“歌曲+名稱”或者“歌曲+名稱@演唱者”就能搜尋歌曲,搜尋不到時會提示使用者,如果傳送其他內容回覆歌曲點播功能的用法。
PS:CSDN2013年度部落格之星評選活動已經拉開序幕,2013年12月14日開始投票,請為柳峰(使用者名稱:lyq8479)投上您的寶貴一票,謝謝!
相關推薦
[042] 微信公眾帳號開發教程第18篇-應用例項之音樂搜尋
引言及內容概要 微信公眾平臺支援向用戶回覆音樂訊息,使用者收到音樂訊息後,點選即可播放音樂。通過音樂訊息,公眾賬號可以實現音樂搜尋(歌曲點播)功能,即使用者輸入想聽的音樂名稱,公眾賬號返回對應的音樂(歌曲)。讀者可以關注xiaoqrobot體驗該功能,操作指南及使用如下所示
[038] 微信公眾帳號開發教程第14篇-自定義選單的建立及選單事件響應
微信5.0釋出 2013年8月5日,伴隨著微信5.0 iPhone版的釋出,公眾平臺也進行了重要的更新,主要包括: 1)運營主體為組織,可選擇成為服務號或者訂閱號; 2)服務號可以申請自定義選單; 3)使用QQ登入的公眾號,可以升級為郵箱登入; 4)使用郵箱登入的公眾號,
[043] 微信公眾平臺開發教程第19篇-應用例項之人臉檢測
CSDN2013年度部落格之星評選活動開始,本人有幸入圍參加評選,如果部落格中的文章對你有所幫助,請為柳峰投上寶貴一票,非常感謝! 在筆者的公眾賬號小q機器人(微訊號:xiaoqrobot)中有一個非常好玩的功能"人臉檢測",它能夠檢測出使用者傳送的圖片中有多少
c# 生成微信公眾帳號帶引數二維碼類
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web
微信公眾帳號給指定使用者推送訊息
轉載: http://blog.csdn.net/blacklife00544/article/details/45974479 http://www.thinkphp.cn/code/1440.html http://www.cnblogs.com/zhuqil/p/33
微信公眾平臺jsapi開發教程(2)獲取timestamp,nonceStr,signature引數
package com.test.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException;
Flask+SAE快速打造微信公眾帳號(有碼)
微信公眾平臺是個很牛逼的東西。大大節約了我們這些玩客的開發成本。Django也不錯,但是開發這種東西,太笨重了,大材小用。還是推薦Flask。 本文以我自己的作品為例,介紹一種簡單方法,可以快速地從零開始開發一個微信公眾帳號,提供簡單的搜尋歌詞的功能,輸入“歌曲名 歌手名”
微信公眾平臺開發教程-微信公眾服務號申請、認證(開通支付)-微信開發教程
微信公眾號服務號與訂閱號的區別 訂閱號: 1、每天可以發1次資訊,每次可以傳送8篇文章(資訊展示在微信公眾號摺疊檔案中) 2、不能申請微信支付功能 3、認證後才可以使用自定義選單功能 4、訂閱號適合:不需要支付功能,以為使用者提供諮詢資訊的企業。 服務號: 1、每月可以發4次資訊,每次可以傳送8
微信公眾號開發學習(1)_____開通微信公眾測試號
微信公眾號平臺:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login appID_______________開發者ID appsecret____________開發者密碼 URL________________伺服器地址
[053] 微信公眾平臺開發教程第23篇-SAE不支援XStream框架的解決方案
問題描述最近幾天(2014年8月20日之後),突然有不少網友反應,柳峰部落格中的微信公眾平臺開發程式碼在SAE上執行會報錯,或者是能正常部署,但向公眾號發訊息沒反應。以前也有一些初學者質疑過我部落格中的程式碼是否能正常執行,最後都被我一一證明是由於他們的不理解和粗心導致,但這
[044] 微信公眾平臺開發教程第20篇-新手解惑40則
筆者在CSDN部落格頻道推出微信公眾平臺開發教程之後,接觸了許多公眾平臺開發愛好者,也幫助他們解決了許多實際的問題,當然這其中有很多問題都是重複的,因此,筆者將這些問題及解答整理出來,以幫助更多初學者少走彎路。1、訂閱號與服務號的主要區別是什麼?訂閱號每天能群
微信公眾平臺網頁開發實戰--1.微信分享一個網頁到朋友圈
微信開發 html5 jssdk 實戰 網頁開發 對微信的JSSDK進行封裝一下,創建一份類似的文件結構,增加index.html與shareApi.js文件,結構如圖3.3所示。 圖3.3 3.2節文件結構另外,提醒讀者一下,wxJSSDK.js文件的JSSDK環境配置中,需要
微信公眾平臺網頁開發實戰--3.利用JSSDK在網頁中獲取地理位置(HTML5+jQuery)
fff .html 1.4 style minimum log fill rdquo 位置 復制一份JSSDK環境,創建一份index.html文件,結構如圖7.1所示。 圖7.1 7.1節文件結構 在location.js中,封裝“getLoc
幸運大轉盤微信公眾抽獎模式開發
幸運大轉盤 幸運大轉盤系統模式定制開發找136-027-9-9492 小楊團隊 微電。幸運大轉盤系統開發平臺、幸運大轉盤開發多少錢、幸運大轉盤如何運營、幸運大轉盤微信端系統開發、幸運大轉盤抽獎方案定制開發、幸運大轉盤抽獎系統源碼開發搭建 一、幸運大轉盤抽獎系統模式軟件玩法規則介紹:
微信公眾訂閱號 上傳臨時素材示例
lap ack 換行 art blog quest bvs 輸入 valueof 1 try { 2 3 //聲明分割線 4 String boundary="-----"; 5 6
微信公眾平臺的開發過程及其要點
調試 導數 判斷 獲得 doc rlogin ads 編碼格式 mysql 微信公眾平臺的搭建,首先需要確定整體的架構模式,我們一般選用B/S的整體架構模式,手機或者pc端可以通過關註微信公眾 號,進而訪問和操作公眾號中的內容,其中的主要搭建包括: A.使用xampp繼
微信小程序前端開發教程-個人中心
方法 load src 小程序前端 mdk 視頻 XML 工作效率 css 小程序前端制作-個人中心,內含服務器端、小程序所有文件、切片文件(可以用小程序切片軟件打開再次編輯)、效果圖 內含以下欄目: 會員頭像 會員名稱 會員類型
微信公共帳號推廣詳情查看百度快照
搞笑 color alt 詳情 後悔 -c 生活 title 分享 惡人從不搞笑,惡人要抓緊時間做惡。微信公共帳號推廣如果有人傷害了你,請一如既往的善良美好,好好享受生活享受愛情,就像沒受過傷一樣。終有一天,那個人會後悔錯過你。微信公共賬號推廣在人生的道路上,如一心追逐名利
ASP.NET MVC5&微信公眾平臺整合開發實戰(響應式布局、JQuery Mobile,Wind
特色 href jquer 入門 騰訊 範圍 最全 mvc 5 前沿 ASP.NET MVC5&微信公眾平臺整合開發實戰(響應式布局、JQuery Mobile,Windows Azure、微信核心開發)網盤地址:https://pan.baidu.com/s/1Y
微信公眾服務號如何快速申請註冊並認證開通支付功能
搞清楚微信公眾訂閱號、服務號的區別 首先要告訴大家的是,定位和用途的不同是區別的本質。微信公眾平臺是個平臺,提供給運營者,而運營者通過這樣一個平臺大家微信公眾號為微信使用者提供資訊和服務。看到了麼,諮詢和服務。微信公眾號的定位和用途是向用戶提供諮詢和服務。而具體的任務分工是這樣的,服務號提供功能服務,訂閱號