1. 程式人生 > >C#微信公眾號全攻略(4)--實現回覆訊息C#程式碼

C#微信公眾號全攻略(4)--實現回覆訊息C#程式碼

接上文 這個函式把使用者發來的內容交接給messageHelp來處理 最後返回messageHelp.ReturnMessage

private void Handle(string postStr)
{
    messageHelp help = new messageHelp(SqlConnectionString);
    string responseContent = help.ReturnMessage(postStr);

    HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
    HttpContext.Current
.Response.Write(responseContent); }

實現messageHelp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Xml;

public class messageHelp
{
    private string mySqlConnectionString;
    private WXHelper myWXHelper;

    public messageHelp(string SqlConnectionString)
    {
        mySqlConnectionString = SqlConnectionString;
        myWXHelper = new
WXHelper(mySqlConnectionString); } public string ReturnMessage(string postStr) { string responseContent = ""; XmlDocument xmldoc = new XmlDocument(); try { xmldoc.Load(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(postStr))); XmlNode MsgType = xmldoc.SelectSingleNode("/xml/MsgType"
); if (MsgType != null) { switch (MsgType.InnerText) { case "event": responseContent = EventHandle(xmldoc); //事件處理 關注和取消關注 break; case "text": responseContent = TextHandle(xmldoc); //接受文字訊息處理 break; case "image": responseContent = ImageHandle(xmldoc); //接受圖片訊息處理 break; default: responseContent = DefaultHandle(xmldoc); //接受其他訊息處理 break; } } } catch (Exception ex) { DateTime CreateTime = myWXHelper.GetCreateTime(xmldoc); //開發過程中保留一些出錯狀況進資料庫 很簡單的INSERT操作 //myWXHelper.InsertHandleException(ex.Message, CreateTime); } return responseContent; } public string EventHandle(XmlDocument xmldoc) { string responseContent = ""; XmlNode Event = xmldoc.SelectSingleNode("/xml/Event"); if (Event != null) { myWXHelper.InsertEvent(xmldoc); responseContent = myWXHelper.GetEventResponse(xmldoc); } return responseContent; } public string TextHandle(XmlDocument xmldoc) { string responseContent = ""; XmlNode Content = xmldoc.SelectSingleNode("/xml/Content"); if (Content != null) { myWXHelper.InsertTextMsg(xmldoc); //先處理一些特殊功能 responseContent = myWXHelper.GetEspecialTextResponse(xmldoc); if (string.IsNullOrEmpty(responseContent)) { //如果不是特殊功能的則處理關鍵字和其他任意文字的回覆 responseContent = myWXHelper.GetTextResponse(xmldoc); } } return responseContent; } public string ImageHandle(XmlDocument xmldoc) { string responseContent = ""; XmlNode PicUrl = xmldoc.SelectSingleNode("/xml/PicUrl"); if (PicUrl != null) { myWXHelper.InsertImageMsg(xmldoc); responseContent = myWXHelper.GetImageResponse(xmldoc); } return responseContent; } public string DefaultHandle(XmlDocument xmldoc) { string responseContent = ""; return responseContent; } }

ReturnMessage中輸入的是整個XML文件
MsgType節點表示訊息型別
事件、文字、圖片訊息對應不同的處理
事件包括關注 和 取消關注 需要對使用者表進行操作
文字需要保留使用者傳送的內容
圖片需要保留使用者傳送的圖片
GetEspecialTextResponse對某些特定字處理
InsertEvent GetEventResponse InsertTextMsg GetTextResponse InsertImageMsg GetImageResponse需要實現,看字面就能知道幹什麼用的

基本思路 得到XML文件,根據訊息型別不同進行處理 文字和圖片需要儲存到資料庫 關注和取消關注修改對應本地使用者表 關注還需要回復給使用者訊息內容 對於特殊的文字 需要優先處理回覆 比如傳送問號得到選單傳送簽到進行簽到等功能。

僅示例

    public void InsertEvent(XmlDocument xmldoc)
    {
        XmlNode xnFromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
        string openid = xnFromUserName.InnerText;

        DateTime CreateTime = GetCreateTime(xmldoc);

        XmlNode xnEvent = xmldoc.SelectSingleNode("/xml/Event");
        string Event = xnEvent.InnerText;

        using (SqlConnection mySqlConnection = new SqlConnection(mySqlConnectionString))
        {
            //得到UserID 新使用者的話就建立
            Int32 UserID = GetUserID(openid);

            StrSQL = "INSERT INTO [WX_Event] ([UserID], [CreateTime], [Event]) VALUES (";
            StrSQL += "@UserID, @CreateTime, @Event)";

            SqlCommand mySqlCommand = new SqlCommand(StrSQL, mySqlConnection);
            mySqlCommand.Parameters.AddWithValue("@UserID", UserID);
            mySqlCommand.Parameters.AddWithValue("@CreateTime", CreateTime);
            mySqlCommand.Parameters.AddWithValue("@Event", Event);

            mySqlConnection.Open();
            mySqlCommand.ExecuteNonQuery();
            mySqlConnection.Close();
        }
    }

資料庫裡對WX_Event表設定觸發器 unsubscribe時 修改使用者狀態為未關注 修改使用者的取消關注時間 設定使用者的重關注標記等 這樣當下一次關注時可以知道用記是不是首次關注 還是取消關注後再次關注 因為每個使用者對於同一公眾號openid不變

這裡寫圖片描述

public string GetEventResponse(XmlDocument xmldoc)
    {
        string responseContent = "";
        StringBuilder sb = new StringBuilder();

        XmlNode ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName");
        XmlNode FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
        string openid = FromUserName.InnerText;
        XmlNode xnEvent = xmldoc.SelectSingleNode("/xml/Event");
        string Event = xnEvent.InnerText;

        Int32 UserID = GetUserID(openid);

        if (Event == "subscribe")
        {
            using (SqlConnection mySqlConnection = new SqlConnection(mySqlConnectionString))
            {
                mySqlConnection.Open();

                string Src = "";
                string nickname = "";
                SqlCommand mySqlCommand = new SqlCommand("SELECT * FROM [WX_User] WHERE [ID] = @UserID", mySqlConnection);
                mySqlCommand.Parameters.AddWithValue("@UserID", UserID);
                SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(mySqlCommand);
                DataTable myDataTable = new DataTable();
                mySqlDataAdapter.Fill(myDataTable);
                nickname = Convert.ToString(myDataTable.Rows[0]["nickname"]);
                mySqlCommand = new SqlCommand("SELECT COUNT(ID) AS SubscribeOrder FROM [view_WX_User_Subscirbe] WHERE ISNULL(SubscribeTime, '') <> ''", mySqlConnection);
                int SubscribeOrder = Convert.ToInt32(mySqlCommand.ExecuteScalar());

                if (myDataTable.Rows[0]["UnSubscribeTime"] == DBNull.Value)  //首次關注
                {
                    Src = "親愛的 #nickname, 公眾號 感謝您的關注!";
                    Src += String.Format("\r\n您是第 {0} 位客人", SubscribeOrder);
                    Src += "\r\n" + dictConstant.GetValue("subscribe", "");
                }
                else  //重新關注
                {
                    Src = "親愛的 #nickname, 公眾號曾經和您小別! 感謝您再次關注!";
                    Src += String.Format("\r\n您當前是第 {0} 位客人", SubscribeOrder);
                    Src += "\r\n" + dictConstant.GetValue("resubscribe", "");
                }
                Src = Src.Replace("#nickname", nickname);
                Src = Src.Replace("#openid", openid);

                sb.Append(RegexHelper.GetStringBuilderFromLineText(Src));
                responseContent = string.Format(ReplyType.Message_Text,
                            FromUserName.InnerText,
                            ToUserName.InnerText,
                            DateTime.Now.Ticks,
                            sb.ToString()
                        );
            }
        }

        return responseContent;
    }
    public class ReplyType
    {
        /// <summary>
        /// 普通文字訊息
        /// </summary>
        public static string Message_Text
        {
            get
            {
                return @"<xml>
                            <ToUserName><![CDATA[{0}]]></ToUserName>
                            <FromUserName><![CDATA[{1}]]></FromUserName>
                            <CreateTime>{2}</CreateTime>
                            <MsgType><![CDATA[text]]></MsgType>
                            <Content><![CDATA[{3}]]></Content>
                            </xml>";
            }
        }
    }
    public Int32 GetUserID(string openid)
    {
        Int32 Res = -1;
        if (!string.IsNullOrWhiteSpace(openid))
        {
            using (SqlConnection mySqlConnection = new SqlConnection(mySqlConnectionString))
            {
                SqlCommand mySqlCommand = new SqlCommand("SELECT * FROM [WX_User] WHERE [openid] = @openid", mySqlConnection);
                mySqlCommand.Parameters.AddWithValue("@openid", openid);
                SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(mySqlCommand);
                DataTable myDataTable = new DataTable();
                mySqlDataAdapter.Fill(myDataTable);
                if (myDataTable.Rows.Count != 0)
                {
                    Res = Convert.ToInt32(myDataTable.Rows[0]["ID"]);
                }
                else
                {
                    mySqlConnection.Open();

                    StrSQL = "BEGIN TRAN; INSERT INTO [WX_User] ([openid]) VALUES (@openid); SELECT IDENT_CURRENT('WX_User'); COMMIT TRAN;";
                    mySqlCommand = new SqlCommand(StrSQL, mySqlConnection);
                    mySqlCommand.Parameters.AddWithValue("@openid", openid);

                    Res = Convert.ToInt32(mySqlCommand.ExecuteScalar());

                    //該使用者不存在於表中 需要 使用Token和Cookie獲取關注使用者的基本資訊
                    string UserInfoJSON = "";
                    if (OHWXHelper.GetUserInfoJSON(openid, WXControllerToken, WXControllerCookie, out UserInfoJSON))
                    {
                        DataTable dtUserInfo = OHWXHelper.GetUserInfoDataTable(UserInfoJSON);
                        if (dtUserInfo.Rows.Count == 1)
                        {
                            string nickname, city, province, country, headimgurl, subscribe_time, signature;
                            int sex;
                            nickname = Convert.ToString(dtUserInfo.Rows[0]["user_name"]);
                            nickname = nickname.Replace(@"\""", @"""");
                            nickname = nickname.Replace(@"\/", @"/");
                            sex = Convert.ToInt16(dtUserInfo.Rows[0]["user_gender"]);
                            city = Convert.ToString(dtUserInfo.Rows[0]["user_city"]);
                            province = Convert.ToString(dtUserInfo.Rows[0]["user_province"]);
                            country = Convert.ToString(dtUserInfo.Rows[0]["user_country"]);
                            headimgurl = Convert.ToString(dtUserInfo.Rows[0]["user_head_img"]).Replace(@"\/", @"/");
                            subscribe_time = Convert.ToString(dtUserInfo.Rows[0]["user_create_time"]);
                            signature = Convert.ToString(dtUserInfo.Rows[0]["user_signature"]);
                            signature = signature.Replace(@"\""", @"""");
                            signature = signature.Replace(@"\/", @"/");

                            StrSQL = "UPDATE [WX_User] SET [openid] = @openid, [nickname] = @nickname, [sex] = @sex, [city] = @city, [province] = @province, [country] = @country, [headimgurl] = @headimgurl, [subscribe_time] = @subscribe_time, [signature] = @signature ";
                            StrSQL += "WHERE [ID] = @ID";
                            mySqlCommand = new SqlCommand(StrSQL, mySqlConnection);
                            mySqlCommand.Parameters.AddWithValue("@openid", openid);
                            mySqlCommand.Parameters.AddWithValue("@nickname", nickname);
                            mySqlCommand.Parameters.AddWithValue("@sex", sex);
                            mySqlCommand.Parameters.AddWithValue("@city", city);
                            mySqlCommand.Parameters.AddWithValue("@province", province);
                            mySqlCommand.Parameters.AddWithValue("@country", country);
                            mySqlCommand.Parameters.AddWithValue("@headimgurl", headimgurl);
                            mySqlCommand.Parameters.AddWithValue("@subscribe_time", subscribe_time);
                            mySqlCommand.Parameters.AddWithValue("@signature", signature);
                            mySqlCommand.Parameters.AddWithValue("@ID", Res);
                            mySqlCommand.ExecuteNonQuery();
                        }
                        else
                        {
                            mySqlCommand = new SqlCommand("UPDATE [WX_Controller] SET [InvalidTag] = 1, [InvalidTime] = GETDATE()", mySqlConnection);
                            mySqlCommand.ExecuteNonQuery();
                        }
                    }
                    else
                    {
                        mySqlCommand = new SqlCommand("UPDATE [WX_Controller] SET [InvalidTag] = 1, [InvalidTime] = GETDATE()", mySqlConnection);
                        mySqlCommand.ExecuteNonQuery();
                    }
                    mySqlConnection.Close();
                }
            }
        }
        return Res;
    }

程式碼僅示例 從我實際的專案中複製得來 可以在使用者關注時回覆給使用者是第幾位關注的使用者 同時可以通過控制檯的Token和Cookie 根據openid獲取使用者的一些基本資訊暱稱 性別 設定的地區 頭像連結 微信中設定的簽名等等(GetUserInfoJSON)功能實現將JSON直接轉換成DataTable

    private Dictionary<string, string> dictConstant = new Dictionary<string, string>();
    private Dictionary<string, string> dictVariant = new Dictionary<string, string>();
    private Dictionary<string, string> dictKeyword = new Dictionary<string, string>();

自動回覆採用了字典變數方式 在資料庫中保留內容 可以隨時直接改資料庫 而不用寫死在程式碼裡,包括常量、變數、關鍵字 三大型別,用變數替換常量中的部分

相關推薦

C#公眾4--實現回覆訊息C#程式碼

接上文 這個函式把使用者發來的內容交接給messageHelp來處理 最後返回messageHelp.ReturnMessage private void Handle(string postStr) { messageHelp help = new

C#公眾3--接管所有訊息驗證部分 C#程式碼

新建網站 新建一般處理程式 怎麼操作SQL資料庫不寫了 只發一些關鍵部分程式碼 一般處理程式關鍵程式碼 public class Interface : IHttpHandler { public stati

C#公眾5--群發訊息時的openid對應的使用者是誰呢

有一個openid不屬於公眾號關注使用者的任何一位 在通過微信控制檯群發訊息後 將有一個Event為MASSSENDJOBFINISH的事件推送 對應的openid 他是誰呢 他的nickname是張三瘋 來自 中國 廣東 廣州 簽名是DayDayUpUp

公眾支付掃碼PHP

基本思路: 1、使用者掃碼進入我們的系統頁面(自己定義的一個使用者輸入金額的頁面)       通過獲取CODE然後獲取openid 2、使用者輸完金額後,點選支付按鈕,進入統一支付介面   &nbs

公眾支付開發手記node

微信支付 前言 總結一下最近業務開發中對微信公眾號支付的開發過程,微信支付的開發前提是已經具備可上線微信公眾號開發的基礎上進行的,如果你的開發階段目前停留在起步,建議參考這篇文章開始。 好了,來聊一聊微信支付。不論是今天的分享,還是網上其他的分享,開頭總是在吐槽微信的文件。我也不例外,剛開始總是覺得文件

公眾java開發沉澱推送群發訊息

許可權 只有認證的的訂閱號 和 服務號,可以群發訊息。自己申請的測試號,或者沒認證的訂閱號、服務號,沒有許可權。 樣子 發出去的文字訊息、圖片訊息等於普通訊息無差,我就不多說了。傳送出去的圖文訊息是這樣子的。 者其實是兩條圖文訊息,上面的真好是第一條,下面

公眾授權---第三方平臺php

用過微擎、微贊、微動力等第三方公眾號管理平臺的人都知道,需要在這些平臺中接入公眾號(就是授權給第三方平臺),為了瞭解探究微擎中掃碼授權的機制,看了微信開放平臺中的第三方平臺開發,並做了例項,寫下此文紀念我這一天遇到的坑!!! 公眾平臺第三方平臺是為了讓公

公眾授權登入一laravel

namespace App\Http\Controllers; use Illuminate\Http\Request; use Validator; use Session; use App\Http\Requests; use App\Http\Controller

公眾java開發沉澱獲取使用者資訊

​ 關注公眾號後,公眾號可獲得關注者的OpenID(加密後的微訊號,每個使用者對每個公眾號的OpenID是唯一的。對於不同公眾號,同一使用者的openid不同)。公眾號可通過OpenID獲取使用者基本資訊,包括暱稱、頭像、性別、所在城市、語言和關注時間。 ​

公眾開發完整教程 PHP7.0版本,TP5.0框架

因為工作的需要,這一兩年對微信公眾號和小程式,專案製作的比較多。所以我才打算寫一篇全面的製作教程,當然了,最好的教程是微信工作平臺的文件。我這裡只是講述一下我的工作中的製作流程。所有相關文章的原始碼,我託管在我自己的github上面,歡迎關注:地址點選開啟連結。接下來開始我們

C#公眾開發之接收事件推送與消息排重的方法

data push con 這樣的 etime ali 推薦 系列 是否 本文實例講述了C#微信公眾號開發之接收事件推送與消息排重的方法。分享給大家供大家參考。具體分析如下: 微信服務器在5秒內收不到響應會斷掉連接,並且重新發起請求,總共重試三次。這樣的話,問題就來了。有

公眾 - 局返回碼說明

url d參數 包含 rpi 標誌位 user 時間 2個 文件中 返回碼說明 -1 系統繁忙 0 請求成功 40001 獲取access_token時Secret錯誤,或者access_token無效 40002 不合法的憑證類型 40003 不合法

C#公眾開發 -- 獲取API呼叫所需的全域性唯一票據access_token

access_token是公眾號的全域性唯一票據,公眾號呼叫各介面時都需使用access_token。開發者需要進行妥善儲存。access_token的儲存至少要保留512個字元空間。access_token的有效期目前為2個小時,需定時重新整理,重複獲取將導致上次獲取的access_token失效。 獲取

C#公眾開發 -- 驗證成為開發者

接下來就是驗證成為開發者了。先來看一下驗證的介面及需要填寫的資訊 在介面配置資訊中填寫需要處理驗證資訊的頁面或者一般性處理檔案,這裡以aspx頁面為例 URl中的格式為:http://XXX.com/wxapi.aspx ,其中XXX.com也即是上文提到的需要有一個外網可以訪問的域名,wxapi.a

C#公眾開發 -- 開發之前的準備

本系列文章講述的是利用C#語言開發微信公眾號的例項教程,主要是服務號的開發(因為訂閱號不能獲取微信開發的高階介面) 想要開發微信服務公眾號,首先必須要有一個認證的微信服務號,這樣才能夠使用微信提供的所有高階介面。在這裡我個人主要以開發講解為主,所以使用了微信提供給開發者一個很方便的工具--公眾平臺測試帳號(

C#公眾開發 -- 使用者關注之後自動回覆

通過了上一篇文章之後的微信開發者驗證之後,我們就可以做微信公眾號的程式碼開發了。 當我們點選關注某個公眾號的時候,有時候會發現他會自動給我們回覆一條訊息,比如歡迎關注XXX公眾號。這個功能其實是在點選關注的時候,使用者觸發了微信定義的事件,同時微信會返回給我們一個XML資料包,微信官方的解釋如下: 推送X

公眾支付開發全過程java版

sdk 命令 所有 data 權限 {} servle res ast 文章有不當之處,歡迎指正,如果喜歡微信閱讀,你也可以關註我的微信公眾號:好好學java,獲取優質學習資源。 一、微信官方文檔微信支付開發流程(公眾號支付) 首先我們到微信支付的官方文檔的開發步驟部分查

公眾客服介面給指定使用者openid傳送訊息

微信開發文件: 客服介面-發訊息 介面呼叫請求說明 http請求方式: POST https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN 各訊息型別所需的

小程式和公眾開發注意事項有些是從開發文件中摘抄出來的

先從簡單的說起 (會提醒你的一些注意事項) 1、微信公眾號和小程式名稱可以由中文、數字、英文。長度在3-20個字元之間,一箇中文字等於2個字元。 2、微信公眾號和小程式名稱不得與公眾平臺已有的訂閱號

公眾利用客服介面主動給使用者傳送訊息的方法

目前微信並沒有放出主動給使用者傳送訊息的介面,但是我們可以使用其多客服介面來達到主動給使用者傳送訊息的目的。 當用戶和公眾號產生特定動作的互動時(具體動作列表請見下方說明),微信將會把訊息資料推送給開發者,開發者可以在一段時間內(目前修改為48小時)呼叫客服介面,通過PO