WeChat のメッセージ タイプは、テキスト、画像、音声、ビデオ、地理的位置、リンク、イベント メッセージです。イベントメッセージ以外のメッセージを総称して通常メッセージと呼びます。 WeChat のメッセージのプッシュと応答は、XML データ パケットで送信されます。ユーザーが公式アカウントにメッセージを送信するとき、WeChat サーバーが 5 秒以内に応答を受信しない場合、サーバーは切断されてリクエストを再開始し、合計 3 回再試行します。通常のメッセージは msgid を使用して重複を排除し、重複メッセージによるビジネス ロジックへの影響を回避できます。
サーバーが 5 秒以内に処理して応答することを保証できない場合は、空の文字列を使用して直接応答できます。WeChat サーバーはこのリクエストを処理せず、再試行も開始しません。なお、ここでいう空文字列への返信は、空のテキストメッセージへの返信ではなく、Response.Write("")への直接返信となります。
以下は、各一般的なメッセージの簡単な説明です。
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> <MsgId>1234567890123456</MsgId> </xml>
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[image]]></MsgType> <PicUrl><![CDATA[this is a url]]></PicUrl> <MediaId><![CDATA[media_id]]></MediaId> <MsgId>1234567890123456</MsgId> </xml>
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1357290913</CreateTime><MsgType><![CDATA[voice]]></MsgType><MediaId><![CDATA[media_id]]></MediaId><Format><![CDATA[Format]]></Format><MsgId>1234567890123456</MsgId></xml>
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1357290913</CreateTime><MsgType><![CDATA[video]]></MsgType><MediaId><![CDATA[media_id]]></MediaId><ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId><MsgId>1234567890123456</MsgId></xml>
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1351776360</CreateTime><MsgType><![CDATA[location]]></MsgType><Location_X>23.134521</Location_X><Location_Y>113.358803</Location_Y><Scale>20</Scale><Label><![CDATA[位置信息]]></Label><MsgId>1234567890123456</MsgId></xml>
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1351776360</CreateTime><MsgType><![CDATA[link]]></MsgType><Title><![CDATA[公众平台官网链接]]></Title><Description><![CDATA[公众平台官网链接]]></Description><Url><![CDATA[url]]></Url><MsgId>1234567890123456</MsgId></xml>
注意深いプログラマは、すべてのメッセージ (イベント メッセージを含む) に次のフィールドが含まれていることを認識しているはずです
パラメータ | 説明 |
---|---|
ToUserName | 受信者の WeChat ID |
FromUserName | 送信者の Weチャット ID (ある場合)は一般ユーザー、OpenID です |
CreateTime | メッセージ作成時間 |
MsgType | メッセージタイプ |
メッセージのタイプは記事の冒頭でそれぞれ説明されています: テキスト、画像、音声、ビデオ、場所、リンク、イベント
管理とコードの記述を容易にするために、これらのメッセージ タイプの列挙を記述することができます。以下の通り:
/// <summary> /// 消息类型枚举 /// </summary> public enum MsgType { /// <summary> ///文本类型 /// </summary> TEXT, /// <summary> /// 图片类型 /// </summary> IMAGE, /// <summary> /// 语音类型 /// </summary> VOICE, /// <summary> /// 视频类型 /// </summary> VIDEO, /// <summary> /// 地理位置类型 /// </summary> LOCATION, /// <summary> /// 链接类型 /// </summary> LINK, /// <summary> /// 事件类型 /// </summary> EVENT }
ここで説明しますが、C# ではイベントはキーワードであるため、列挙ではイベントを使用できません。そのため、統一性を保つために、ここでは列挙ではすべて大文字を使用します。
すべてのメッセージ本文には上記のフィールドがあるため、基本クラスを作成し、さまざまなメッセージ エンティティがこの基本クラスを 継承 することができます。 (問題に悩んでいます。以前はクラスのメッセージ本文にすべてのフィールドを書いていました。これは呼び出すのに非常に便利でした。しかし、クラス内のフィールドがますます増えて、不快になってきました。 , 私は才能も知識もほとんどなく、オブジェクト指向の使い方に熟達していないので、常にクラス内のすべてのフィールドをリストします
呼び出すときは、直接var ss = WeiXinRequest.RequestHelper(token, EncodingAESKey, appid) );
はWeiXinRequestを返します、そして、メッセージタイプとイベントタイプを判断して応答します
今日は、サブクラスとベースクラスに分割するといういくつかの調整を行いました。コードの可読性は向上しますが、それほど便利ではありません。親愛なる友人、アドバイスをお願いします
)
各メッセージ エンティティの基本クラスは、メッセージ本文のパブリック フィールドとユーザーのリクエストに応答するために使用される仮想メソッド (応答メッセージはこの記事の焦点ではありません)。そのため、メソッド本体は掲載されていません。以降の記事に注意してください)。
基本クラスのメソッドのパラメーターの 1 つは EnterParam タイプであり、このクラスは、ユーザーがトークン、暗号化キー、appid などのメッセージにアクセスしてその信頼性を検証するときに使用する必要があるパラメーターです。 。定義は次のとおりです。 public abstract class BaseMessage
{ /// <summary>
/// 开发者微信号 /// </summary>
public string ToUserName { get; set; } /// <summary>
/// 发送方帐号(一个OpenID) /// </summary>
public string FromUserName { get; set; } /// <summary>
/// 消息创建时间 (整型) /// </summary>
public string CreateTime { get; set; } /// <summary>
/// 消息类型 /// </summary>
public MsgType MsgType { get; set; } public virtual void ResponseNull()
{
Utils.ResponseWrite("");
} public virtual void ResText(EnterParam param, string content)
{
} /// <summary>
/// 回复消息(音乐) /// </summary>
public void ResMusic(EnterParam param, Music mu)
{
} public void ResVideo(EnterParam param, Video v)
{ } /// <summary>
/// 回复消息(图片) /// </summary>
public void ResPicture(EnterParam param, Picture pic, string domain)
{
} /// <summary>
/// 回复消息(图文列表) /// </summary>
/// <param name="param"></param>
/// <param name="art"></param>
public void ResArticles(EnterParam param, List<Articles> art)
{ } /// <summary>
/// 多客服转发 /// </summary>
/// <param name="param"></param>
public void ResDKF(EnterParam param)
{
} /// <summary>
/// 多客服转发如果指定的客服没有接入能力(不在线、没有开启自动接入或者自动接入已满),该用户会一直等待指定客服有接入能力后才会被接入,而不会被其他客服接待。建议在指定客服时,先查询客服的接入能力指定到有能力接入的客服,保证客户能够及时得到服务。 /// </summary>
/// <param name="param">用户发送的消息体</param>
/// <param name="KfAccount">多客服账号</param>
public void ResDKF(EnterParam param, string KfAccount)
{ } private void Response(EnterParam param, string data)
{
}
}
/// <summary> /// 微信接入参数 /// </summary> public class EnterParam { /// <summary> /// 是否加密 /// </summary> public bool IsAes { get; set; } /// <summary> /// 接入token /// </summary> public string token { get; set; } /// <summary> ///微信appid /// </summary> public string appid { get; set; } /// <summary> /// 加密密钥 /// </summary> public string EncodingAESKey { get; set; } }
画像エンティティ:
public class TextMessage:BaseMessage { /// <summary> /// 消息内容 /// </summary> public string Content { get; set; } /// <summary> /// 消息id,64位整型 /// </summary> public string MsgId { get; set; } }
音声エンティティ:
public class ImgMessage : BaseMessage { /// <summary> /// 图片路径 /// </summary> public string PicUrl { get; set; } /// <summary> /// 消息id,64位整型 /// </summary> public string MsgId { get; set; } /// <summary> /// 媒体ID /// </summary> public string MediaId { get; set; } }
ビデオ エンティティ:
public class VoiceMessage : BaseMessage { /// <summary> /// 缩略图ID /// </summary> public string MsgId { get; set; } /// <summary> /// 格式 /// </summary> public string Format { get; set; } /// <summary> /// 媒体ID /// </summary> public string MediaId { get; set; } /// <summary> /// 语音识别结果 /// </summary> public string Recognition { get; set; } }
リンク エンティティ:
public class VideoMessage : BaseMessage { /// <summary> /// 缩略图ID /// </summary> public string ThumbMediaId { get; set; } /// <summary> /// 消息id,64位整型 /// </summary> public string MsgId { get; set; } /// <summary> /// 媒体ID /// </summary> public string MediaId { get; set; } }
メッセージ エンティティが定義されたら、次のステップは次のとおりです。 WeChat サーバーに従ってプッシュします。メッセージ本文は対応するエンティティに解析されます。当初は C# に付属の XML シリアル化を使用してシリアル化されたコンポーネントを送信する予定でしたが、試してみると必ず XML エラーが報告されるため、単純にリフレクションを使用した処理メソッドを記述しました。
public class LinkMessage : BaseMessage { /// <summary> /// 缩略图ID /// </summary> public string MsgId { get; set; } /// <summary> /// 标题 /// </summary> public string Title { get; set; } /// <summary> /// 描述 /// </summary> public string Description { get; set; } /// <summary> /// 链接地址 /// </summary> public string Url { get; set; } }
XML 処理メソッドが定義された後、以下は、さまざまなメッセージ タイプに応じて対応するエンティティの解析について話しましょう:
public static T ConvertObj<T>(string xmlstr) { XElement xdoc = XElement.Parse(xmlstr); var type = typeof(T); var t = Activator.CreateInstance<T>(); foreach (XElement element in xdoc.Elements()) { var pr = type.GetProperty(element.Name.ToString()); if (element.HasElements) {//这里主要是兼容微信新添加的菜单类型。nnd,竟然有子属性,所以这里就做了个子属性的处理 foreach (var ele in element.Elements()) { pr = type.GetProperty(ele.Name.ToString()); pr.SetValue(t, Convert.ChangeType(ele.Value, pr.PropertyType), null); } continue; } if (pr.PropertyType.Name == "MsgType")//获取消息模型 { pr.SetValue(t, (MsgType)Enum.Parse(typeof(MsgType), element.Value.ToUpper()), null); continue; } if (pr.PropertyType.Name == "Event")//获取事件类型。 { pr.SetValue(t, (Event)Enum.Parse(typeof(Event), element.Value.ToUpper()), null); continue; } pr.SetValue(t, Convert.ChangeType(element.Value, pr.PropertyType), null); } return t; }
CreateMessage メソッドはデータ パケットを渡し (暗号化されている場合は、復号化して渡す必要があります)、対応するエンティティを次の形式で返します。基本クラスの。
通常のメッセージの受信はここでほぼ完了しました。以前のブログ投稿に基づいて、修正されたアクセス コードが次のように掲載されます:
public class MessageFactory { public static BaseMessage CreateMessage(string xml) { XElement xdoc = XElement.Parse(xml); var msgtype = xdoc.Element("MsgType").Value.ToUpper(); MsgType type = (MsgType)Enum.Parse(typeof(MsgType), msgtype); switch (type) { case MsgType.TEXT: return Utils.ConvertObj<TextMessage>(xml); case MsgType.IMAGE: return Utils.ConvertObj<ImgMessage>(xml); case MsgType.VIDEO: return Utils.ConvertObj<VideoMessage>(xml); case MsgType.VOICE: return Utils.ConvertObj<VoiceMessage>(xml); case MsgType.LINK: return Utils.ConvertObj<LinkMessage>(xml); case MsgType.LOCATION: return Utils.ConvertObj<LocationMessage>(xml); case MsgType.EVENT://事件类型 { } break; default: return Utils.ConvertObj<BaseMessage>(xml); } } }
[関連推奨事項]
1.
WeChat パブリック アカウント プラットフォームのソース コードのダウンロード2.
WeChat Lala テイクアウェイ 2.2.4 復号化された WeChat ルービック キューブ ソース コードのオープン ソース バージョン以上がテキストメッセージを受信するための WeChat の開発の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。