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的用戶。

 

只要某個用戶發過來一個消息,微信服務器就會發送一個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;//回復內容有了哦。基本實現了
}
還有其他更多的接口,比如發過來圖片,語音,音樂,視頻等等,還可以獲取用戶信息,用戶地理位置,等等。這里應該又可以想出不少的功能。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM