committed by
GitHub
102 changed files with 2366 additions and 333 deletions
@ -0,0 +1,43 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Chat.Request; |
|||
using LINGYUN.Abp.WeChat.Work.Chat.Response; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Chat; |
|||
/// <summary>
|
|||
/// 群聊操作接口
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 参考:https://developer.work.weixin.qq.com/document/path/90244
|
|||
/// </remarks>
|
|||
public interface IWeChatWorkAppChatManager |
|||
{ |
|||
/// <summary>
|
|||
/// 创建群聊会话
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 参考:https://developer.work.weixin.qq.com/document/path/90245
|
|||
/// </remarks>
|
|||
Task<WeChatWorkAppChatCreateResponse> CreateAsync( |
|||
WeChatWorkAppChatCreateRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 修改群聊会话
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 参考:https://developer.work.weixin.qq.com/document/path/98913
|
|||
/// </remarks>
|
|||
Task<WeChatWorkResponse> UpdateAsync( |
|||
WeChatWorkAppChatUpdateRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 获取群聊会话
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 参考:https://developer.work.weixin.qq.com/document/path/98914
|
|||
/// </remarks>
|
|||
Task<WeChatWorkAppChatInfoResponse> GetAsync( |
|||
string agentId, |
|||
string chatId, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Chat.Models; |
|||
public class WeChatWorkAppChatInfo |
|||
{ |
|||
/// <summary>
|
|||
/// 群聊名
|
|||
/// </summary>
|
|||
[JsonProperty("name")] |
|||
[JsonPropertyName("name")] |
|||
public virtual string Name { get; set; } |
|||
/// <summary>
|
|||
/// 群主id
|
|||
/// </summary>
|
|||
[JsonProperty("owner")] |
|||
[JsonPropertyName("owner")] |
|||
public virtual string Owner { get; set; } |
|||
/// <summary>
|
|||
/// 群成员id列表
|
|||
/// </summary>
|
|||
[JsonProperty("userlist")] |
|||
[JsonPropertyName("userlist")] |
|||
public virtual List<string> Users { get; set; } |
|||
/// <summary>
|
|||
/// 群聊唯一标志
|
|||
/// </summary>
|
|||
[JsonProperty("chatid")] |
|||
[JsonPropertyName("chatid")] |
|||
public virtual string ChatId { get; set; } |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Chat.Request; |
|||
public class WeChatWorkAppChatCreateRequest : WeChatWorkAppChatRequest |
|||
{ |
|||
public WeChatWorkAppChatCreateRequest( |
|||
string agentId, |
|||
string name, |
|||
List<string> users, |
|||
string owner = null, |
|||
string chatId = null) |
|||
: base(agentId) |
|||
{ |
|||
Name = name; |
|||
Owner = owner; |
|||
Users = users; |
|||
ChatId = chatId; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 群聊名,最多50个utf8字符,超过将截断
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("name")] |
|||
[JsonPropertyName("name")] |
|||
public virtual string Name { get; set; } |
|||
/// <summary>
|
|||
/// 指定群主的id。
|
|||
/// 如果不指定,系统会随机从userlist中选一人作为群主
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("owner")] |
|||
[JsonPropertyName("owner")] |
|||
public virtual string Owner { get; set; } |
|||
/// <summary>
|
|||
/// 群成员id列表。
|
|||
/// 至少2人,至多2000人
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("userlist")] |
|||
[JsonPropertyName("userlist")] |
|||
public virtual List<string> Users { get; set; } |
|||
/// <summary>
|
|||
/// 群聊的唯一标志,不能与已有的群重复;
|
|||
/// 字符串类型,最长32个字符。
|
|||
/// 只允许字符0-9及字母a-zA-Z。
|
|||
/// 如果不填,系统会随机生成群id
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("chatid")] |
|||
[JsonPropertyName("chatid")] |
|||
public virtual string ChatId { get; set; } |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Chat.Request; |
|||
public abstract class WeChatWorkAppChatRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 应用标识
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[Newtonsoft.Json.JsonIgnore] |
|||
[System.Text.Json.Serialization.JsonIgnore] |
|||
public virtual string AgentId { get; set; } |
|||
protected WeChatWorkAppChatRequest(string agentId) |
|||
{ |
|||
AgentId = agentId; |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Chat.Request; |
|||
public class WeChatWorkAppChatUpdateRequest : WeChatWorkAppChatRequest |
|||
{ |
|||
public WeChatWorkAppChatUpdateRequest( |
|||
string agentId, |
|||
string chatId, |
|||
string name = null, |
|||
string owner = null, |
|||
List<string> addUsers = null, |
|||
List<string> delUsers = null) |
|||
: base(agentId) |
|||
{ |
|||
Name = name; |
|||
Owner = owner; |
|||
AddUsers = addUsers; |
|||
DelUsers = delUsers; |
|||
ChatId = chatId; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 新的群聊名。若不需更新,请忽略此参数。最多50个utf8字符,超过将截断
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("name")] |
|||
[JsonPropertyName("name")] |
|||
public virtual string Name { get; set; } |
|||
/// <summary>
|
|||
/// 新群主的id。
|
|||
/// 若不需更新,请忽略此参数。课程群聊群主必须在设置的群主列表内
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("owner")] |
|||
[JsonPropertyName("owner")] |
|||
public virtual string Owner { get; set; } |
|||
/// <summary>
|
|||
/// 添加成员的id列表
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("add_user_list")] |
|||
[JsonPropertyName("add_user_list")] |
|||
public virtual List<string> AddUsers { get; set; } |
|||
/// <summary>
|
|||
/// 踢出成员的id列表
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("del_user_list")] |
|||
[JsonPropertyName("del_user_list")] |
|||
public virtual List<string> DelUsers { get; set; } |
|||
/// <summary>
|
|||
/// 群聊id
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("chatid")] |
|||
[JsonPropertyName("chatid")] |
|||
public virtual string ChatId { get; set; } |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Chat.Response; |
|||
|
|||
public class WeChatWorkAppChatCreateResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 群聊的唯一标志
|
|||
/// </summary>
|
|||
[JsonProperty("chatid")] |
|||
[JsonPropertyName("chatid")] |
|||
public virtual string ChatId { get; set; } |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Chat.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Chat.Response; |
|||
public class WeChatWorkAppChatInfoResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 群聊信息
|
|||
/// </summary>
|
|||
[JsonProperty("chat_info")] |
|||
[JsonPropertyName("chat_info")] |
|||
public WeChatWorkAppChatInfo ChatInfo { get; set; } |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Chat.Request; |
|||
using LINGYUN.Abp.WeChat.Work.Chat.Response; |
|||
using LINGYUN.Abp.WeChat.Work.Features; |
|||
using LINGYUN.Abp.WeChat.Work.Token; |
|||
using System.Net.Http; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Chat; |
|||
|
|||
[RequiresFeature(WeChatWorkFeatureNames.Enable)] |
|||
public class WeChatWorkAppChatManager : IWeChatWorkAppChatManager, ISingletonDependency |
|||
{ |
|||
protected IHttpClientFactory HttpClientFactory { get; } |
|||
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
|||
|
|||
public WeChatWorkAppChatManager( |
|||
IHttpClientFactory httpClientFactory, |
|||
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
|||
{ |
|||
HttpClientFactory = httpClientFactory; |
|||
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkAppChatCreateResponse> CreateAsync( |
|||
WeChatWorkAppChatCreateRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(request.AgentId, cancellationToken); |
|||
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
|||
|
|||
using var response = await client.CreateAppChatAsync(token.AccessToken, request, cancellationToken); |
|||
return await response.DeserializeObjectAsync<WeChatWorkAppChatCreateResponse>(); |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkAppChatInfoResponse> GetAsync( |
|||
string agentId, |
|||
string chatId, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(agentId, cancellationToken); |
|||
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
|||
|
|||
using var response = await client.GetAppChatAsync(token.AccessToken, agentId, cancellationToken); |
|||
return await response.DeserializeObjectAsync<WeChatWorkAppChatInfoResponse>(); |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkResponse> UpdateAsync( |
|||
WeChatWorkAppChatUpdateRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(request.AgentId, cancellationToken); |
|||
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
|||
|
|||
using var response = await client.UpdateAppChatAsync(token.AccessToken, request, cancellationToken); |
|||
return await response.DeserializeObjectAsync<WeChatWorkAppChatCreateResponse>(); |
|||
} |
|||
} |
|||
@ -1,6 +1,6 @@ |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Media; |
|||
namespace LINGYUN.Abp.WeChat.Work.Media.Models; |
|||
public class WeChatWorkImageResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
@ -1,6 +1,6 @@ |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Media; |
|||
namespace LINGYUN.Abp.WeChat.Work.Media.Models; |
|||
public class WeChatWorkMediaRequest |
|||
{ |
|||
public string AccessToken { get; set; } |
|||
@ -1,6 +1,6 @@ |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Media; |
|||
namespace LINGYUN.Abp.WeChat.Work.Media.Models; |
|||
public class WeChatWorkMediaResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
@ -0,0 +1,22 @@ |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
/// <summary>
|
|||
/// 企业微信消息管理器
|
|||
/// </summary>
|
|||
public interface IWeChatWorkMessageManager |
|||
{ |
|||
/// <summary>
|
|||
/// 撤回应用消息
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 参考:https://developer.work.weixin.qq.com/document/path/94867
|
|||
/// </remarks>
|
|||
/// <param name="agentId">应用标识</param>
|
|||
/// <param name="messageId">消息ID。从应用发送消息接口 <see cref="IWeChatWorkMessageSender"/> 处获得。</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<bool> ReCallMessageAsync(string agentId, string messageId, CancellationToken cancellationToken = default); |
|||
|
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 小程序通知消息
|
|||
/// </summary>
|
|||
public class MiniProgramMessage |
|||
{ |
|||
/// <summary>
|
|||
/// 小程序appid,必须是与当前应用关联的小程序
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("appid")] |
|||
[JsonPropertyName("appid")] |
|||
public string AppId { get; set; } |
|||
/// <summary>
|
|||
/// 消息标题,长度限制4-12个汉字(支持id转译)
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("title")] |
|||
[JsonPropertyName("title")] |
|||
public string Title { get; set; } |
|||
/// <summary>
|
|||
/// 点击消息卡片后的小程序页面,最长1024个字节,仅限本小程序内的页面。该字段不填则消息点击后不跳转。
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("page")] |
|||
[JsonPropertyName("page")] |
|||
public string Page { get; set; } |
|||
/// <summary>
|
|||
/// 消息描述,长度限制4-12个汉字(支持id转译)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("description")] |
|||
[JsonPropertyName("description")] |
|||
public string Description { get; set; } |
|||
/// <summary>
|
|||
/// 是否放大第一个content_item
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("emphasis_first_item")] |
|||
[JsonPropertyName("emphasis_first_item")] |
|||
public bool? EmphasisFirstItem { get; set; } |
|||
/// <summary>
|
|||
/// 消息内容键值对,最多允许10个item
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("content_item")] |
|||
[JsonPropertyName("content_item")] |
|||
public List<MiniProgramContent> ContentItems{ get; set; } |
|||
public MiniProgramMessage() |
|||
{ |
|||
ContentItems = new List<MiniProgramContent>(); |
|||
} |
|||
|
|||
public MiniProgramMessage( |
|||
string appId, |
|||
string title, |
|||
string page = null, |
|||
string description = null, |
|||
bool? emphasisFirstItem = null) |
|||
{ |
|||
AppId = appId; |
|||
Page = page; |
|||
Title = title; |
|||
Description = description; |
|||
EmphasisFirstItem = emphasisFirstItem; |
|||
} |
|||
} |
|||
|
|||
public class MiniProgramContent |
|||
{ |
|||
/// <summary>
|
|||
/// 长度10个汉字以内
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("key")] |
|||
[JsonPropertyName("key")] |
|||
public string Key { get; set; } |
|||
/// <summary>
|
|||
/// 长度30个汉字以内(支持id转译)
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("value")] |
|||
[JsonPropertyName("value")] |
|||
public string Value { get; set; } |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信群聊文件消息
|
|||
/// </summary>
|
|||
public class WeChatWorkAppChatFileMessage : WeChatWorkAppChatMessage |
|||
{ |
|||
public WeChatWorkAppChatFileMessage( |
|||
string agentId, |
|||
string chatId, |
|||
MediaMessage file) : base(agentId, chatId, "file") |
|||
{ |
|||
File = file; |
|||
} |
|||
/// <summary>
|
|||
/// 媒体文件
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("file")] |
|||
[JsonPropertyName("file")] |
|||
public MediaMessage File { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否是保密消息,
|
|||
/// 0表示可对外分享,
|
|||
/// 1表示不能分享且内容显示水印,
|
|||
/// 默认为0
|
|||
/// </summary>
|
|||
[JsonProperty("safe")] |
|||
[JsonPropertyName("safe")] |
|||
public byte Safe { get; set; } |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信群聊图片消息
|
|||
/// </summary>
|
|||
public class WeChatWorkAppChatImageMessage : WeChatWorkAppChatMessage |
|||
{ |
|||
public WeChatWorkAppChatImageMessage( |
|||
string agentId, |
|||
string chatId, |
|||
MediaMessage image) : base(agentId, chatId, "image") |
|||
{ |
|||
Image = image; |
|||
} |
|||
/// <summary>
|
|||
/// 图片媒体文件
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("image")] |
|||
[JsonPropertyName("image")] |
|||
public MediaMessage Image { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否是保密消息,
|
|||
/// 0表示可对外分享,
|
|||
/// 1表示不能分享且内容显示水印,
|
|||
/// 默认为0
|
|||
/// </summary>
|
|||
[JsonProperty("safe")] |
|||
[JsonPropertyName("safe")] |
|||
public int Safe { get; set; } |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信群聊markdown消息
|
|||
/// </summary>
|
|||
public class WeChatWorkAppChatMarkdownMessage : WeChatWorkAppChatMessage |
|||
{ |
|||
public WeChatWorkAppChatMarkdownMessage( |
|||
string agentId, |
|||
string chatId, |
|||
MarkdownMessage markdown) : base(agentId, chatId, "markdown") |
|||
{ |
|||
Markdown = markdown; |
|||
} |
|||
/// <summary>
|
|||
/// markdown消息
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("markdown")] |
|||
[JsonPropertyName("markdown")] |
|||
public MarkdownMessage Markdown { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否是保密消息,
|
|||
/// 0不保密
|
|||
/// 1保密
|
|||
/// 默认为0
|
|||
/// </summary>
|
|||
[JsonProperty("safe")] |
|||
[JsonPropertyName("safe")] |
|||
public byte Safe { get; set; } |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信群聊文本图文消息
|
|||
/// </summary>
|
|||
public class WeChatWorkAppChatMpNewMessage : WeChatWorkAppChatMessage |
|||
{ |
|||
public WeChatWorkAppChatMpNewMessage( |
|||
string agentId, |
|||
string chatId, |
|||
MpNewMessagePayload mpnews) : base(agentId, chatId, "mpnews") |
|||
{ |
|||
News = mpnews; |
|||
} |
|||
/// <summary>
|
|||
/// 图文消息(mp)
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("mpnews")] |
|||
[JsonPropertyName("mpnews")] |
|||
public MpNewMessagePayload News { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否是保密消息,
|
|||
/// 0不保密
|
|||
/// 1保密
|
|||
/// 默认为0
|
|||
/// </summary>
|
|||
[JsonProperty("safe")] |
|||
[JsonPropertyName("safe")] |
|||
public byte Safe { get; set; } |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信群聊文本图文消息
|
|||
/// </summary>
|
|||
public class WeChatWorkAppChatNewMessage : WeChatWorkAppChatMessage |
|||
{ |
|||
public WeChatWorkAppChatNewMessage( |
|||
string agentId, |
|||
string chatId, |
|||
NewMessagePayload news) : base(agentId, chatId, "news") |
|||
{ |
|||
News = news; |
|||
} |
|||
/// <summary>
|
|||
/// 图文消息
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("news")] |
|||
[JsonPropertyName("news")] |
|||
public NewMessagePayload News { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否是保密消息,
|
|||
/// 0不保密
|
|||
/// 1保密
|
|||
/// 默认为0
|
|||
/// </summary>
|
|||
[JsonProperty("safe")] |
|||
[JsonPropertyName("safe")] |
|||
public byte Safe { get; set; } |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信群聊文本卡片消息
|
|||
/// </summary>
|
|||
public class WeChatWorkAppChatTextCardMessage : WeChatWorkAppChatMessage |
|||
{ |
|||
public WeChatWorkAppChatTextCardMessage( |
|||
string agentId, |
|||
string chatId, |
|||
TextCardMessage textcard) : base(agentId, chatId, "textcard") |
|||
{ |
|||
TextCard = textcard; |
|||
} |
|||
/// <summary>
|
|||
/// 卡片消息
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("textcard")] |
|||
[JsonPropertyName("textcard")] |
|||
public TextCardMessage TextCard { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否是保密消息,
|
|||
/// 0表示可对外分享,
|
|||
/// 1表示不能分享且内容显示水印,
|
|||
/// 默认为0
|
|||
/// </summary>
|
|||
[JsonProperty("safe")] |
|||
[JsonPropertyName("safe")] |
|||
public byte Safe { get; set; } |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信群聊文本消息
|
|||
/// </summary>
|
|||
public class WeChatWorkAppChatTextMessage : WeChatWorkAppChatMessage |
|||
{ |
|||
public WeChatWorkAppChatTextMessage( |
|||
string agentId, |
|||
string chatId, |
|||
TextMessage text) : base(agentId, chatId, "text") |
|||
{ |
|||
Text = text; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 消息内容,最长不超过2048个字节,超过将截断(支持id转译)
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("text")] |
|||
[JsonPropertyName("text")] |
|||
public TextMessage Text { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否是保密消息,
|
|||
/// 0表示可对外分享,
|
|||
/// 1表示不能分享且内容显示水印,
|
|||
/// 默认为0
|
|||
/// </summary>
|
|||
[JsonProperty("safe")] |
|||
[JsonPropertyName("safe")] |
|||
public int Safe { get; set; } |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信群聊语言消息
|
|||
/// </summary>
|
|||
public class WeChatWorkAppChatVideoMessage : WeChatWorkAppChatMessage |
|||
{ |
|||
public WeChatWorkAppChatVideoMessage( |
|||
string agentId, |
|||
string chatId, |
|||
VideoMessage video) : base(agentId, chatId, "video") |
|||
{ |
|||
Video = video; |
|||
} |
|||
/// <summary>
|
|||
/// 视频媒体文件
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("video")] |
|||
[JsonPropertyName("video")] |
|||
public VideoMessage Video { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否是保密消息,
|
|||
/// 0表示可对外分享,
|
|||
/// 1表示不能分享且内容显示水印,
|
|||
/// 默认为0
|
|||
/// </summary>
|
|||
[JsonProperty("safe")] |
|||
[JsonPropertyName("safe")] |
|||
public byte Safe { get; set; } |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信群聊语言消息
|
|||
/// </summary>
|
|||
public class WeChatWorkAppChatVoiceMessage : WeChatWorkAppChatMessage |
|||
{ |
|||
public WeChatWorkAppChatVoiceMessage( |
|||
string agentId, |
|||
string chatId, |
|||
MediaMessage voice) : base(agentId, chatId, "voice") |
|||
{ |
|||
Voice = voice; |
|||
} |
|||
/// <summary>
|
|||
/// 语音媒体文件
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("voice")] |
|||
[JsonPropertyName("voice")] |
|||
public MediaMessage Voice { get; set; } |
|||
} |
|||
@ -1,9 +1,8 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信文件消息
|
|||
/// </summary>
|
|||
@ -1,9 +1,8 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信图片消息
|
|||
/// </summary>
|
|||
@ -1,9 +1,8 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信markdown消息
|
|||
/// </summary>
|
|||
@ -0,0 +1,84 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信小程序通知消息
|
|||
/// </summary>
|
|||
public class WeChatWorkMiniProgramMessage |
|||
{ |
|||
/// <summary>
|
|||
/// 指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个)。
|
|||
/// 特殊情况:指定为"@all",则向该企业应用的全部成员发送
|
|||
/// </summary>
|
|||
[JsonProperty("touser")] |
|||
[JsonPropertyName("touser")] |
|||
public virtual string ToUser { get; set; } |
|||
/// <summary>
|
|||
/// 指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。
|
|||
/// 当touser为"@all"时忽略本参数
|
|||
/// </summary>
|
|||
[JsonProperty("toparty")] |
|||
[JsonPropertyName("toparty")] |
|||
public virtual string ToParty { get; set; } |
|||
/// <summary>
|
|||
/// 指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。
|
|||
/// 当touser为"@all"时忽略本参数
|
|||
/// </summary>
|
|||
[JsonProperty("totag")] |
|||
[JsonPropertyName("totag")] |
|||
public virtual string ToTag { get; set; } |
|||
/// <summary>
|
|||
/// 消息类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("msgtype")] |
|||
[JsonPropertyName("msgtype")] |
|||
public virtual string MsgType { get; } |
|||
/// <summary>
|
|||
/// 表示是否开启id转译,0表示否,1表示是,默认0。
|
|||
/// 仅第三方应用需要用到
|
|||
/// 企业自建应用可以忽略。
|
|||
/// </summary>
|
|||
[JsonProperty("enable_id_trans")] |
|||
[JsonPropertyName("enable_id_trans")] |
|||
public byte EnableIdTrans { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否开启重复消息检查,0表示否,1表示是,默认0
|
|||
/// </summary>
|
|||
[JsonProperty("enable_duplicate_check")] |
|||
[JsonPropertyName("enable_duplicate_check")] |
|||
public byte EnableDuplicateCheck { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
|
|||
/// </summary>
|
|||
[JsonProperty("duplicate_check_interval")] |
|||
[JsonPropertyName("duplicate_check_interval")] |
|||
public int DuplicateCheckInterval { get; set; } = 1800; |
|||
/// <summary>
|
|||
/// 消息内容
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("miniprogram_notice")] |
|||
[JsonPropertyName("miniprogram_notice")] |
|||
public MiniProgramMessage MiniProgram { get; set; } |
|||
public WeChatWorkMiniProgramMessage( |
|||
MiniProgramMessage miniProgram, |
|||
string toUser = "", |
|||
string toParty = "", |
|||
string toTag = "", |
|||
byte enableIdTrans = 0, |
|||
byte enableDuplicateCheck = 0, |
|||
int duplicateCheckInterval = 1800) |
|||
{ |
|||
ToUser = toUser; |
|||
ToParty = toParty; |
|||
ToTag = toTag; |
|||
EnableIdTrans = enableIdTrans; |
|||
EnableDuplicateCheck = enableDuplicateCheck; |
|||
DuplicateCheckInterval = duplicateCheckInterval; |
|||
MiniProgram = miniProgram; |
|||
MsgType = "miniprogram_notice"; |
|||
} |
|||
} |
|||
@ -1,9 +1,8 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信文本图文消息
|
|||
/// </summary>
|
|||
@ -1,9 +1,8 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信文本图文消息
|
|||
/// </summary>
|
|||
@ -1,9 +1,8 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信文本卡片消息
|
|||
/// </summary>
|
|||
@ -1,9 +1,8 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信文本消息
|
|||
/// </summary>
|
|||
@ -1,9 +1,8 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信语言消息
|
|||
/// </summary>
|
|||
@ -1,9 +1,8 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Models; |
|||
/// <summary>
|
|||
/// 企业微信语言消息
|
|||
/// </summary>
|
|||
@ -0,0 +1,27 @@ |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Request; |
|||
/// <summary>
|
|||
/// 撤回消息请求载体
|
|||
/// </summary>
|
|||
public class WeChatWorkMessageReCallRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 调用接口凭证
|
|||
/// </summary>
|
|||
[System.Text.Json.Serialization.JsonIgnore] |
|||
[Newtonsoft.Json.JsonIgnore] |
|||
public string AccessToken { get; set; } |
|||
/// <summary>
|
|||
/// 消息ID
|
|||
/// </summary>
|
|||
[JsonProperty("msgid")] |
|||
[JsonPropertyName("msgid")] |
|||
public string MessageId { get; set; } |
|||
public WeChatWorkMessageReCallRequest(string accessToken, string messageId) |
|||
{ |
|||
AccessToken = accessToken; |
|||
MessageId = messageId; |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Request; |
|||
public class WeChatWorkMessageRequest<TMessage> |
|||
{ |
|||
public string AccessToken { get; set; } |
|||
public TMessage Message { get; set; } |
|||
public WeChatWorkMessageRequest(string accessToken, TMessage message) |
|||
{ |
|||
AccessToken = accessToken; |
|||
Message = message; |
|||
} |
|||
} |
|||
@ -1,7 +1,7 @@ |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Response; |
|||
/// <summary>
|
|||
/// 企业微信发送消息响应
|
|||
/// </summary>
|
|||
@ -0,0 +1,28 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
|
|||
public abstract class TemplateCard |
|||
{ |
|||
/// <summary>
|
|||
/// 模板卡片类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("card_type")] |
|||
[JsonPropertyName("card_type")] |
|||
public string Type { get; } |
|||
/// <summary>
|
|||
/// 任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("task_id")] |
|||
[JsonPropertyName("task_id")] |
|||
public string TaskId { get; set; } |
|||
protected TemplateCard(string type, string taskId = "") |
|||
{ |
|||
Type = type; |
|||
TaskId = taskId; |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 卡片操作按钮
|
|||
/// </summary>
|
|||
public class TemplateCardAction |
|||
{ |
|||
public TemplateCardAction(string key, string text) |
|||
{ |
|||
Key = key; |
|||
Text = text; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 操作key值,用户点击后,会产生回调事件将本参数作为EventKey返回,回调事件会带上该key值,最长支持1024字节,不可重复
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("key")] |
|||
[JsonPropertyName("key")] |
|||
public string Key { get; set; } |
|||
/// <summary>
|
|||
/// 操作的描述文案
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("text")] |
|||
[JsonPropertyName("text")] |
|||
public string Text { get; set; } |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 卡片右上角更多操作按钮
|
|||
/// </summary>
|
|||
public class TemplateCardActionMenu |
|||
{ |
|||
/// <summary>
|
|||
/// 卡片副交互辅助文本说明
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("desc")] |
|||
[JsonPropertyName("desc")] |
|||
public string Description { get; set; } |
|||
/// <summary>
|
|||
/// 操作列表,列表长度取值范围为 [1, 3]
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("action_list")] |
|||
[JsonPropertyName("action_list")] |
|||
public List<TemplateCardAction> Actions { get; set;} |
|||
public TemplateCardActionMenu(List<TemplateCardAction> actions, string description = "") |
|||
{ |
|||
Actions = actions; |
|||
Description = description; |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 整体卡片的点击跳转事件
|
|||
/// </summary>
|
|||
public class TemplateCardCardAction |
|||
{ |
|||
public TemplateCardCardAction(string url) |
|||
{ |
|||
Type = 1; |
|||
Url = url; |
|||
} |
|||
public TemplateCardCardAction(string appid, string pagePath) |
|||
{ |
|||
Type = 2; |
|||
AppId = appid; |
|||
PagePath = pagePath; |
|||
} |
|||
/// <summary>
|
|||
/// 跳转链接类型,0或不填代表不是链接,1 代表跳转url,2 代表跳转小程序
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public byte Type { get; set; } |
|||
/// <summary>
|
|||
/// 跳转链接的url,card_action.type是1时必填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("url")] |
|||
[JsonPropertyName("url")] |
|||
public string Url { get; set; } |
|||
/// <summary>
|
|||
/// 跳转链接的小程序的appid,必须是与当前应用关联的小程序,card_action.type是2时必填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("appid")] |
|||
[JsonPropertyName("appid")] |
|||
public string AppId { get; set; } |
|||
/// <summary>
|
|||
/// 跳转链接的小程序的pagepath,card_action.type是2时选填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("pagepath")] |
|||
[JsonPropertyName("pagepath")] |
|||
public string PagePath { get; set; } |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 关键数据样式
|
|||
/// </summary>
|
|||
public class TemplateCardEmphasisContent |
|||
{ |
|||
public TemplateCardEmphasisContent( |
|||
string title = "", |
|||
string description = "") |
|||
{ |
|||
Title = title; |
|||
Description = description; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 关键数据样式的数据内容,建议不超过14个字
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("title")] |
|||
[JsonPropertyName("title")] |
|||
public string Title { get; set; } |
|||
/// <summary>
|
|||
/// 关键数据样式的数据描述内容,建议不超过22个字
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("desc")] |
|||
[JsonPropertyName("desc")] |
|||
public string Description { get; set; } |
|||
} |
|||
@ -0,0 +1,93 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 二级标题+文本
|
|||
/// </summary>
|
|||
public class TemplateCardHorizontalContent |
|||
{ |
|||
public static TemplateCardHorizontalContent None(string keyName, string value = "") |
|||
{ |
|||
return new TemplateCardHorizontalContent( |
|||
keyName, 0, value); |
|||
} |
|||
|
|||
public static TemplateCardHorizontalContent FromUrl(string keyName, string url, string value = "") |
|||
{ |
|||
return new TemplateCardHorizontalContent( |
|||
keyName, 1, value, url); |
|||
} |
|||
|
|||
public static TemplateCardHorizontalContent FromMedia(string keyName, string mediaId, string value = "") |
|||
{ |
|||
return new TemplateCardHorizontalContent( |
|||
keyName, 2, value, mediaId: mediaId); |
|||
} |
|||
|
|||
public static TemplateCardHorizontalContent FromUser(string keyName, string userId, string value = "") |
|||
{ |
|||
return new TemplateCardHorizontalContent( |
|||
keyName, 3, value, userId: userId); |
|||
} |
|||
|
|||
public TemplateCardHorizontalContent( |
|||
string keyName, |
|||
byte type = 0, |
|||
string value = "", |
|||
string url = "", |
|||
string mediaId = "", |
|||
string userId = "") |
|||
{ |
|||
Type = type; |
|||
KeyName = keyName; |
|||
Value = value; |
|||
Url = url; |
|||
MediaId = mediaId; |
|||
UserId = userId; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 链接类型,0或不填代表不是链接,1 代表跳转url,2 代表下载附件,3 代表点击跳转成员详情
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public byte Type { get; } |
|||
/// <summary>
|
|||
/// 二级标题,建议不超过5个字
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("keyname")] |
|||
[JsonPropertyName("keyname")] |
|||
public string KeyName { get; set; } |
|||
/// <summary>
|
|||
/// 二级文本,如果horizontal_content_list.type是2,该字段代表文件名称(要包含文件类型),建议不超过30个字,(支持id转译)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("value")] |
|||
[JsonPropertyName("value")] |
|||
public string Value { get; set; } |
|||
/// <summary>
|
|||
/// 链接跳转的url,horizontal_content_list.type是1时必填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("url")] |
|||
[JsonPropertyName("url")] |
|||
public string Url { get; set; } |
|||
/// <summary>
|
|||
/// 附件的media_id,horizontal_content_list.type是2时必填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("media_id")] |
|||
[JsonPropertyName("media_id")] |
|||
public string MediaId { get; set; } |
|||
/// <summary>
|
|||
/// 成员详情的userid,horizontal_content_list.type是3时必填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("userid")] |
|||
[JsonPropertyName("userid")] |
|||
public string UserId { get; set; } |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 跳转指引样式
|
|||
/// </summary>
|
|||
public class TemplateCardJump |
|||
{ |
|||
public TemplateCardJump(string title, string url) |
|||
{ |
|||
Type = 1; |
|||
Url = url; |
|||
Title = title; |
|||
} |
|||
public TemplateCardJump(string title, string appid, string pagePath) |
|||
{ |
|||
Type = 2; |
|||
AppId = appid; |
|||
PagePath = pagePath; |
|||
Title = title; |
|||
} |
|||
/// <summary>
|
|||
/// 跳转链接类型,0或不填代表不是链接,1 代表跳转url,2 代表跳转小程序
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public byte Type { get; } |
|||
/// <summary>
|
|||
/// 跳转链接样式的文案内容,建议不超过18个字
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("title")] |
|||
[JsonPropertyName("title")] |
|||
public string Title { get; set; } |
|||
/// <summary>
|
|||
/// 跳转链接的url,jump_list.type是1时必填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("url")] |
|||
[JsonPropertyName("url")] |
|||
public string Url { get; set; } |
|||
/// <summary>
|
|||
/// 跳转链接的小程序的appid,必须是与当前应用关联的小程序,jump_list.type是2时必填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("appid")] |
|||
[JsonPropertyName("appid")] |
|||
public string AppId { get; set; } |
|||
/// <summary>
|
|||
/// 跳转链接的小程序的pagepath,jump_list.type是2时选填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("pagepath")] |
|||
[JsonPropertyName("pagepath")] |
|||
public string PagePath { get; set; } |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 卡票标题
|
|||
/// </summary>
|
|||
public class TemplateCardMainTitle |
|||
{ |
|||
public TemplateCardMainTitle( |
|||
string title = "", |
|||
string description = "") |
|||
{ |
|||
Title = title; |
|||
Description = description; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 一级标题,建议不超过36个字,文本通知型卡片本字段非必填,但不可本字段和sub_title_text都不填,(支持id转译)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("title")] |
|||
[JsonPropertyName("title")] |
|||
public string Title { get; set; } |
|||
/// <summary>
|
|||
/// 标题辅助信息,建议不超过44个字,(支持id转译)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("desc")] |
|||
[JsonPropertyName("desc")] |
|||
public string Description { get; set; } |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 引用文献样式
|
|||
/// </summary>
|
|||
public class TemplateCardQuoteArea |
|||
{ |
|||
public TemplateCardQuoteArea(string url, string title = "", string text = "") |
|||
{ |
|||
Type = 1; |
|||
Url = url; |
|||
Title = title; |
|||
Text = text; |
|||
} |
|||
public TemplateCardQuoteArea(string appid, string pagePath, string title = "", string text = "") |
|||
{ |
|||
Type = 2; |
|||
AppId = appid; |
|||
PagePath = pagePath; |
|||
Title = title; |
|||
Text = text; |
|||
} |
|||
/// <summary>
|
|||
/// 引用文献样式区域点击事件,0或不填代表没有点击事件,1 代表跳转url,2 代表跳转小程序
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public byte Type { get; } |
|||
/// <summary>
|
|||
/// 点击跳转的url,quote_area.type是1时必填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("url")] |
|||
[JsonPropertyName("url")] |
|||
public string Url { get; set; } |
|||
/// <summary>
|
|||
/// 点击跳转的小程序的appid,必须是与当前应用关联的小程序,quote_area.type是2时必填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("appid")] |
|||
[JsonPropertyName("appid")] |
|||
public string AppId { get; set; } |
|||
/// <summary>
|
|||
/// 点击跳转的小程序的pagepath,quote_area.type是2时选填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("pagepath")] |
|||
[JsonPropertyName("pagepath")] |
|||
public string PagePath { get; set; } |
|||
/// <summary>
|
|||
/// 引用文献样式的标题
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("title")] |
|||
[JsonPropertyName("title")] |
|||
public string Title { get; set; } |
|||
/// <summary>
|
|||
/// 引用文献样式的引用文案
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("quote_text")] |
|||
[JsonPropertyName("quote_text")] |
|||
public string Text { get; set; } |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 来源文字颜色
|
|||
/// </summary>
|
|||
public enum DescriptionColor |
|||
{ |
|||
Gray = 0, |
|||
Black = 1, |
|||
Red = 2, |
|||
Green = 3, |
|||
} |
|||
/// <summary>
|
|||
/// 卡片来源样式信息
|
|||
/// </summary>
|
|||
public class TemplateCardSource |
|||
{ |
|||
public TemplateCardSource( |
|||
string iconUrl = "", |
|||
string description = "", |
|||
DescriptionColor descriptionColor = DescriptionColor.Gray) |
|||
{ |
|||
IconUrl = iconUrl; |
|||
Description = description; |
|||
DescriptionColor = descriptionColor; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 来源图片的url,来源图片的尺寸建议为72*72
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("icon_url")] |
|||
[JsonPropertyName("icon_url")] |
|||
public string IconUrl { get; set; } |
|||
/// <summary>
|
|||
/// 来源图片的描述,建议不超过20个字,(支持id转译)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("desc")] |
|||
[JsonPropertyName("desc")] |
|||
public string Description { get; set; } |
|||
/// <summary>
|
|||
/// 来源文字的颜色,目前支持:0(默认) 灰色,1 黑色,2 红色,3 绿色
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("desc_color")] |
|||
[JsonPropertyName("desc_color")] |
|||
public DescriptionColor DescriptionColor { get; set; } |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 文本模板卡片消息
|
|||
/// </summary>
|
|||
public class TextTemplateCard : TemplateCard |
|||
{ |
|||
public TextTemplateCard(TemplateCardCardAction cardAction, string taskId = "") |
|||
: base("template_card", taskId) |
|||
{ |
|||
CardAction = cardAction; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 卡片来源样式信息,不需要来源样式可不填写
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("source")] |
|||
[JsonPropertyName("source")] |
|||
public TemplateCardSource Source { get; set; } |
|||
/// <summary>
|
|||
/// 卡片右上角更多操作按钮
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("action_menu")] |
|||
[JsonPropertyName("action_menu")] |
|||
public TemplateCardActionMenu ActionMenu { get; set; } |
|||
/// <summary>
|
|||
/// 一级标题
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("main_title")] |
|||
[JsonPropertyName("main_title")] |
|||
public TemplateCardMainTitle MainTitle { get; set; } |
|||
/// <summary>
|
|||
/// 二级普通文本,建议不超过160个字,(支持id转译)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("sub_title_text")] |
|||
[JsonPropertyName("sub_title_text")] |
|||
public string SubTitle { get; set; } |
|||
/// <summary>
|
|||
/// 引用文献样式
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("quote_area")] |
|||
[JsonPropertyName("quote_area")] |
|||
public TemplateCardQuoteArea QuoteArea { get; set; } |
|||
/// <summary>
|
|||
/// 关键数据样式
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("emphasis_content")] |
|||
[JsonPropertyName("emphasis_content")] |
|||
public TemplateCardEmphasisContent EmphasisContent { get; set; } |
|||
/// <summary>
|
|||
/// 二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("horizontal_content_list")] |
|||
[JsonPropertyName("horizontal_content_list")] |
|||
public List<TemplateCardHorizontalContent> HorizontalContents { get; set; } |
|||
/// <summary>
|
|||
/// 跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("jump_list")] |
|||
[JsonPropertyName("jump_list")] |
|||
public List<TemplateCardJump> Jumps { get; set; } |
|||
/// <summary>
|
|||
/// 整体卡片的点击跳转事件,text_notice必填本字段
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("TemplateCardCardAction")] |
|||
[JsonPropertyName("TemplateCardCardAction")] |
|||
public TemplateCardCardAction CardAction { get; set; } |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message.Templates; |
|||
/// <summary>
|
|||
/// 企业微信模板卡片消息
|
|||
/// </summary>
|
|||
public class WeChatWorkTemplateCardMessage : WeChatWorkMessage |
|||
{ |
|||
public WeChatWorkTemplateCardMessage( |
|||
string agentId, |
|||
TemplateCard template, |
|||
string toUser = "", |
|||
string toParty = "", |
|||
string toTag = "") : base(agentId, "template_card", toUser, toParty, toTag) |
|||
{ |
|||
Template = template; |
|||
} |
|||
/// <summary>
|
|||
/// 模板卡片消息
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("template_card")] |
|||
[JsonPropertyName("template_card")] |
|||
public TemplateCard Template { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否开启id转译,0表示否,1表示是,默认0。
|
|||
/// 仅第三方应用需要用到
|
|||
/// 企业自建应用可以忽略。
|
|||
/// </summary>
|
|||
[JsonProperty("enable_id_trans")] |
|||
[JsonPropertyName("enable_id_trans")] |
|||
public byte EnableIdTrans { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否开启重复消息检查,0表示否,1表示是,默认0
|
|||
/// </summary>
|
|||
[JsonProperty("enable_duplicate_check")] |
|||
[JsonPropertyName("enable_duplicate_check")] |
|||
public byte EnableDuplicateCheck { get; set; } |
|||
/// <summary>
|
|||
/// 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
|
|||
/// </summary>
|
|||
[JsonProperty("duplicate_check_interval")] |
|||
[JsonPropertyName("duplicate_check_interval")] |
|||
public int DuplicateCheckInterval { get; set; } = 1800; |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
/// <summary>
|
|||
/// 企业微信群聊消息
|
|||
/// </summary>
|
|||
public abstract class WeChatWorkAppChatMessage : WeChatWorkRequest |
|||
{ |
|||
protected WeChatWorkAppChatMessage( |
|||
string agentId, |
|||
string chatId, |
|||
string msgType) |
|||
{ |
|||
AgentId = agentId; |
|||
ChatId = chatId; |
|||
MsgType = msgType; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 群聊id
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("chatid")] |
|||
[JsonPropertyName("chatid")] |
|||
public virtual string ChatId { get; protected set; } |
|||
/// <summary>
|
|||
/// 消息类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("msgtype")] |
|||
[JsonPropertyName("msgtype")] |
|||
public virtual string MsgType { get; protected set; } |
|||
/// <summary>
|
|||
/// 企业应用的id
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 由于需要换取token, 因此需要传递应用标识
|
|||
/// </remarks>
|
|||
[NotNull] |
|||
[Newtonsoft.Json.JsonIgnore] |
|||
[System.Text.Json.Serialization.JsonIgnore] |
|||
public virtual string AgentId { get; protected set; } |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Message.Request; |
|||
using LINGYUN.Abp.WeChat.Work.Token; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using System.Net.Http; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
|
|||
public class WeChatWorkMessageManager : IWeChatWorkMessageManager, ISingletonDependency |
|||
{ |
|||
public ILogger<WeChatWorkMessageManager> Logger { get; set; } |
|||
|
|||
protected IHttpClientFactory HttpClientFactory { get; } |
|||
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
|||
|
|||
public WeChatWorkMessageManager( |
|||
IHttpClientFactory httpClientFactory, |
|||
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
|||
{ |
|||
HttpClientFactory = httpClientFactory; |
|||
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
|||
|
|||
Logger = NullLogger<WeChatWorkMessageManager>.Instance; |
|||
} |
|||
|
|||
public async virtual Task<bool> ReCallMessageAsync(string agentId, string messageId, CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(agentId, cancellationToken); |
|||
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
|||
|
|||
var request = new WeChatWorkMessageReCallRequest( |
|||
token.AccessToken, |
|||
messageId); |
|||
|
|||
using var response = await client.ReCallMessageAsync(request, cancellationToken); |
|||
var messageResponse = await response.DeserializeObjectAsync<WeChatWorkResponse>(); |
|||
|
|||
return messageResponse.IsSuccessed; |
|||
} |
|||
} |
|||
@ -1,11 +0,0 @@ |
|||
namespace LINGYUN.Abp.WeChat.Work.Message; |
|||
public class WeChatWorkMessageRequest |
|||
{ |
|||
public string AccessToken { get; set; } |
|||
public WeChatWorkMessage Message { get; set; } |
|||
public WeChatWorkMessageRequest(string accessToken, WeChatWorkMessage message) |
|||
{ |
|||
AccessToken = accessToken; |
|||
Message = message; |
|||
} |
|||
} |
|||
@ -1,4 +1,4 @@ |
|||
namespace LINGYUN.Abp.WeChat.Work.Security; |
|||
namespace LINGYUN.Abp.WeChat.Work.Security.Models; |
|||
public class WeChatWorkCryptoDecryptData : WeChatWorkCryptoData |
|||
{ |
|||
public string PostData { get; } |
|||
@ -1,4 +1,4 @@ |
|||
namespace LINGYUN.Abp.WeChat.Work.Security; |
|||
namespace LINGYUN.Abp.WeChat.Work.Security.Models; |
|||
public class WeChatWorkCryptoEchoData : WeChatWorkCryptoData |
|||
{ |
|||
public string EchoStr { get; } |
|||
@ -1,11 +1,32 @@ |
|||
using System.Threading; |
|||
using LINGYUN.Abp.WeChat.Work.Token.Models; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Token |
|||
namespace LINGYUN.Abp.WeChat.Work.Token; |
|||
/// <summary>
|
|||
/// 企业微信AccessToken接口
|
|||
/// </summary>
|
|||
public interface IWeChatWorkTokenProvider |
|||
{ |
|||
public interface IWeChatWorkTokenProvider |
|||
{ |
|||
Task<WeChatWorkToken> GetTokenAsync(string agentId, CancellationToken cancellationToken = default); |
|||
Task<WeChatWorkToken> GetTokenAsync(string corpId, string agentId, CancellationToken cancellationToken = default); |
|||
} |
|||
/// <summary>
|
|||
/// 获取应用Token
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 参考:https://developer.work.weixin.qq.com/document/path/91039
|
|||
/// </remarks>
|
|||
/// <param name="agentId">应用标识</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkToken> GetTokenAsync(string agentId, CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 获取应用Token
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 参考:https://developer.work.weixin.qq.com/document/path/91039
|
|||
/// </remarks>
|
|||
/// <param name="corpId">企业标识</param>
|
|||
/// <param name="agentId">应用标识</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkToken> GetTokenAsync(string corpId, string agentId, CancellationToken cancellationToken = default); |
|||
} |
|||
|
|||
@ -1,4 +1,4 @@ |
|||
namespace LINGYUN.Abp.WeChat.Work.Token |
|||
namespace LINGYUN.Abp.WeChat.Work.Token.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 企业微信令牌
|
|||
@ -1,4 +1,4 @@ |
|||
namespace LINGYUN.Abp.WeChat.Work.Token |
|||
namespace LINGYUN.Abp.WeChat.Work.Token.Models |
|||
{ |
|||
public class WeChatWorkTokenCacheItem |
|||
{ |
|||
@ -1,4 +1,4 @@ |
|||
namespace LINGYUN.Abp.WeChat.Work.Token |
|||
namespace LINGYUN.Abp.WeChat.Work.Token.Models |
|||
{ |
|||
public class WeChatWorkTokenRequest |
|||
{ |
|||
@ -1,6 +1,6 @@ |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.Token |
|||
namespace LINGYUN.Abp.WeChat.Work.Token.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 微信访问令牌返回对象
|
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work; |
|||
|
|||
[Serializable] |
|||
public abstract class WeChatWorkRequest |
|||
{ |
|||
public virtual string SerializeToJson() |
|||
{ |
|||
return WeChatObjectSerializeExtensions.SerializeToJson(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Authorize.Request; |
|||
using System.Text; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace System.Net.Http |
|||
{ |
|||
internal static partial class HttpClientWeChatWorkRequestExtensions |
|||
{ |
|||
public async static Task<HttpResponseMessage> GetUserInfoAsync( |
|||
this HttpMessageInvoker client, |
|||
string accessToken, |
|||
string code, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/auth/getuserinfo"); |
|||
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
|||
urlBuilder.AppendFormat("&code={0}", code); |
|||
|
|||
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlBuilder.ToString()); |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
|
|||
public async static Task<HttpResponseMessage> GetUserDetailAsync( |
|||
this HttpMessageInvoker client, |
|||
string accessToken, |
|||
WeChatWorkUserDetailRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/auth/getuserdetail"); |
|||
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
|||
|
|||
var httpRequest = new HttpRequestMessage( |
|||
HttpMethod.Post, |
|||
urlBuilder.ToString()) |
|||
{ |
|||
Content = new StringContent(request.SerializeToJson()) |
|||
}; |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Chat.Request; |
|||
using System.Text; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace System.Net.Http |
|||
{ |
|||
internal static partial class HttpClientWeChatWorkRequestExtensions |
|||
{ |
|||
public async static Task<HttpResponseMessage> GetAppChatAsync( |
|||
this HttpMessageInvoker client, |
|||
string accessToken, |
|||
string chatId, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/appchat/get"); |
|||
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
|||
urlBuilder.AppendFormat("&chatid={0}", chatId); |
|||
|
|||
var httpRequest = new HttpRequestMessage( |
|||
HttpMethod.Get, |
|||
urlBuilder.ToString()); |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
|
|||
public async static Task<HttpResponseMessage> CreateAppChatAsync( |
|||
this HttpMessageInvoker client, |
|||
string accessToken, |
|||
WeChatWorkAppChatCreateRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/appchat/create"); |
|||
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
|||
|
|||
var httpRequest = new HttpRequestMessage( |
|||
HttpMethod.Post, |
|||
urlBuilder.ToString()) |
|||
{ |
|||
Content = new StringContent(request.SerializeToJson()) |
|||
}; |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
|
|||
public async static Task<HttpResponseMessage> UpdateAppChatAsync( |
|||
this HttpMessageInvoker client, |
|||
string accessToken, |
|||
WeChatWorkAppChatUpdateRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/appchat/update"); |
|||
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
|||
|
|||
var httpRequest = new HttpRequestMessage( |
|||
HttpMethod.Post, |
|||
urlBuilder.ToString()) |
|||
{ |
|||
Content = new StringContent(request.SerializeToJson()) |
|||
}; |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Media.Models; |
|||
using LINGYUN.Abp.WeChat.Work.Utils; |
|||
using System.IO; |
|||
using System.Text; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace System.Net.Http |
|||
{ |
|||
internal static partial class HttpClientWeChatWorkRequestExtensions |
|||
{ |
|||
public async static Task<HttpResponseMessage> GetMediaAsync( |
|||
this HttpMessageInvoker client, |
|||
string accessToken, |
|||
string mediaId, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/media/get"); |
|||
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
|||
urlBuilder.AppendFormat("&media_id={0}", mediaId); |
|||
|
|||
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlBuilder.ToString()); |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
|
|||
public async static Task<HttpResponseMessage> UploadMediaAsync( |
|||
this HttpMessageInvoker client, |
|||
string type, |
|||
WeChatWorkMediaRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/media/upload"); |
|||
urlBuilder.AppendFormat("?access_token={0}", request.AccessToken); |
|||
urlBuilder.AppendFormat("&type={0}", type); |
|||
|
|||
var fileBytes = await request.Content.GetStream().GetAllBytesAsync(); |
|||
var httpRequest = new HttpRequestMessage( |
|||
HttpMethod.Post, |
|||
urlBuilder.ToString()) |
|||
{ |
|||
Content = HttpContentBuildHelper.BuildUploadMediaContent("media", fileBytes, request.Content.FileName) |
|||
}; |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
|
|||
public async static Task<HttpResponseMessage> UploadImageAsync( |
|||
this HttpMessageInvoker client, |
|||
WeChatWorkMediaRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/media/uploadimg"); |
|||
urlBuilder.AppendFormat("?access_token={0}", request.AccessToken); |
|||
|
|||
var fileBytes = await request.Content.GetStream().GetAllBytesAsync(); |
|||
var httpRequest = new HttpRequestMessage( |
|||
HttpMethod.Post, |
|||
urlBuilder.ToString()) |
|||
{ |
|||
Content = HttpContentBuildHelper.BuildUploadMediaContent("file", fileBytes, request.Content.FileName) |
|||
}; |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Message; |
|||
using LINGYUN.Abp.WeChat.Work.Message.Request; |
|||
using System.Text; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace System.Net.Http |
|||
{ |
|||
internal static partial class HttpClientWeChatWorkRequestExtensions |
|||
{ |
|||
public async static Task<HttpResponseMessage> SendMessageAsync( |
|||
this HttpMessageInvoker client, |
|||
WeChatWorkMessageRequest<WeChatWorkMessage> request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/message/send"); |
|||
urlBuilder.AppendFormat("?access_token={0}", request.AccessToken); |
|||
|
|||
var httpRequest = new HttpRequestMessage( |
|||
HttpMethod.Post, |
|||
urlBuilder.ToString()) |
|||
{ |
|||
Content = new StringContent(request.Message.SerializeToJson()) |
|||
}; |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
|
|||
public async static Task<HttpResponseMessage> SendMessageAsync( |
|||
this HttpMessageInvoker client, |
|||
WeChatWorkMessageRequest<WeChatWorkAppChatMessage> request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/appchat/send"); |
|||
urlBuilder.AppendFormat("?access_token={0}", request.AccessToken); |
|||
|
|||
var httpRequest = new HttpRequestMessage( |
|||
HttpMethod.Post, |
|||
urlBuilder.ToString()) |
|||
{ |
|||
Content = new StringContent(request.Message.SerializeToJson()) |
|||
}; |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
|
|||
public async static Task<HttpResponseMessage> ReCallMessageAsync( |
|||
this HttpMessageInvoker client, |
|||
WeChatWorkMessageReCallRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var urlBuilder = new StringBuilder(); |
|||
urlBuilder.Append("/cgi-bin/message/recall"); |
|||
urlBuilder.AppendFormat("?access_token={0}", request.AccessToken); |
|||
|
|||
var httpRequest = new HttpRequestMessage( |
|||
HttpMethod.Post, |
|||
urlBuilder.ToString()) |
|||
{ |
|||
Content = new StringContent(request.SerializeToJson()) |
|||
}; |
|||
|
|||
return await client.SendAsync(httpRequest, cancellationToken); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using LINGYUN.Abp.WeChat.Work; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Http.Client; |
|||
|
|||
namespace System.Net.Http; |
|||
internal static class HttpResponseDeserializeExtensions |
|||
{ |
|||
public async static Task<T> DeserializeObjectAsync<T>(this HttpResponseMessage response) where T : WeChatWorkResponse |
|||
{ |
|||
if (!response.IsSuccessStatusCode) |
|||
{ |
|||
throw new AbpRemoteCallException($"Wechat work request error: {response.StatusCode} - {response.ReasonPhrase}"); |
|||
} |
|||
var responseContent = await response.Content.ReadAsStringAsync(); |
|||
|
|||
return responseContent.DeserializeObject<T>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace System; |
|||
internal static class WeChatObjectSerializeExtensions |
|||
{ |
|||
public static string SerializeToJson(this object @object) |
|||
{ |
|||
return JsonConvert.SerializeObject(@object); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using LINGYUN.Abp.WeChat.Work; |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace System; |
|||
internal static class WeChatWorkResponseDeserializeExtensions |
|||
{ |
|||
public static T DeserializeObject<T>(this string responseContent) where T : WeChatWorkResponse |
|||
{ |
|||
return JsonConvert.DeserializeObject<T>(responseContent); |
|||
} |
|||
} |
|||
@ -1 +1,2 @@ |
|||
global using Xunit; |
|||
global using Xunit; |
|||
global using Shouldly; |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue