C#微信公衆平臺帳號開發,從零到整,步驟詳細。

想到微信的火熱,想到其餘公司開發手遊,如雷電,酷跑類的,都不是很火,可是弱智的「打飛機」和「每天酷跑」倒是那麼火熱。因而乎,想作個微信營銷的軟件。
首先想到的是手機連電腦wifi,用抓包工具抓微信的包,而後分析。奮鬥2星期,基本一無所得,獲得一個結論,騰訊的東西真的很差破解。就算千辛萬苦破解一個,只要一更新,前面的努力所有白費。
因而只能老老實實的去用官方提供的接口。也就是微信公衆平臺。
C#開發公衆平臺,須要在官網mp.weixin.qq.com註冊一個帳號,審覈經過後,就能夠開始了。
第一步
點開高級功能,關閉弱智的編輯模式,打開高級的開發模式。
第二部
進入開發模式,填寫接口配置信息。這裏也是剛開始困擾個人地方。URL就是服務器地址,剛開始想用本身電腦作服務器,讓微信服務器訪問,可是我是在內網裏,路由器權限也沒有,沒法端口映射到本身電腦,因此只好網上買了一個服務器空間,一年不到200的那種,空間只有100M,數據庫50M。可是夠用了。
Token是驗證用的令牌,隨便填一個字符串,可是要記住。程序裏也要用這個Token字符串來驗證是否微信服務器發來請求。否則別人能夠模擬請求,僞造信息。
填好後,還不能經過驗證,由於你沒寫代碼。微信服務器訪問你的時候,沒法獲取結果,天然不能經過驗證。
服務器地址填寫後,微信服務器會提交get請求,訪問你的URL而且帶上4個參數。
1,signature 微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。 
2,timestamp 時間戳 
3,nonce 隨機數 
4,echostr 隨機字符串 
他的signature加密方式爲
1. 將token、timestamp、nonce三個參數進行字典序排序2. 將三個參數字符串拼接成一個字符串進行sha1加密3. 開發者得到加密後的字符串可與signature對比,標識該請求來源於微信
經過這些介紹,咱們就能夠開始在默認頁面那裏:好比Default.aspx.cs寫page_load事件,獲取4個參數,按加密算法,得到signature結果,再對比微信發過來的signature,相同,原樣輸出echostr。這樣,就能經過微信服務器驗證。之後每次收到消息後,微信就會發送消息到服務器,服務器通過處理後,就能夠回覆必定的內容給發送過來的那我的消息。算法

 

下面詳細介紹如何經過代碼,來經過剛纔的url接口配置。
ASP.NET DEFAULT.ASPX頁面的page_load事件裏。
首先獲取四個參數。
string signature = Request["signature"];
string timestamp = Request["timestamp"];
string nonce = Request["nonce"];
string echostr = Request["echostr"];
按照前面說的加密過程,得到加密結果。
var arr = new[] { token, timestamp, nonce }.OrderBy(z => z).ToArray();
var arrString = string.Join("", arr);
var sha1 = System.Security.Cryptography.SHA1.Create();
var sha1Arr = sha1.ComputeHash(Encoding.UTF8.GetBytes(arrString));
StringBuilder enText = new StringBuilder();
foreach (var b in sha1Arr)
{
enText.AppendFormat("{0:x2}", b);
}
對比,
if( enText.ToString() == signature )
{
Response.Output.Write(echostr);
}
這樣,就完成了簡單的一步驗證。微信就能經過校驗,之後全部信息都會發到你填寫的這個url服務器上去了。
校驗完後,之後的消息都是post請求你的服務器。請求裏包含一段xml數據。xml數據裏包含了用戶發過來的數據,和這個用戶的openid.你獲取了這些信息後,就能夠發送自動回覆的內容,發給這個openid的用戶。sql

 

只要某個用戶發過來一個消息,微信服務器就會發送一個post請求到你填寫的服務器url上,而後每次都會觸發page_load事件。接收用戶信息,和處理要回復的內容,都在page_load裏。
if (Request.HttpMethod == "POST")
{
string weixin = "";//獲取xml數據
weixin = PostInput();//自定義方法,獲取xml數據
if (!string.IsNullOrEmpty(weixin))
{
ResponseMsg(weixin);//根據獲取的內容,自動回覆必定的內容。
}

這樣,咱們的微信功能就完成了。教程到此結束。。。。。。是不可能的。
先講postinput方法,
private string PostInput()/// 獲取post請求數據
{
Stream s = System.Web.HttpContext.Current.Request.InputStream;
byte[] b = new byte[s.Length];
s.Read(b, 0, (int)s.Length);
return Encoding.UTF8.GetString(b);
}
四行代碼,就獲取了xml數據。asp.net不多用,因此不知道有沒有更好的方法。
而後就是最重要的ResponseMsg方法了。上源碼。
private void ResponseMsg(string weixin)// 服務器響應微信請求
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(weixin);//讀取xml字符串
XmlElement root = doc.DocumentElement;
XmlNode MsgType = root.SelectSingleNode("MsgType");//獲取收到的消息類型。文本(text),圖片(image),語音等。
string messageType = MsgType.InnerText;
try
{
switch (messageType)
{
case "text":
WriteContent(ResponseText.GetResponseMessage(weixin));
break;
case "image":

break;
case "voice":
break;
case "vedio":
break;
case "location":
break;
case "link":
break;
default:
break;
}
Response.End();
}
catch (Exception)
{

}
}
其實前面講的都不重要。重要的是分支語句,
switch (messageType)
{
case "text":
Response.Output.Write(ResponseText.GetResponseMessage(weixin));
break;
就是若是用戶發過來的是文本請求,調用ResponseText.GetResponseMessage()方法。
這個方法裏,就是根據具體的文本關鍵字,通過處理,設置自動回覆的內容。數據庫

 

教程其實快結束了。
只有一個自動回覆的方法沒講。直接貼源碼了。在代碼裏註釋着講。
public static string GetResponseMessage(string weixin)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(weixin);//讀取xml字符串
XmlElement root = doc.DocumentElement;
string message = "對不起,沒法識別您發送的命令。請發送「幫助」來獲取已經實現的功能。";
string resxml = "";
var model = new
{
ToUserName = root.SelectSingleNode("ToUserName").InnerText,//本公衆帳號
FromUserName = root.SelectSingleNode("FromUserName").InnerText,//用戶
CreateTime = root.SelectSingleNode("CreateTime").InnerText,//建立時間
Content = root.SelectSingleNode("Content").InnerText,//消息內容
MsgId = root.SelectSingleNode("MsgId").InnerText//消息ID,64位整型
};//獲取xml數據裏各個結點的內容。
MySQL sql = new MySQL();//這裏是我記錄用戶發送的內容到數據庫的,不寫也沒事。
string str_insert = "insert into ChatRecord values('" + model.FromUserName + "','" + model.Content + "','" + DateTime.Now.ToString().Substring(2) + "')";
if (sql.ExecuteCommand(str_insert) < 0)//插入失敗,記錄日誌
{
StreamWriter sw = new StreamWriter(HttpContext.Current.Request.PhysicalApplicationPath + "/Log/log.txt", true, Encoding.UTF8);
sw.WriteLine(DateTime.Now.ToString().Substring(2) + ": 插入ChatRecord表失敗[" + model.FromUserName + "----" + model.Content + "]");
sw.Close();
}
//這裏就是關鍵的設置自動回覆的內容。回覆的格式,要按照官方提供的來填寫,也是一段xml數據。具體格式,註冊了微信公衆平臺帳號後,看API文檔就有了。這裏稍微簡單的介紹一下。ToUserName,就是剛纔發過來的那個用戶的openid,fromusername通常就是咱們的公衆帳號。CREATETIME就是一個整型時間,unix格式的,轉成距離1970年1月1日0點0分有多少秒就好了。MsgType就是回覆的類型。你能夠回覆圖片,新聞連接,語音,視頻,音樂等。這裏咱們是文本,因此是text。content就是自動回覆的內容。funcflag無論,填寫0.
resxml += "<xml><ToUserName><![CDATA[" + model.FromUserName + "]]></ToUserName><FromUserName><![CDATA[";
resxml += model.ToUserName + "]]></FromUserName><CreateTime>" + MyAPI.ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";
////////////////////////////////////已實現功能////////////////////已實現功能//////////////////////////////////////////////
//這裏若是對方發過來「幫助」,咱們設置常量文本(暫時這麼叫。。),自動回覆給用戶。
if (model.Content == "幫助")
{
message = "目前實現功能有:" + CRLF + "1,幫助:獲取發送命令菜單" + CRLF;
message += "2,翻譯功能。只要發送「翻譯」+空格+須要翻譯的內容,便可實現翻譯功能。" + CRLF;
message += "3,天氣預報。發送 「天氣」+空格+城市名 ,便可查詢該城市6天內天氣預報。如發送「天氣 北京」。" + CRLF;
}
//這裏。若是是「翻譯+空格+詞語」,咱們就調用百度翻譯API,獲取翻譯結果後,再發給用戶。關於這些內容,就不在教程的範圍裏了。種類太多,畢竟你有可能要操做數據庫,請求別的網站,等等各類各類的功能。發送「笑話」,「鬼故事」等等,查數據庫也能夠,請求別的網站也能夠。這裏實現方法就不在這個地方講拉。我也不是很清楚。查了不少資料,才實現了翻譯。
else if (model.Content.Trim().StartsWith("翻譯 "))
{
string str = model.Content.Trim().Substring(3);
MyAPI api = new MyAPI();
MyJSON json = new MyJSON();
BaiDuFanYiResult obj = json.FromJson<BaiDuFanYiResult>(api.BaiduTanslate(str, "auto", "auto"));
message = obj.trans_result[0].dst;
}
//這裏是天氣預報。用戶發「天氣+空格+城市」,
else if (model.Content.Trim().StartsWith("天氣 "))
{
string str = model.Content.Trim().Substring(3);
MyAPI api = new MyAPI();
MyJSON json = new MyJSON();
string strjson = api.WeatherReport(str);
if (strjson.Length < 10)
{
message = "對不起,找不到[" + str + "]的天氣,請正確輸入城市名字,若是城市確實存在,請發送「BUG 城市名」提交BUG";
resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + message + "]]></Content><FuncFlag>0</FuncFlag></xml>";
return resxml;
}
RootObject report = json.FromJson<RootObject>(strjson);
message = "今天: " + report.weatherinfo.temp1 + ", " + report.weatherinfo.weather1 + CRLF;
message += "明天開始接下來5每天氣預報以下:" + CRLF;
message += report.weatherinfo.temp2 + ", " + report.weatherinfo.weather2 + CRLF;
message += report.weatherinfo.temp3 + ", " + report.weatherinfo.weather3 + CRLF;
message += report.weatherinfo.temp4 + ", " + report.weatherinfo.weather4 + CRLF;
message += report.weatherinfo.temp5 + ", " + report.weatherinfo.weather5 + CRLF;
message += report.weatherinfo.temp6 + ", " + report.weatherinfo.weather6 + CRLF;
message += report.weatherinfo.index_d;
}
else if (model.Content.Trim().StartsWith(""))
{

}
//這裏原本是想寫個在線的純文字(能夠帶圖片)的在線多人RPG遊戲。。。暫時還沒開始。。我的能力問題。
else if (model.Content.Trim().StartsWith("遊戲 "))
{
string gamename = model.Content.Trim().Substring(3);
message = Game.GetBackground(gamename);
}
else
{
message = "對不起,沒法識別您發送的命令。請發送「幫助」來獲取已經實現的功能。";
}
resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + message + "]]></Content><FuncFlag>0</FuncFlag></xml>";
return resxml;//回覆內容有了哦。基本實現了
}
還有其餘更多的接口,好比發過來圖片,語音,音樂,視頻等等,還能夠獲取用戶信息,用戶地理位置,等等。這裏應該又能夠想出很多的功能。json

相關文章
相關標籤/搜索