/*----------------------------------------------------------------
Copyright (C) 2023 Senparc
文件名:CustomWxOpenMessageHandler.cs
文件功能描述:微信小程序自定义MessageHandler
创建标识:Senparc - 20150312
修改标识:Senparc - 20200909
修改描述:使用异步方法
----------------------------------------------------------------*/
//DPBMARK_FILE MiniProgram
using Senparc.CO2NET.Utilities;
using Senparc.NeuChar.Entities;
using Senparc.Weixin.WxOpen.Entities;
using Senparc.Weixin.WxOpen.Entities.Request;
using Senparc.Weixin.WxOpen.MessageHandlers;
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Senparc.CO2NET.Helpers;
using Senparc.CO2NET.Extensions;
using Senparc.Weixin.MP;
using Senparc.CO2NET.Trace;
#if NET462
using System.Web.Configuration;
#else
#endif
namespace Senparc.Weixin.Sample.CommonService.WxOpenMessageHandler
{
///
/// 自定义MessageHandler
/// 把MessageHandler作为基类,重写对应请求的处理方法
///
public partial class CustomWxOpenMessageHandler : WxOpenMessageHandler
{
private string appId = Config.SenparcWeixinSetting.WxOpenAppId;
private string appSecret = Config.SenparcWeixinSetting.WxOpenAppSecret;
///
/// 为中间件提供生成当前类的委托
///
public static Func GenerateMessageHandler =
(stream, postModel, maxRecordCount, serviceProvider) => new CustomWxOpenMessageHandler(stream, postModel, maxRecordCount, serviceProvider);
public CustomWxOpenMessageHandler(Stream inputStream, PostModel postModel, int maxRecordCount = 0, IServiceProvider serviceProvider = null)
: base(inputStream, postModel, maxRecordCount, serviceProvider: serviceProvider)
{
//这里设置仅用于测试,实际开发可以在外部更全局的地方设置,
//比如MessageHandler.GlobalGlobalMessageContext.ExpireMinutes = 3。
GlobalMessageContext.ExpireMinutes = 3;
if (!string.IsNullOrEmpty(postModel.AppId))
{
appId = postModel.AppId;//通过第三方开放平台发送过来的请求
}
//在指定条件下,不使用消息去重
base.OmitRepeatedMessageFunc = requestMessage =>
{
var textRequestMessage = requestMessage as RequestMessageText;
if (textRequestMessage != null && textRequestMessage.Content == "容错")
{
return false;
}
return true;
};
}
public override async Task OnExecutingAsync(CancellationToken cancellationToken)
{
//测试MessageContext.StorageData
var currentMessageContext = await base.GetCurrentMessageContext();
if (currentMessageContext.StorageData == null || (currentMessageContext.StorageData is int))
{
currentMessageContext.StorageData = 0;
}
await base.OnExecutingAsync(cancellationToken);
}
public override async Task OnExecutedAsync(CancellationToken cancellationToken)
{
await base.OnExecutedAsync(cancellationToken);
try
{
var currentMessageContext = await base.GetCurrentMessageContext();
currentMessageContext.StorageData = ((int)currentMessageContext.StorageData) + 1;
}
catch (Exception ex)
{
Senparc.CO2NET.Trace.SenparcTrace.SendCustomLog("小程序 OnExecutedAsync 常规跟踪(开发者请忽略)", ex.ToString() + "\r\n" + ex.StackTrace?.ToString());
}
}
///
/// 处理文字请求
///
///
public override async Task OnTextRequestAsync(RequestMessageText requestMessage)
{
//TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs
//这里可以进行数据库记录或处理
//发送一条客服消息回复用户
var contentUpper = requestMessage.Content.ToUpper();
if (contentUpper == "LINK")
{
//发送客服消息
await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendLinkAsync(appId, OpenId, "欢迎使用 Senparc.Weixin SDK", "感谢大家的支持!\r\n\r\n盛派永远在你身边!",
"https://weixin.senparc.com", "https://sdk.weixin.senparc.com/images/book-cover-front-small-3d-transparent.png");
}
else if (contentUpper == "CARD")
{
//上传封面临时素材
var uploadResult = await MP.AdvancedAPIs.MediaApi.UploadTemporaryMediaAsync(appId, UploadMediaFileType.image, ServerUtility.ContentRootMapPath("~/Images/Logo.thumb.jpg"));
//发送客服消息
await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendMiniProgramPageAsync(appId, OpenId, "欢迎使用 Senparc.Weixin SDK", "pages/websocket/websocket",
uploadResult.media_id);
}
else if (contentUpper == "客服")
{
await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, "您即将进入客服");
var responseMessage = base.CreateResponseMessage();
return responseMessage;
}
else
{
var result = new StringBuilder();
result.AppendFormat("您刚才发送了文字信息:{0}\r\n\r\n", requestMessage.Content);
var messageContext = await GetCurrentMessageContext().ConfigureAwait(false);
if (messageContext.RequestMessages.Count > 1)
{
result.AppendFormat("您刚才还发送了如下消息({0}/{1}):\r\n", messageContext.RequestMessages.Count,
messageContext.StorageData);
for (int i = messageContext.RequestMessages.Count - 2; i >= 0; i--)
{
var historyMessage = messageContext.RequestMessages[i];
string content = null;
if (historyMessage is RequestMessageText)
{
content = (historyMessage as RequestMessageText).Content;
}
else if (historyMessage is RequestMessageEvent_UserEnterTempSession)
{
content = "[进入客服]";
}
else
{
content = string.Format("[非文字信息:{0}]", historyMessage.GetType().Name);
}
result.AppendFormat("{0} 【{1}】{2}\r\n",
historyMessage.CreateTime.ToString("HH:mm:ss"),
historyMessage.MsgType.ToString(),
content
);
}
result.AppendLine("\r\n");
}
//处理微信换行符识别问题
var msg = result.ToString().Replace("\r\n", "\n");
//发送客服消息
await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, msg);
//也可以使用微信公众号的接口,完美兼容:
//Senparc.Weixin.MP.AdvancedAPIs.CustomApi.SendText(appId, WeixinOpenId, msg);
}
return new SuccessResponseMessage();
//和公众号一样回复XML是无效的:
// return new SuccessResponseMessage()
// {
// ReturnText = string.Format(@"
//
//
//
// 1357986928
//
//
//",requestMessage.FromUserName,requestMessage.ToUserName)
// };
}
public override async Task OnImageRequestAsync(RequestMessageImage requestMessage)
{
//发来图片,进行处理
await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, "刚才您发送了这张图片:");
await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendImageAsync(appId, OpenId, requestMessage.MediaId);
return await DefaultResponseMessageAsync(requestMessage);
}
public override async Task OnEvent_UserEnterTempSessionRequestAsync(RequestMessageEvent_UserEnterTempSession requestMessage)
{
//进入客服
var msg = @"欢迎您!这条消息来自 Senparc.Weixin 进入客服事件。
您可以进行以下测试:
1、发送任意文字,返回上下文消息记录
2、发送图片,返回同样的图片
3、发送文字“link”,返回图文链接
4、发送文字“card”,发送小程序卡片
5、点击右下角出现的小程序浮窗,发送小程序页面信息";
await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, msg);
return await DefaultResponseMessageAsync(requestMessage);
}
public override async Task OnMiniProgramPageRequestAsync(RequestMessageMiniProgramPage requestMessage)
{
var msg = $"您从某个小程序页面来到客服,并且发送了小程序卡片。\r\nTitle:{requestMessage.Title}\r\nAppId:{requestMessage.AppId.Substring(1, 5)}...\r\nPagePath:{requestMessage.PagePath}\r\n附带照片:";
await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, msg);
await Senparc.Weixin.WxOpen.AdvancedAPIs.CustomApi.SendImageAsync(appId, OpenId, requestMessage.ThumbMediaId);
return await DefaultResponseMessageAsync(requestMessage);
}
public override async Task OnEvent_MediaCheckRequestAsync(RequestMessageEvent_MediaCheck requestMessage)
{
SenparcTrace.SendCustomLog("收到 OnEvent_MediaCheckRequestAsync 回调请求", requestMessage.ToJson());
return new SuccessResponseMessage();
}
public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
{
//所有没有被处理的消息会默认返回这里的结果
return new SuccessResponseMessage();
//return new SuccessResponseMessage();等效于:
//base.TextResponseMessage = "success";
//return null;
}
public override async Task DefaultResponseMessageAsync(IRequestMessageBase requestMessage)
{
return await Task.FromResult(new SuccessResponseMessage());
}
}
}