committed by
GitHub
185 changed files with 7252 additions and 12 deletions
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,27 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.WeChat.Work.ExternalContact</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.WeChat.Work.ExternalContact</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GenerateDocumentationFile>True</GenerateDocumentationFile> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\WeChat\Work\ExternalContact\Localization\Resources\*.json" /> |
|||
<EmbeddedResource Include="LINGYUN\Abp\WeChat\Work\ExternalContact\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.WeChat.Work\LINGYUN.Abp.WeChat.Work.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,78 @@ |
|||
using LINGYUN.Abp.WeChat.Common; |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
using LINGYUN.Abp.WeChat.Work.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact; |
|||
|
|||
[DependsOn(typeof(AbpWeChatWorkModule))] |
|||
public class AbpWeChatWorkExternalContactModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpWeChatWorkMessageResolveOptions>(options => |
|||
{ |
|||
// 企业客户变更事件
|
|||
options.MapEvent("change_external_contact", context => |
|||
{ |
|||
var changeType = context.GetMessageData("ChangeType"); |
|||
return changeType switch |
|||
{ |
|||
"add_external_contact" => context.GetWeChatMessage<ExternalContactCreateEvent>(), |
|||
"edit_external_contact" => context.GetWeChatMessage<ExternalContactUpdateEvent>(), |
|||
"add_half_external_contact" => context.GetWeChatMessage<ExternalContactCreateHalfEvent>(), |
|||
"del_external_contact" => context.GetWeChatMessage<ExternalContactDeleteEvent>(), |
|||
"del_follow_user" => context.GetWeChatMessage<ExternalContactDeleteFollowUserEvent>(), |
|||
"transfer_fail" => context.GetWeChatMessage<ExternalContactTransferFailEvent>(), |
|||
_ => throw new AbpWeChatException($"Contact change event change_external_contact:{changeType} is not mounted!"), |
|||
}; |
|||
}); |
|||
// 客户群变更事件
|
|||
options.MapEvent("change_external_chat", context => |
|||
{ |
|||
var changeType = context.GetMessageData("ChangeType"); |
|||
switch (changeType) |
|||
{ |
|||
case "create": return context.GetWeChatMessage<ExternalChatCreateEvent>(); |
|||
case "update": |
|||
// 客户群变更事件
|
|||
var updateDetail = context.GetMessageData("UpdateDetail"); |
|||
return updateDetail switch |
|||
{ |
|||
"add_member" => context.GetWeChatMessage<ExternalChatAddMemberEvent>(), |
|||
"del_member" => context.GetWeChatMessage<ExternalChaDelMemberEvent>(), |
|||
"change_owner" => context.GetWeChatMessage<ExternalChatChangeOwnerEvent>(), |
|||
"change_name" => context.GetWeChatMessage<ExternalChatChangeNameEvent>(), |
|||
"change_notice" => context.GetWeChatMessage<ExternalChatChangeNoticeEvent>(), |
|||
_ => throw new AbpWeChatException($"Contact change event change_external_chat:{changeType}:{updateDetail} is not mounted!"), |
|||
}; |
|||
case "dismiss": return context.GetWeChatMessage<ExternalChatDismissEvent>(); |
|||
default: throw new AbpWeChatException($"Contact change event change_external_chat:{changeType} is not mounted!"); |
|||
} |
|||
}); |
|||
// 企业客户标签事件
|
|||
options.MapEvent("change_external_tag", context => |
|||
{ |
|||
var changeType = context.GetMessageData("ChangeType"); |
|||
return changeType switch |
|||
{ |
|||
"create" => context.GetWeChatMessage<ExternalTagCreateEvent>(), |
|||
"update" => context.GetWeChatMessage<ExternalTagUpdateEvent>(), |
|||
"delete" => context.GetWeChatMessage<ExternalTagDeleteEvent>(), |
|||
"shuffle" => context.GetWeChatMessage<ExternalTagShuffleEvent>(), |
|||
_ => throw new AbpWeChatException($"Contact change event change_external_tag:{changeType} is not mounted!"), |
|||
}; |
|||
}); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<WeChatWorkResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/WeChat/Work/ExternalContact/Localization/Resources"); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Response; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments; |
|||
/// <summary>
|
|||
/// 附件资源接口
|
|||
/// </summary>
|
|||
public interface IWeChatWorkAttachmentProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 上传附件资源
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/90253"/>
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkUploadAttachmentResponse> UploadAsync( |
|||
WeChatWorkUploadAttachmentRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Models; |
|||
/// <summary>
|
|||
/// 附件类型
|
|||
/// </summary>
|
|||
[Description("附件类型")] |
|||
public enum AttachmentType |
|||
{ |
|||
/// <summary>
|
|||
/// 朋友圈
|
|||
/// </summary>
|
|||
[Description("朋友圈")] |
|||
Moments = 1, |
|||
/// <summary>
|
|||
/// 商品图册
|
|||
/// </summary>
|
|||
[Description("商品图册")] |
|||
ProductCatalogue = 2, |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Models; |
|||
/// <summary>
|
|||
/// 媒体文件类型
|
|||
/// </summary>
|
|||
[Description("媒体文件类型")] |
|||
public enum MediaType |
|||
{ |
|||
/// <summary>
|
|||
/// 图片
|
|||
/// </summary>
|
|||
[Description("图片")] |
|||
Image = 1, |
|||
/// <summary>
|
|||
/// 视频
|
|||
/// </summary>
|
|||
[Description("视频")] |
|||
Video = 2, |
|||
/// <summary>
|
|||
/// 普通文件
|
|||
/// </summary>
|
|||
[Description("普通文件")] |
|||
File = 3, |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Models; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Request; |
|||
/// <summary>
|
|||
/// 上传附件资源请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/95098" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkUploadAttachmentRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 媒体文件类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
public MediaType MediaType { get; } |
|||
/// <summary>
|
|||
/// 附件类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
public AttachmentType AttachmentType { get; } |
|||
/// <summary>
|
|||
/// 媒体文件
|
|||
/// </summary>
|
|||
[NotNull] |
|||
public IRemoteStreamContent Content { get; } |
|||
public WeChatWorkUploadAttachmentRequest( |
|||
MediaType mediaType, |
|||
AttachmentType attachmentType, |
|||
IRemoteStreamContent content) |
|||
{ |
|||
Check.NotNull(content, nameof(content)); |
|||
|
|||
MediaType = mediaType; |
|||
AttachmentType = attachmentType; |
|||
Content = content; |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Response; |
|||
/// <summary>
|
|||
/// 上传附件资源响应结果
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/95098" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkUploadAttachmentResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public string MediaType { get; set; } |
|||
/// <summary>
|
|||
/// 媒体文件上传后获取的唯一标识,三天有效,可使用获取临时素材接口获取
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("media_id")] |
|||
[JsonPropertyName("media_id")] |
|||
public string MediaId { get; set; } |
|||
/// <summary>
|
|||
/// 媒体文件上传时间戳
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("created_at")] |
|||
[JsonPropertyName("created_at")] |
|||
public long CreatedAt { get; set; } |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Response; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features; |
|||
using LINGYUN.Abp.WeChat.Work.Token; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System.Net.Http; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments; |
|||
|
|||
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)] |
|||
public class WeChatWorkAttachmentProvider : IWeChatWorkAttachmentProvider, ISingletonDependency |
|||
{ |
|||
protected IHttpClientFactory HttpClientFactory { get; } |
|||
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
|||
|
|||
public WeChatWorkAttachmentProvider( |
|||
IHttpClientFactory httpClientFactory, |
|||
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
|||
{ |
|||
HttpClientFactory = httpClientFactory; |
|||
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkUploadAttachmentResponse> UploadAsync( |
|||
WeChatWorkUploadAttachmentRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.UploadAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkUploadAttachmentResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Response; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts; |
|||
/// <summary>
|
|||
/// 外部联系人接口
|
|||
/// </summary>
|
|||
public interface IWeChatWorkExternalContactProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 获取已服务的外部联系人
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/99434" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkGetExternalContactListResponse> GetExternalContactListAsync( |
|||
WeChatWorkGetExternalContactListRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,73 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Models; |
|||
/// <summary>
|
|||
/// 外部联系人
|
|||
/// </summary>
|
|||
public class ExternalContactInfo |
|||
{ |
|||
/// <summary>
|
|||
/// 是否被成员标记为客户
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("is_customer")] |
|||
[JsonPropertyName("is_customer")] |
|||
public bool IsCustomer { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人临时ID
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
///
|
|||
/// 外部联系人临时id是一个外部联系人的唯一标识,企业可根据此id对外部联系人进行去重统计。<br />
|
|||
/// 但外部联系人临时id仅在一轮遍历查询(从首个分页查询开始到最后一个分页查询完毕)中唯一;<br />
|
|||
/// 每次请求首个数据分页(cursor为空)时,返回的外部联系人临时id和next_cursor将发生变化。
|
|||
/// </remarks>
|
|||
[NotNull] |
|||
[JsonProperty("tmp_openid")] |
|||
[JsonPropertyName("tmp_openid")] |
|||
public string TmpOpenId { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人的externaluserid(如果是客户才返回)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("external_userid")] |
|||
[JsonPropertyName("external_userid")] |
|||
public string? ExternalUserId { get; set; } |
|||
/// <summary>
|
|||
/// 脱敏后的外部联系人昵称(如果是其他外部联系人才返回)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("name")] |
|||
[JsonPropertyName("name")] |
|||
public string? Name { get; set; } |
|||
/// <summary>
|
|||
/// 添加此外部联系人的企业成员或外部联系人所在群聊的群主userid
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("follow_userid")] |
|||
[JsonPropertyName("follow_userid")] |
|||
public string? FollowUserId { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人所在的群聊ID(如果群聊被成员标记为客户群才返回)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("chat_id")] |
|||
[JsonPropertyName("chat_id")] |
|||
public string? ChatId { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人所在群聊的群名(如果群聊未被成员标记为客户群才返回)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("chat_name")] |
|||
[JsonPropertyName("chat_name")] |
|||
public string? ChatName { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人首次添加/进群的时间
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("add_time")] |
|||
[JsonPropertyName("add_time")] |
|||
public long AddTime { get; set; } |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Request; |
|||
/// <summary>
|
|||
/// 获取已服务的外部联系人请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/99434" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetExternalContactListRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 用于分页查询的游标,字符串类型,由上一次调用返回,首次调用可不填
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// cursor具有有效期,请勿缓存后使用
|
|||
/// </remarks>
|
|||
[CanBeNull] |
|||
[JsonProperty("cursor")] |
|||
[JsonPropertyName("cursor")] |
|||
public string? Cursor { get; } |
|||
/// <summary>
|
|||
/// 返回的最大记录数,整型,默认为1000
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("limit")] |
|||
[JsonPropertyName("limit")] |
|||
public int? Limit { get; } |
|||
public WeChatWorkGetExternalContactListRequest(string? cursor = null, int? limit = 1000) |
|||
{ |
|||
Cursor = cursor; |
|||
Limit = limit; |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Response; |
|||
/// <summary>
|
|||
/// 获取已服务的外部联系人响应结果
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92994" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetExternalContactListResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 外部联系人列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("info_list")] |
|||
[JsonPropertyName("info_list")] |
|||
public ExternalContactInfo[] InfoList { get; set; } |
|||
/// <summary>
|
|||
/// 分页游标,再下次请求时填写以获取之后分页的记录,如果已经没有更多的数据则返回空,有效期为4小时
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("next_cursor")] |
|||
[JsonPropertyName("next_cursor")] |
|||
public string? NextCursor { get; set; } |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Response; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features; |
|||
using LINGYUN.Abp.WeChat.Work.Token; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System.Net.Http; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts; |
|||
|
|||
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)] |
|||
public class WeChatWorkExternalContactProvider : IWeChatWorkExternalContactProvider, ISingletonDependency |
|||
{ |
|||
protected IHttpClientFactory HttpClientFactory { get; } |
|||
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
|||
|
|||
public WeChatWorkExternalContactProvider( |
|||
IHttpClientFactory httpClientFactory, |
|||
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
|||
{ |
|||
HttpClientFactory = httpClientFactory; |
|||
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkGetExternalContactListResponse> GetExternalContactListAsync( |
|||
WeChatWorkGetExternalContactListRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
Check.NotNull(request, nameof(request)); |
|||
|
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.GetExternalContactListAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetExternalContactListResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers; |
|||
/// <summary>
|
|||
/// 客户管理接口
|
|||
/// </summary>
|
|||
public interface IWeChatWorkCustomerProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 获取客户列表
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92113" />
|
|||
/// </remarks>
|
|||
/// <param name="userId">企业成员的userid</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkGetCustomerListResponse> GetCustomerListAsync( |
|||
string userId, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 批量获取客户详情
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92994" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkBulkGetCustomerResponse> BulkGetCustomerAsync( |
|||
WeChatWorkBulkGetCustomerRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 获取客户详情
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92114" />
|
|||
/// </remarks>
|
|||
/// <param name="externalUserid">外部联系人的userid,注意不是企业成员的账号</param>
|
|||
/// <param name="cursor">上次请求返回的next_cursor</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkGetCustomerResponse> GetCustomerAsync( |
|||
string externalUserid, |
|||
string? cursor = null, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 修改客户备注信息
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92115" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkResponse> UpdateCustomerRemarkAsync( |
|||
WeChatWorkUpdateCustomerRemarkRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,87 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers; |
|||
/// <summary>
|
|||
/// 客户联系规则组管理
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
|
|||
/// </remarks>
|
|||
public interface IWeChatWorkCustomerStrategyProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 获取规则组列表
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E5%88%97%E8%A1%A8" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkGetCustomerStrategyListResponse> GetCustomerStrategyListAsync( |
|||
WeChatWorkGetCustomerStrategyListRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 获取规则组
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E8%AF%A6%E6%83%85" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkGetCustomerStrategyResponse> GetCustomerStrategyAsync( |
|||
WeChatWorkGetCustomerStrategyRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 获取规则组管理范围
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkGetCustomerStrategyRangeResponse> GetCustomerStrategyRangeAsync( |
|||
WeChatWorkGetCustomerStrategyRangeRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 创建新的规则组
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E5%88%9B%E5%BB%BA%E6%96%B0%E7%9A%84%E8%A7%84%E5%88%99%E7%BB%84" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkCreateCustomerStrategyResponse> CreateCustomerStrategyAsync( |
|||
WeChatWorkCreateCustomerStrategyRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 编辑规则组及其管理范围
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E7%BC%96%E8%BE%91%E8%A7%84%E5%88%99%E7%BB%84%E5%8F%8A%E5%85%B6%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkResponse> UpdateCustomerStrategyAsync( |
|||
WeChatWorkUpdateCustomerStrategyRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 删除规则组
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E5%88%A0%E9%99%A4%E8%A7%84%E5%88%99%E7%BB%84" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkResponse> DeleteCustomerStrategyAsync( |
|||
WeChatWorkDeleteCustomerStrategyRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 规则组
|
|||
/// </summary>
|
|||
public class CustomerStrategy |
|||
{ |
|||
/// <summary>
|
|||
/// 规则组id
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy_id")] |
|||
[JsonPropertyName("strategy_id")] |
|||
public int StrategyId { get; set; } |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 规则组详情
|
|||
/// </summary>
|
|||
public class CustomerStrategyInfo : CustomerStrategy |
|||
{ |
|||
/// <summary>
|
|||
/// 父规则组id, 如果当前规则组没父规则组,则为0
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("parent_id")] |
|||
[JsonPropertyName("parent_id")] |
|||
public int ParentId { get; set; } |
|||
/// <summary>
|
|||
/// 规则组名称
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy_name")] |
|||
[JsonPropertyName("strategy_name")] |
|||
public string StrategyName { get; set; } |
|||
/// <summary>
|
|||
/// 规则组创建时间戳
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("create_time")] |
|||
[JsonPropertyName("create_time")] |
|||
public long CreateTime { get; set; } |
|||
/// <summary>
|
|||
/// 规则组管理员userid列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("admin_list")] |
|||
[JsonPropertyName("admin_list")] |
|||
public string[] AdminList { get; set; } |
|||
/// <summary>
|
|||
/// 规则组权限
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("privilege")] |
|||
[JsonPropertyName("privilege")] |
|||
public CustomerStrategyPrivilege Privilege { get; set; } |
|||
} |
|||
@ -0,0 +1,183 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 规则组权限
|
|||
/// </summary>
|
|||
public class CustomerStrategyPrivilege |
|||
{ |
|||
/// <summary>
|
|||
/// 查看客户列表,基础权限,不可取消
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("view_customer_list")] |
|||
[JsonPropertyName("view_customer_list")] |
|||
public bool ViewCustomerList { get; set; } |
|||
/// <summary>
|
|||
/// 查看客户统计数据,基础权限,不可取消
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("view_customer_data")] |
|||
[JsonPropertyName("view_customer_data")] |
|||
public bool ViewCustomerData { get; set; } |
|||
/// <summary>
|
|||
/// 查看群聊列表,基础权限,不可取消
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("view_room_list")] |
|||
[JsonPropertyName("view_room_list")] |
|||
public bool ViewRoomList { get; set; } |
|||
/// <summary>
|
|||
/// 可使用联系我,基础权限,不可取消
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("contact_me")] |
|||
[JsonPropertyName("contact_me")] |
|||
public bool ContactMe { get; set; } |
|||
/// <summary>
|
|||
/// 可加入群聊,基础权限,不可取消
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("join_room")] |
|||
[JsonPropertyName("join_room")] |
|||
public bool JoinRoom { get; set; } |
|||
/// <summary>
|
|||
/// 允许分享客户给其他成员,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("share_customer")] |
|||
[JsonPropertyName("share_customer")] |
|||
public bool ShareCustomer { get; set; } |
|||
/// <summary>
|
|||
/// 允许分配离职成员客户,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("oper_resign_customer")] |
|||
[JsonPropertyName("oper_resign_customer")] |
|||
public bool OperResignCustomer { get; set; } |
|||
/// <summary>
|
|||
/// 允许分配离职成员客户群,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("oper_resign_group")] |
|||
[JsonPropertyName("oper_resign_group")] |
|||
public bool OperResignGroup { get; set; } |
|||
/// <summary>
|
|||
/// 允许给企业客户发送消息,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("send_customer_msg")] |
|||
[JsonPropertyName("send_customer_msg")] |
|||
public bool SendCustomerMsg { get; set; } |
|||
/// <summary>
|
|||
/// 允许配置欢迎语,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("edit_welcome_msg")] |
|||
[JsonPropertyName("edit_welcome_msg")] |
|||
public bool EditWelcomeMsg { get; set; } |
|||
/// <summary>
|
|||
/// 允许查看成员联系客户统计,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("view_behavior_data")] |
|||
[JsonPropertyName("view_behavior_data")] |
|||
public bool ViewBehaviorData { get; set; } |
|||
/// <summary>
|
|||
/// 允许查看群聊数据统计,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("view_room_data")] |
|||
[JsonPropertyName("view_room_data")] |
|||
public bool ViewRoomData { get; set; } |
|||
/// <summary>
|
|||
/// 允许发送消息到企业的客户群,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("send_group_msg")] |
|||
[JsonPropertyName("send_group_msg")] |
|||
public bool SendGroupMsg { get; set; } |
|||
/// <summary>
|
|||
/// 允许对企业客户群进行去重,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("room_deduplication")] |
|||
[JsonPropertyName("room_deduplication")] |
|||
public bool RoomDeduplication { get; set; } |
|||
/// <summary>
|
|||
/// 配置快捷回复,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("rapid_reply")] |
|||
[JsonPropertyName("rapid_reply")] |
|||
public bool RapidReply { get; set; } |
|||
/// <summary>
|
|||
/// 转接在职成员的客户,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("onjob_customer_transfer")] |
|||
[JsonPropertyName("onjob_customer_transfer")] |
|||
public bool OnjobCustomerTransfer { get; set; } |
|||
/// <summary>
|
|||
/// 编辑企业成员防骚扰规则,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("edit_anti_spam_rule")] |
|||
[JsonPropertyName("edit_anti_spam_rule")] |
|||
public bool EditAntiSpamRule { get; set; } |
|||
/// <summary>
|
|||
/// 导出客户列表,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("export_customer_list")] |
|||
[JsonPropertyName("export_customer_list")] |
|||
public bool ExportCustomerList { get; set; } |
|||
/// <summary>
|
|||
/// 导出成员客户统计,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("export_customer_data")] |
|||
[JsonPropertyName("export_customer_data")] |
|||
public bool ExportCustomerData { get; set; } |
|||
/// <summary>
|
|||
/// 导出客户群列表,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("export_customer_group_list")] |
|||
[JsonPropertyName("export_customer_group_list")] |
|||
public bool ExportCustomerGroupList { get; set; } |
|||
/// <summary>
|
|||
/// 配置企业客户标签,默认为true
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("manage_customer_tag")] |
|||
[JsonPropertyName("manage_customer_tag")] |
|||
public bool ManageCustomerTag { get; set; } |
|||
|
|||
public static CustomerStrategyPrivilege Default() |
|||
{ |
|||
return new CustomerStrategyPrivilege |
|||
{ |
|||
ViewCustomerList = true, |
|||
ViewCustomerData = true, |
|||
ViewRoomList = true, |
|||
ContactMe = true, |
|||
JoinRoom = true, |
|||
ShareCustomer = true, |
|||
EditWelcomeMsg = true, |
|||
ViewBehaviorData = true, |
|||
ViewRoomData = true, |
|||
SendGroupMsg = true, |
|||
RoomDeduplication = true, |
|||
RapidReply = true, |
|||
OnjobCustomerTransfer = true, |
|||
EditAntiSpamRule = true, |
|||
ExportCustomerList = true, |
|||
ExportCustomerData = true, |
|||
ExportCustomerGroupList = true, |
|||
ManageCustomerTag = true, |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 规则组管理范围
|
|||
/// </summary>
|
|||
public class CustomerStrategyRange |
|||
{ |
|||
/// <summary>
|
|||
/// 节点类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public CustomerStrategyRangeType Type { get; set; } |
|||
/// <summary>
|
|||
/// 管理范围内配置的成员userid,仅 Type为<see cref="CustomerStrategyRangeType.Member"/> 时返回
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("userid")] |
|||
[JsonPropertyName("userid")] |
|||
public string? UserId { get; set; } |
|||
/// <summary>
|
|||
/// 管理范围内配置的部门partyid,仅 Type为<see cref="CustomerStrategyRangeType.Part"/> 时返回
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("partyid")] |
|||
[JsonPropertyName("partyid")] |
|||
public int? PartyId { get; set; } |
|||
|
|||
public CustomerStrategyRange() |
|||
{ |
|||
|
|||
} |
|||
|
|||
private CustomerStrategyRange( |
|||
CustomerStrategyRangeType type, |
|||
string? userId = null, |
|||
int? partyId = null) |
|||
{ |
|||
Type = type; |
|||
UserId = userId; |
|||
PartyId = partyId; |
|||
} |
|||
|
|||
public static CustomerStrategyRange Member(string userId) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(userId, nameof(userId)); |
|||
|
|||
return new CustomerStrategyRange(CustomerStrategyRangeType.Member, userId); |
|||
} |
|||
public static CustomerStrategyRange Party(int partyId) |
|||
{ |
|||
Check.NotDefaultOrNull<int>(partyId, nameof(partyId)); |
|||
|
|||
return new CustomerStrategyRange(CustomerStrategyRangeType.Part, partyId: partyId); |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 节点类型
|
|||
/// </summary>
|
|||
[Description("节点类型")] |
|||
public enum CustomerStrategyRangeType |
|||
{ |
|||
/// <summary>
|
|||
/// 成员
|
|||
/// </summary>
|
|||
[Description("成员")] |
|||
Member = 1, |
|||
/// <summary>
|
|||
/// 部门
|
|||
/// </summary>
|
|||
[Description("部门")] |
|||
Part = 2 |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 外部联系人性别
|
|||
/// </summary>
|
|||
[Description("外部联系人性别")] |
|||
public enum ExternalContactGender |
|||
{ |
|||
/// <summary>
|
|||
/// 未知
|
|||
/// </summary>
|
|||
[Description("未知")] |
|||
None = 0, |
|||
/// <summary>
|
|||
/// 男性
|
|||
/// </summary>
|
|||
[Description("男性")] |
|||
Male = 1, |
|||
/// <summary>
|
|||
/// 女性
|
|||
/// </summary>
|
|||
[Description("女性")] |
|||
FeMale = 2, |
|||
} |
|||
@ -0,0 +1,88 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 外部联系人信息
|
|||
/// </summary>
|
|||
public class ExternalContactInfo |
|||
{ |
|||
/// <summary>
|
|||
/// 外部联系人的userid
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("external_userid")] |
|||
[JsonPropertyName("external_userid")] |
|||
public string ExternalUserId { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人的名称
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 如果是微信用户,则返回其微信昵称。<br />
|
|||
/// 如果是企业微信联系人,则返回其设置对外展示的别名或实名
|
|||
/// </remarks>
|
|||
[NotNull] |
|||
[JsonProperty("name")] |
|||
[JsonPropertyName("name")] |
|||
public string Name { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人头像
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("avatar")] |
|||
[JsonPropertyName("avatar")] |
|||
public string? Avatar { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人的类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public ExternalContactType Type { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人性别
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("gender")] |
|||
[JsonPropertyName("gender")] |
|||
public ExternalContactGender Gender { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人在微信开放平台的唯一身份标识(微信unionid),通过此字段企业可将外部联系人与公众号/小程序用户关联起来。<br />
|
|||
/// 仅当联系人类型是微信用户,且企业绑定了微信开发者ID有此字段
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("unionid")] |
|||
[JsonPropertyName("unionid")] |
|||
public string? UnionId { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人的职位,如果外部企业或用户选择隐藏职位,则不返回,仅当联系人类型是企业微信用户时有此字段
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("position")] |
|||
[JsonPropertyName("position")] |
|||
public string? Position { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人所在企业的简称,仅当联系人类型是企业微信用户时有此字段
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("corp_name")] |
|||
[JsonPropertyName("corp_name")] |
|||
public string? CorpName { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人所在企业的主体名称,仅当联系人类型是企业微信用户时有此字段<br />
|
|||
/// 仅企业自建应用可获取
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("corp_full_name")] |
|||
[JsonPropertyName("corp_full_name")] |
|||
public string? CorpFullName { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人的自定义展示信息
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("external_profile")] |
|||
[JsonPropertyName("external_profile")] |
|||
public ExternalProfile? ExternalProfile { get; set; } |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 外部联系人列表
|
|||
/// </summary>
|
|||
public class ExternalContactList |
|||
{ |
|||
/// <summary>
|
|||
/// 客户的基本信息
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("external_contact")] |
|||
[JsonPropertyName("external_contact")] |
|||
public ExternalContactInfo ExternalContact { get; set; } |
|||
/// <summary>
|
|||
/// 企业成员客户跟进信息
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("follow_info")] |
|||
[JsonPropertyName("follow_info")] |
|||
public FollowUser FollowUser { get; set; } |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 外部联系人类型
|
|||
/// </summary>
|
|||
[Description("外部联系人类型")] |
|||
public enum ExternalContactType |
|||
{ |
|||
/// <summary>
|
|||
/// 微信用户
|
|||
/// </summary>
|
|||
[Description("微信用户")] |
|||
WeChat = 1, |
|||
/// <summary>
|
|||
/// 企业微信用户
|
|||
/// </summary>
|
|||
[Description("企业微信用户")] |
|||
WeChatWork = 2, |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 添加了外部联系人的企业成员
|
|||
/// </summary>
|
|||
public class FollowUser |
|||
{ |
|||
/// <summary>
|
|||
/// 添加了此外部联系人的企业成员userid
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("userid")] |
|||
[JsonPropertyName("userid")] |
|||
public string UserId { get; set; } |
|||
/// <summary>
|
|||
/// 发起添加的userid<br />
|
|||
/// 如果成员主动添加,为成员的userid;<br />
|
|||
/// 如果是客户主动添加,则为客户的外部联系人userid;<br />
|
|||
/// 如果是内部成员共享/管理员分配,则为对应的成员/管理员userid
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("oper_userid")] |
|||
[JsonPropertyName("oper_userid")] |
|||
public string OperUserId { get; set; } |
|||
/// <summary>
|
|||
/// 企业自定义的state参数,用于区分客户具体是通过哪个「联系我」或获客链接添加
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("state")] |
|||
[JsonPropertyName("state")] |
|||
public string? State { get; set; } |
|||
/// <summary>
|
|||
/// 该成员对此外部联系人的备注
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("remark")] |
|||
[JsonPropertyName("remark")] |
|||
public string? Remark { get; set; } |
|||
/// <summary>
|
|||
/// 该成员对此外部联系人的描述
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("description")] |
|||
[JsonPropertyName("description")] |
|||
public string? Description { get; set; } |
|||
/// <summary>
|
|||
/// 该成员添加此外部联系人的时间
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("createtime")] |
|||
[JsonPropertyName("createtime")] |
|||
public long Createtime { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人所打标签列表
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("tags")] |
|||
[JsonPropertyName("tags")] |
|||
public List<FollowUserTag>? Tags { get; set; } |
|||
/// <summary>
|
|||
/// 该成员对此微信客户备注的企业名称(仅微信客户有该字段)
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("remark_corp_name")] |
|||
[JsonPropertyName("remark_corp_name")] |
|||
public string? RemarkCorpName { get; set; } |
|||
/// <summary>
|
|||
/// 该成员对此客户备注的手机号码,代开发自建应用需要管理员授权才可以获取
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("remark_mobiles")] |
|||
[JsonPropertyName("remark_mobiles")] |
|||
public List<string>? RemarkMobiles { get; set; } |
|||
/// <summary>
|
|||
/// 该成员添加此客户的来源
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("add_way")] |
|||
[JsonPropertyName("add_way")] |
|||
public FollowUserAddWay AddWay { get; set; } |
|||
/// <summary>
|
|||
/// 该成员添加此客户的来源add_way为10时,对应的视频号信息
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("wechat_channels")] |
|||
[JsonPropertyName("wechat_channels")] |
|||
public FollowUserWechatChannel? WechatChannel { get; set; } |
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 客户来源
|
|||
/// </summary>
|
|||
[Description("客户来源")] |
|||
public enum FollowUserAddWay |
|||
{ |
|||
/// <summary>
|
|||
/// 未知来源
|
|||
/// </summary>
|
|||
[Description("未知来源")] |
|||
None = 0, |
|||
/// <summary>
|
|||
/// 扫描二维码
|
|||
/// </summary>
|
|||
[Description("扫描二维码")] |
|||
ScanQrCode = 1, |
|||
/// <summary>
|
|||
/// 搜索手机号
|
|||
/// </summary>
|
|||
[Description("搜索手机号")] |
|||
SearchPhoneNumber = 2, |
|||
/// <summary>
|
|||
/// 名片分享
|
|||
/// </summary>
|
|||
[Description("名片分享")] |
|||
SharedCard = 3, |
|||
/// <summary>
|
|||
/// 群聊
|
|||
/// </summary>
|
|||
[Description("群聊")] |
|||
GroupChat = 4, |
|||
/// <summary>
|
|||
/// 手机通讯录
|
|||
/// </summary>
|
|||
[Description("手机通讯录")] |
|||
PhoneBook = 5, |
|||
/// <summary>
|
|||
/// 微信联系人
|
|||
/// </summary>
|
|||
[Description("微信联系人")] |
|||
WeChatContact = 6, |
|||
/// <summary>
|
|||
/// 安装第三方应用时自动添加的客服人员
|
|||
/// </summary>
|
|||
[Description("安装第三方应用时自动添加的客服人员")] |
|||
InstallThirdPartyApp = 8, |
|||
/// <summary>
|
|||
/// 搜索邮箱
|
|||
/// </summary>
|
|||
[Description("搜索邮箱")] |
|||
SearchEmail = 9, |
|||
/// <summary>
|
|||
/// 视频号添加
|
|||
/// </summary>
|
|||
[Description("视频号添加")] |
|||
WechatChannel = 10, |
|||
/// <summary>
|
|||
/// 通过日程参与人添加
|
|||
/// </summary>
|
|||
[Description("通过日程参与人添加")] |
|||
SchedulePart = 11, |
|||
/// <summary>
|
|||
/// 通过会议参与人添加
|
|||
/// </summary>
|
|||
[Description("通过会议参与人添加")] |
|||
MeetPart = 12, |
|||
/// <summary>
|
|||
/// 添加微信好友对应的企业微信
|
|||
/// </summary>
|
|||
[Description("添加微信好友对应的企业微信")] |
|||
WeChatFriend = 13, |
|||
/// <summary>
|
|||
/// 通过智慧硬件专属客服添加
|
|||
/// </summary>
|
|||
[Description("通过智慧硬件专属客服添加")] |
|||
SmartHardware = 14, |
|||
/// <summary>
|
|||
/// 通过上门服务客服添加
|
|||
/// </summary>
|
|||
[Description("通过上门服务客服添加")] |
|||
DoorService = 15, |
|||
/// <summary>
|
|||
/// 通过获客链接添加
|
|||
/// </summary>
|
|||
[Description("通过获客链接添加")] |
|||
CustomerAcqLink = 16, |
|||
/// <summary>
|
|||
/// 通过定制开发添加
|
|||
/// </summary>
|
|||
[Description("通过定制开发添加")] |
|||
CustomDevelopment = 17, |
|||
/// <summary>
|
|||
/// 通过需求回复添加
|
|||
/// </summary>
|
|||
[Description("通过需求回复添加")] |
|||
DemandResponse = 18, |
|||
/// <summary>
|
|||
/// 通过第三方售前客服添加
|
|||
/// </summary>
|
|||
[Description("通过第三方售前客服添加")] |
|||
ThirdPartyPreSales = 21, |
|||
/// <summary>
|
|||
/// 通过可能的商务伙伴添加
|
|||
/// </summary>
|
|||
[Description("通过可能的商务伙伴添加")] |
|||
PotentialBusPart = 22, |
|||
/// <summary>
|
|||
/// 通过接受微信账号收到的好友申请添加
|
|||
/// </summary>
|
|||
[Description("通过接受微信账号收到的好友申请添加")] |
|||
WeChatFriendRequest = 24, |
|||
/// <summary>
|
|||
/// 内部成员共享
|
|||
/// </summary>
|
|||
[Description("内部成员共享")] |
|||
SharedByInternalMembers = 201, |
|||
/// <summary>
|
|||
/// 管理员/负责人分配
|
|||
/// </summary>
|
|||
[Description("管理员/负责人分配")] |
|||
AllocationByAdmin = 202 |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 外部联系人所打标签
|
|||
/// </summary>
|
|||
public class FollowUserTag |
|||
{ |
|||
/// <summary>
|
|||
/// 该成员添加此外部联系人所打标签的分组名称
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("group_name")] |
|||
[JsonPropertyName("group_name")] |
|||
public string? GroupName { get; set; } |
|||
/// <summary>
|
|||
/// 该成员添加此外部联系人所打标签名称
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("tag_name")] |
|||
[JsonPropertyName("tag_name")] |
|||
public string TagName { get; set; } |
|||
/// <summary>
|
|||
/// 该成员添加此外部联系人所打标签类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public FollowUserTagType Type { get; set; } |
|||
/// <summary>
|
|||
/// 该成员添加此外部联系人所打企业标签的id,用户自定义类型标签(type=2)不返回
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("tag_id")] |
|||
[JsonPropertyName("tag_id")] |
|||
public string? TagId { get; set; } |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 标签类型
|
|||
/// </summary>
|
|||
[Description("标签类型")] |
|||
public enum FollowUserTagType |
|||
{ |
|||
/// <summary>
|
|||
/// 企业设置
|
|||
/// </summary>
|
|||
[Description("企业设置")] |
|||
EnterpriseSettings = 1, |
|||
/// <summary>
|
|||
/// 用户自定义
|
|||
/// </summary>
|
|||
[Description("用户自定义")] |
|||
UserCustom = 2, |
|||
/// <summary>
|
|||
/// 规则组标签
|
|||
/// </summary>
|
|||
[Description("规则组标签")] |
|||
RuleGroupTags = 3, |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 视频号信息
|
|||
/// </summary>
|
|||
public class FollowUserWechatChannel |
|||
{ |
|||
/// <summary>
|
|||
/// 视频号名称
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("nickname")] |
|||
[JsonPropertyName("nickname")] |
|||
public string NickName { get; set; } |
|||
/// <summary>
|
|||
/// 视频号添加场景
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("source")] |
|||
[JsonPropertyName("source")] |
|||
public FollowUserWechatChannelSource Source { get; set; } |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
/// <summary>
|
|||
/// 视频号添加场景
|
|||
/// </summary>
|
|||
[Description("视频号添加场景")] |
|||
public enum FollowUserWechatChannelSource |
|||
{ |
|||
/// <summary>
|
|||
/// 未知
|
|||
/// </summary>
|
|||
[Description("未知")] |
|||
None = 0, |
|||
/// <summary>
|
|||
/// 视频号主页
|
|||
/// </summary>
|
|||
[Description("视频号主页")] |
|||
Home = 1, |
|||
/// <summary>
|
|||
/// 视频号直播间
|
|||
/// </summary>
|
|||
[Description("视频号直播间")] |
|||
LiveRoom = 2, |
|||
/// <summary>
|
|||
/// 视频号留资服务
|
|||
/// </summary>
|
|||
[Description("视频号留资服务")] |
|||
RetentionService = 3 |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
/// <summary>
|
|||
/// 创建新的规则组请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E5%88%9B%E5%BB%BA%E6%96%B0%E7%9A%84%E8%A7%84%E5%88%99%E7%BB%84" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkBulkGetCustomerRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 企业成员的userid列表,字符串类型,最多支持100个
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("userid_list")] |
|||
[JsonPropertyName("userid_list")] |
|||
public List<string> UserIds { get; } |
|||
/// <summary>
|
|||
/// 用于分页查询的游标,字符串类型,由上一次调用返回,首次调用可不填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("cursor")] |
|||
[JsonPropertyName("cursor")] |
|||
public string? Cursor { get; } |
|||
/// <summary>
|
|||
/// 返回的最大记录数,整型,最大值100,默认值50,超过最大值时取最大值
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("limit")] |
|||
[JsonPropertyName("limit")] |
|||
public int Limit { get; } |
|||
public WeChatWorkBulkGetCustomerRequest( |
|||
List<string> userIds, |
|||
string? cursor = null, |
|||
int limit = 50) |
|||
{ |
|||
Check.NotNullOrEmpty(userIds, nameof(userIds)); |
|||
Check.Range(limit, nameof(limit), 1, 100); |
|||
|
|||
if (userIds.Count > 100) |
|||
{ |
|||
throw new ArgumentException("The maximum number of userIds allowed in the list is only 100!"); |
|||
} |
|||
|
|||
UserIds = userIds; |
|||
Cursor = cursor; |
|||
Limit = limit; |
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
using Newtonsoft.Json; |
|||
using System; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
/// <summary>
|
|||
/// 批量获取客户详情请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92994" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkCreateCustomerStrategyRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 父规则组id
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("parent_id")] |
|||
[JsonPropertyName("parent_id")] |
|||
public int? ParentId { get; set; } |
|||
/// <summary>
|
|||
/// 规则组名称
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy_name")] |
|||
[JsonPropertyName("strategy_name")] |
|||
public string StrategyName { get; } |
|||
/// <summary>
|
|||
/// 规则组管理员userid列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("admin_list")] |
|||
[JsonPropertyName("admin_list")] |
|||
public string[] AdminList { get; } |
|||
/// <summary>
|
|||
/// 规则组权限
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("privilege")] |
|||
[JsonPropertyName("privilege")] |
|||
public CustomerStrategyPrivilege Privilege { get; } |
|||
/// <summary>
|
|||
/// 规则组管理范围
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("range")] |
|||
[JsonPropertyName("range")] |
|||
public CustomerStrategyRange[] Range { get; } |
|||
public WeChatWorkCreateCustomerStrategyRequest( |
|||
string strategyName, |
|||
string[] adminList, |
|||
CustomerStrategyPrivilege? privilege = null, |
|||
CustomerStrategyRange[]? range = null) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(strategyName, nameof(strategyName)); |
|||
Check.NotNullOrEmpty(adminList, nameof(adminList)); |
|||
|
|||
if (adminList.Length > 20) |
|||
{ |
|||
throw new ArgumentException("Up to 20 admin list can be configured at a time!"); |
|||
} |
|||
if (range != null && range.Length > 100) |
|||
{ |
|||
throw new ArgumentException("Up to 100 management range can be configured at a time!"); |
|||
} |
|||
|
|||
StrategyName = strategyName; |
|||
AdminList = adminList; |
|||
Privilege = privilege ?? CustomerStrategyPrivilege.Default(); |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
/// <summary>
|
|||
/// 删除规则组请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E5%88%A0%E9%99%A4%E8%A7%84%E5%88%99%E7%BB%84" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkDeleteCustomerStrategyRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 规则组id
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy_id")] |
|||
[JsonPropertyName("strategy_id")] |
|||
public int StrategyId { get; } |
|||
public WeChatWorkDeleteCustomerStrategyRequest(int strategyId) |
|||
{ |
|||
Check.NotDefaultOrNull<int>(strategyId, nameof(strategyId)); |
|||
|
|||
StrategyId = strategyId; |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
/// <summary>
|
|||
/// 获取规则组列表请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E5%88%97%E8%A1%A8" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetCustomerStrategyListRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 分页查询游标,首次调用可不填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("cursor")] |
|||
[JsonPropertyName("cursor")] |
|||
public string? Cursor { get; } |
|||
/// <summary>
|
|||
/// 分页大小,默认为1000,最大不超过1000
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("limit")] |
|||
[JsonPropertyName("limit")] |
|||
public int? Limit { get; } |
|||
public WeChatWorkGetCustomerStrategyListRequest(string? cursor = null, int? limit = 1000) |
|||
{ |
|||
if (limit.HasValue) |
|||
{ |
|||
Check.Range(limit.Value, nameof(limit), 1, 1000); |
|||
} |
|||
|
|||
Cursor = cursor; |
|||
Limit = limit; |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
/// <summary>
|
|||
/// 获取规则组管理范围请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetCustomerStrategyRangeRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 规则组id
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy_id")] |
|||
[JsonPropertyName("strategy_id")] |
|||
public int StrategyId { get; } |
|||
/// <summary>
|
|||
/// 分页查询游标,首次调用可不填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("cursor")] |
|||
[JsonPropertyName("cursor")] |
|||
public string? Cursor { get; } |
|||
/// <summary>
|
|||
/// 每个分页的成员/部门节点数,默认为1000,最大为1000
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("limit")] |
|||
[JsonPropertyName("limit")] |
|||
public int? Limit { get; } |
|||
public WeChatWorkGetCustomerStrategyRangeRequest(int strategyId, string? cursor = null, int? limit = 1000) |
|||
{ |
|||
if (limit.HasValue) |
|||
{ |
|||
Check.Range(limit.Value, nameof(limit), 1, 1000); |
|||
} |
|||
|
|||
StrategyId = strategyId; |
|||
Cursor = cursor; |
|||
Limit = limit; |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
/// <summary>
|
|||
/// 获取规则组请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E8%AF%A6%E6%83%85" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetCustomerStrategyRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 规则组id
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy_id")] |
|||
[JsonPropertyName("strategy_id")] |
|||
public int StrategyId { get; } |
|||
public WeChatWorkGetCustomerStrategyRequest(int strategyId) |
|||
{ |
|||
StrategyId = strategyId; |
|||
} |
|||
} |
|||
@ -0,0 +1,86 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
/// <summary>
|
|||
/// 修改客户备注信息请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92115" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkUpdateCustomerRemarkRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 企业成员的userid
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("userid")] |
|||
[JsonPropertyName("userid")] |
|||
public string UserId { get; } |
|||
/// <summary>
|
|||
/// 外部联系人userid
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("external_userid")] |
|||
[JsonPropertyName("external_userid")] |
|||
public string ExternalUserId { get; } |
|||
/// <summary>
|
|||
/// 此用户对外部联系人的备注,最多20个字符
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[StringLength(20)] |
|||
[JsonProperty("remark")] |
|||
[JsonPropertyName("remark")] |
|||
public string? Remark { get; } |
|||
/// <summary>
|
|||
/// 此用户对外部联系人的描述,最多150个字符
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[StringLength(150)] |
|||
[JsonProperty("description")] |
|||
[JsonPropertyName("description")] |
|||
public string? Description { get; } |
|||
/// <summary>
|
|||
/// 此用户对外部联系人备注的所属公司名称,最多20个字符
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[StringLength(20)] |
|||
[JsonProperty("remark_company")] |
|||
[JsonPropertyName("remark_company")] |
|||
public string? RemarkCompany { get; } |
|||
/// <summary>
|
|||
/// 此用户对外部联系人备注的手机号
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("remark_mobiles")] |
|||
[JsonPropertyName("remark_mobiles")] |
|||
public List<string>? RemarkMobiles { get; } |
|||
/// <summary>
|
|||
/// 备注图片的mediaid
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("remark_pic_mediaid")] |
|||
[JsonPropertyName("remark_pic_mediaid")] |
|||
public string? RemarkPictureMediaId { get; } |
|||
public WeChatWorkUpdateCustomerRemarkRequest( |
|||
string userId, |
|||
string externalUserId, |
|||
string? remark = null, |
|||
string? description = null, |
|||
string? remarkCompany = null, |
|||
List<string>? remarkMobiles = null, |
|||
string? remarkPictureMediaId = null) |
|||
{ |
|||
UserId = Check.NotNullOrWhiteSpace(userId, nameof(userId)); |
|||
ExternalUserId = Check.NotNullOrWhiteSpace(externalUserId, nameof(externalUserId)); |
|||
Remark = Check.Length(remark, nameof(remark), 20); |
|||
Description = Check.Length(description, nameof(description), 150); |
|||
RemarkCompany = Check.Length(remarkCompany, nameof(remarkCompany), 20); |
|||
RemarkMobiles = remarkMobiles; |
|||
RemarkPictureMediaId = remarkPictureMediaId; |
|||
} |
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
/// <summary>
|
|||
/// 编辑规则组及其管理范围请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E7%BC%96%E8%BE%91%E8%A7%84%E5%88%99%E7%BB%84%E5%8F%8A%E5%85%B6%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkUpdateCustomerStrategyRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 规则组id
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy_id")] |
|||
[JsonPropertyName("strategy_id")] |
|||
public int StrategyId { get; } |
|||
/// <summary>
|
|||
/// 规则组名称
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("strategy_name")] |
|||
[JsonPropertyName("strategy_name")] |
|||
public string? StrategyName { get; set; } |
|||
/// <summary>
|
|||
/// 规则组管理员userid列表
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("admin_list")] |
|||
[JsonPropertyName("admin_list")] |
|||
public string[]? AdminList { get; set; } |
|||
/// <summary>
|
|||
/// 规则组权限
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("privilege")] |
|||
[JsonPropertyName("privilege")] |
|||
public CustomerStrategyPrivilege? Privilege { get; set; } |
|||
/// <summary>
|
|||
/// 新增管理范围
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("range_add")] |
|||
[JsonPropertyName("range_add")] |
|||
public List<CustomerStrategyRange> CreateRange { get; private set; } |
|||
/// <summary>
|
|||
/// 删除管理范围
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("range_del")] |
|||
[JsonPropertyName("range_del")] |
|||
public List<CustomerStrategyRange> DeleteRange { get; private set; } |
|||
public WeChatWorkUpdateCustomerStrategyRequest( |
|||
int strategyId, |
|||
string? strategyName = null, |
|||
string[]? adminList = null, |
|||
CustomerStrategyPrivilege? privilege = null) |
|||
{ |
|||
Check.NotDefaultOrNull<int>(strategyId, nameof(strategyId)); |
|||
|
|||
StrategyId = strategyId; |
|||
StrategyName = strategyName; |
|||
AdminList = adminList; |
|||
Privilege = privilege; |
|||
|
|||
CreateRange = new List<CustomerStrategyRange>(); |
|||
DeleteRange = new List<CustomerStrategyRange>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
/// <summary>
|
|||
/// 批量获取客户详情响应参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92994" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkBulkGetCustomerResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 外部联系人的userid列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("external_contact_list")] |
|||
[JsonPropertyName("external_contact_list")] |
|||
public List<ExternalContactList> ExternalUserId { get; set; } = new List<ExternalContactList>(); |
|||
/// <summary>
|
|||
/// 分页游标,再下次请求时填写以获取之后分页的记录,如果已经没有更多的数据则返回空
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("next_cursor")] |
|||
[JsonPropertyName("next_cursor")] |
|||
public string? NextCursor { get; set; } |
|||
/// <summary>
|
|||
/// 若请求中所有userid都无有效互通许可,接口直接报错701008。如果部分userid无有效互通许可,接口返回成功
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("fail_info")] |
|||
[JsonPropertyName("fail_info")] |
|||
public WeChatWorkBulkGetCustomerFailInfo? FailInfo { get; set; } |
|||
} |
|||
|
|||
public class WeChatWorkBulkGetCustomerFailInfo |
|||
{ |
|||
/// <summary>
|
|||
/// 无许可的userid列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("next_cursor")] |
|||
[JsonPropertyName("next_cursor")] |
|||
public List<string> UnlicensedUseridList { get; set; } = new List<string>(); |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
/// <summary>
|
|||
/// 创建新的规则组响应参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkCreateCustomerStrategyResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 规则组id
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy_id")] |
|||
[JsonPropertyName("strategy_id")] |
|||
public int StrategyId { get; set; } |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
/// <summary>
|
|||
/// 获取客户列表响应参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92113" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetCustomerListResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 外部联系人的userid列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("external_userid")] |
|||
[JsonPropertyName("external_userid")] |
|||
public List<string> ExternalUserId { get; set; } = new List<string>(); |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
/// <summary>
|
|||
/// 获取客户详情响应参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92114" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetCustomerResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 外部联系人信息
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("external_contact")] |
|||
[JsonPropertyName("external_contact")] |
|||
public ExternalContactInfo ExternalContact { get; set; } |
|||
/// <summary>
|
|||
/// 添加了此外部联系人的企业成员
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("follow_user")] |
|||
[JsonPropertyName("follow_user")] |
|||
public List<FollowUser> FollowUser { get; set; } |
|||
/// <summary>
|
|||
/// 分页的cursor,当跟进人多于500人时返回
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("next_cursor")] |
|||
[JsonPropertyName("next_cursor")] |
|||
public string? NextCursor { get; set; } |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
/// <summary>
|
|||
/// 获取规则组列表响应参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetCustomerStrategyListResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 规则组列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy")] |
|||
[JsonPropertyName("strategy")] |
|||
public CustomerStrategy[] Strategy { get; set; } |
|||
/// <summary>
|
|||
/// 分页游标,用于查询下一个分页的数据,无更多数据时不返回
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("next_cursor")] |
|||
[JsonPropertyName("next_cursor")] |
|||
public string? NextCursor { get; set; } |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
/// <summary>
|
|||
/// 获取规则组管理范围响应参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetCustomerStrategyRangeResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 规则组管理范围
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("range")] |
|||
[JsonPropertyName("range")] |
|||
public CustomerStrategyRange[] Range { get; set; } |
|||
/// <summary>
|
|||
/// 分页游标,用于查询下一个分页的数据,无更多数据时不返回
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("next_cursor")] |
|||
[JsonPropertyName("next_cursor")] |
|||
public string? NextCursor { get; set; } |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
/// <summary>
|
|||
/// 获取规则组详情响应参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetCustomerStrategyResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 规则组详情
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("strategy")] |
|||
[JsonPropertyName("strategy")] |
|||
public CustomerStrategyInfo Strategy { get; set; } |
|||
} |
|||
@ -0,0 +1,93 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features; |
|||
using LINGYUN.Abp.WeChat.Work.Token; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System.Net.Http; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers; |
|||
|
|||
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)] |
|||
public class WeChatWorkCustomerProvider : IWeChatWorkCustomerProvider, ISingletonDependency |
|||
{ |
|||
protected IHttpClientFactory HttpClientFactory { get; } |
|||
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
|||
|
|||
public WeChatWorkCustomerProvider( |
|||
IHttpClientFactory httpClientFactory, |
|||
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
|||
{ |
|||
HttpClientFactory = httpClientFactory; |
|||
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkGetCustomerListResponse> GetCustomerListAsync( |
|||
string userId, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(userId, nameof(userId)); |
|||
|
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.GetCustomerListAsync(token.AccessToken, userId, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerListResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkBulkGetCustomerResponse> BulkGetCustomerAsync( |
|||
WeChatWorkBulkGetCustomerRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
Check.NotNull(request, nameof(request)); |
|||
|
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.BulkGetCustomerAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkBulkGetCustomerResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkGetCustomerResponse> GetCustomerAsync( |
|||
string externalUserid, |
|||
string? cursor = null, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(externalUserid, nameof(externalUserid)); |
|||
|
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.GetCustomerAsync(token.AccessToken, externalUserid, cursor, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkResponse> UpdateCustomerRemarkAsync( |
|||
WeChatWorkUpdateCustomerRemarkRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
Check.NotNull(request, nameof(request)); |
|||
|
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.UpdateCustomerRemarkAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
} |
|||
@ -0,0 +1,111 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features; |
|||
using LINGYUN.Abp.WeChat.Work.Token; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System.Net.Http; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers; |
|||
|
|||
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)] |
|||
public class WeChatWorkCustomerStrategyProvider : IWeChatWorkCustomerStrategyProvider, ISingletonDependency |
|||
{ |
|||
protected IHttpClientFactory HttpClientFactory { get; } |
|||
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
|||
|
|||
public WeChatWorkCustomerStrategyProvider( |
|||
IHttpClientFactory httpClientFactory, |
|||
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
|||
{ |
|||
HttpClientFactory = httpClientFactory; |
|||
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkGetCustomerStrategyListResponse> GetCustomerStrategyListAsync( |
|||
WeChatWorkGetCustomerStrategyListRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.GetCustomerStrategyListAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerStrategyListResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkGetCustomerStrategyResponse> GetCustomerStrategyAsync( |
|||
WeChatWorkGetCustomerStrategyRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.GetCustomerStrategyAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerStrategyResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkGetCustomerStrategyRangeResponse> GetCustomerStrategyRangeAsync( |
|||
WeChatWorkGetCustomerStrategyRangeRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.GetCustomerStrategyRangeAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerStrategyRangeResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkCreateCustomerStrategyResponse> CreateCustomerStrategyAsync( |
|||
WeChatWorkCreateCustomerStrategyRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.CreateCustomerStrategyAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkCreateCustomerStrategyResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkResponse> UpdateCustomerStrategyAsync( |
|||
WeChatWorkUpdateCustomerStrategyRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.UpdateCustomerStrategyAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkResponse> DeleteCustomerStrategyAsync( |
|||
WeChatWorkDeleteCustomerStrategyRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.DeleteCustomerStrategyAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Features; |
|||
using LINGYUN.Abp.WeChat.Work.Localization; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Validation.StringValues; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Features; |
|||
public class WeChatWorkExternalContactFeatureDefinitionProvider : FeatureDefinitionProvider |
|||
{ |
|||
public override void Define(IFeatureDefinitionContext context) |
|||
{ |
|||
var weChatFeature = context.GetGroupOrNull(WeChatWorkFeatureNames.GroupName); |
|||
if (weChatFeature == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var group = weChatFeature.AddFeature(WeChatWorkExternalContactFeatureNames.GroupName); |
|||
group.CreateChild( |
|||
WeChatWorkExternalContactFeatureNames.Enable, |
|||
defaultValue: "false", |
|||
displayName: L("Features:ExternalContactEnable"), |
|||
description: L("Features:ExternalContactEnableDesc"), |
|||
valueType: new ToggleStringValueType(new BooleanValueValidator())); |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<WeChatWorkResource>(name); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Features; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Features; |
|||
/// <summary>
|
|||
/// 企业微信客户联系模块功能
|
|||
/// </summary>
|
|||
public static class WeChatWorkExternalContactFeatureNames |
|||
{ |
|||
public const string GroupName = WeChatWorkFeatureNames.GroupName + ".ExternalContact"; |
|||
/// <summary>
|
|||
/// 启用企业微信客户联系
|
|||
/// </summary>
|
|||
public const string Enable = GroupName + ".Enable"; |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Follows.Response; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Follows; |
|||
/// <summary>
|
|||
/// 企业服务人员管理接口
|
|||
/// </summary>
|
|||
public interface IWeChatWorkFollowUserProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 获取配置了客户联系功能的成员列表
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92571" />
|
|||
/// </remarks>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkGetFollowUserListResponse> GetFollowUserListAsync(CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Follows.Response; |
|||
/// <summary>
|
|||
/// 获取配置了客户联系功能的成员列表响应参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/91853" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetFollowUserListResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 配置了客户联系功能的成员userid列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("follow_user")] |
|||
[JsonPropertyName("follow_user")] |
|||
public List<string> FollowUser { get; set; } = new List<string>(); |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Follows.Response; |
|||
using LINGYUN.Abp.WeChat.Work.Token; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System.Net.Http; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Follows; |
|||
|
|||
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)] |
|||
public class WeChatWorkFollowUserProvider : IWeChatWorkFollowUserProvider, ISingletonDependency |
|||
{ |
|||
protected IHttpClientFactory HttpClientFactory { get; } |
|||
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
|||
|
|||
public WeChatWorkFollowUserProvider( |
|||
IHttpClientFactory httpClientFactory, |
|||
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
|||
{ |
|||
HttpClientFactory = httpClientFactory; |
|||
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkGetFollowUserListResponse> GetFollowUserListAsync(CancellationToken cancellationToken = default) |
|||
{ |
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.GetFollowUserListAsync(token.AccessToken, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetFollowUserListResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats; |
|||
/// <summary>
|
|||
/// 客户群管理接口
|
|||
/// </summary>
|
|||
public interface IWeChatWorkGroupChatProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 获取客户群列表
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92120" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkGetGroupChatListResponse> GetGroupChatListAsync( |
|||
WeChatWorkGetGroupChatListRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 获取客户群详情
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92122" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkGetGroupChatResponse> GetGroupChatAsync( |
|||
WeChatWorkGetGroupChatRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
/// <summary>
|
|||
/// 客户群opengid转换
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94822" />
|
|||
/// </remarks>
|
|||
/// <param name="request">请求参数</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<WeChatWorkOpengIdToChatIdResponse> OpengIdToChatIdAsync( |
|||
WeChatWorkOpengIdToChatIdRequest request, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 客户群
|
|||
/// </summary>
|
|||
public class GroupChat |
|||
{ |
|||
/// <summary>
|
|||
/// 客户群ID
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("chat_id")] |
|||
[JsonPropertyName("chat_id")] |
|||
public string ChatId { get; set; } |
|||
/// <summary>
|
|||
/// 客户群跟进状态
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("status")] |
|||
[JsonPropertyName("status")] |
|||
public GroupChatStatus Status { get; set; } |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 客户群详情
|
|||
/// </summary>
|
|||
public class GroupChatInfo |
|||
{ |
|||
/// <summary>
|
|||
/// 客户群ID
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("chat_id")] |
|||
[JsonPropertyName("chat_id")] |
|||
public string ChatId { get; set; } |
|||
/// <summary>
|
|||
/// 群名
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("name")] |
|||
[JsonPropertyName("name")] |
|||
public string Name { get; set; } |
|||
/// <summary>
|
|||
/// 群主ID
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("owner")] |
|||
[JsonPropertyName("owner")] |
|||
public string Owner { get; set; } |
|||
/// <summary>
|
|||
/// 群的创建时间
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("create_time")] |
|||
[JsonPropertyName("create_time")] |
|||
public long CreateTime { get; set; } |
|||
/// <summary>
|
|||
/// 群公告
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("notice")] |
|||
[JsonPropertyName("notice")] |
|||
public string Notice { get; set; } |
|||
/// <summary>
|
|||
/// 群成员列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("member_list")] |
|||
[JsonPropertyName("member_list")] |
|||
public GroupChatMember[] MemberList { get; set; } |
|||
/// <summary>
|
|||
/// 群管理员列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("admin_list")] |
|||
[JsonPropertyName("admin_list")] |
|||
public GroupChatManager[] AdminList { get; set; } |
|||
/// <summary>
|
|||
/// 当前群成员版本号。可以配合客户群变更事件减少主动调用本接口的次数
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("member_version")] |
|||
[JsonPropertyName("member_version")] |
|||
public string MemberVersion { get; set; } |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 邀请者
|
|||
/// </summary>
|
|||
public class GroupChatInvitor |
|||
{ |
|||
/// <summary>
|
|||
/// 邀请者的userid
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("userid")] |
|||
[JsonPropertyName("userid")] |
|||
public string UserId { get; set; } |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 群管理员
|
|||
/// </summary>
|
|||
public class GroupChatManager |
|||
{ |
|||
/// <summary>
|
|||
/// 群管理员userid
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("userid")] |
|||
[JsonPropertyName("userid")] |
|||
public string UserId { get; set; } |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 群成员
|
|||
/// </summary>
|
|||
public class GroupChatMember |
|||
{ |
|||
/// <summary>
|
|||
/// 群成员id
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("userid")] |
|||
[JsonPropertyName("userid")] |
|||
public string UserId { get; set; } |
|||
/// <summary>
|
|||
/// 成员类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public GroupChatMemberType Type { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人在微信开放平台的唯一身份标识(微信unionid),通过此字段企业可将外部联系人与公众号/小程序用户关联起来。<br />
|
|||
/// 仅当群成员类型是微信用户(包括企业成员未添加好友),且企业绑定了微信开发者ID有此字段
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("unionid")] |
|||
[JsonPropertyName("unionid")] |
|||
public string? UnionId { get; set; } |
|||
/// <summary>
|
|||
/// 入群时间
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("join_time")] |
|||
[JsonPropertyName("join_time")] |
|||
public long JoinTime { get; set; } |
|||
/// <summary>
|
|||
/// 入群方式
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("join_scene")] |
|||
[JsonPropertyName("join_scene")] |
|||
public GroupChatMemberJoinScene JoinScene { get; set; } |
|||
/// <summary>
|
|||
/// 邀请者。目前仅当是由本企业内部成员邀请入群时会返回该值
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("invitor")] |
|||
[JsonPropertyName("invitor")] |
|||
public GroupChatInvitor? Invitor { get; set; } |
|||
/// <summary>
|
|||
/// 在群里的昵称
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("group_nickname")] |
|||
[JsonPropertyName("group_nickname")] |
|||
public string? GroupNickname { get; set; } |
|||
/// <summary>
|
|||
/// 名字。仅当 need_name = 1 时返回<br />
|
|||
/// 如果是微信用户,则返回其在微信中设置的名字<br />
|
|||
/// 如果是企业微信联系人,则返回其设置对外展示的别名或实名
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("name")] |
|||
[JsonPropertyName("name")] |
|||
public string? Name { get; set; } |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 入群方式
|
|||
/// </summary>
|
|||
[Description("入群方式")] |
|||
public enum GroupChatMemberJoinScene |
|||
{ |
|||
/// <summary>
|
|||
/// 由群成员邀请入群(直接邀请入群)
|
|||
/// </summary>
|
|||
[Description("直接邀请入群")] |
|||
DirectInvitation = 1, |
|||
/// <summary>
|
|||
/// 由群成员邀请入群(通过邀请链接入群)
|
|||
/// </summary>
|
|||
[Description("通过邀请链接入群")] |
|||
InvitationLink = 2, |
|||
/// <summary>
|
|||
/// 通过扫描群二维码入群
|
|||
/// </summary>
|
|||
[Description("通过扫描群二维码入群")] |
|||
ScanQrCode = 3, |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 成员类型
|
|||
/// </summary>
|
|||
[Description("成员类型")] |
|||
public enum GroupChatMemberType |
|||
{ |
|||
/// <summary>
|
|||
/// 企业成员
|
|||
/// </summary>
|
|||
[Description("企业成员")] |
|||
Internal = 1, |
|||
/// <summary>
|
|||
/// 外部联系人
|
|||
/// </summary>
|
|||
[Description("外部联系人")] |
|||
External = 2 |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 客户群跟进状态
|
|||
/// </summary>
|
|||
[Description("客户群跟进状态")] |
|||
public enum GroupChatStatus |
|||
{ |
|||
/// <summary>
|
|||
/// 跟进人正常
|
|||
/// </summary>
|
|||
[Description("跟进人正常")] |
|||
Normal = 0, |
|||
/// <summary>
|
|||
/// 跟进人离职
|
|||
/// </summary>
|
|||
[Description("跟进人离职")] |
|||
Leaves = 1, |
|||
/// <summary>
|
|||
/// 离职继承中
|
|||
/// </summary>
|
|||
[Description("离职继承中")] |
|||
Resiging = 2, |
|||
/// <summary>
|
|||
/// 离职继承完成
|
|||
/// </summary>
|
|||
[Description(" 离职继承完成")] |
|||
ResignCompleted = 3, |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 群主过滤
|
|||
/// </summary>
|
|||
public class OwnerFilter |
|||
{ |
|||
/// <summary>
|
|||
/// 用户ID列表。最多100个
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("userid_list")] |
|||
[JsonPropertyName("userid_list")] |
|||
public string[] UserIdList { get; } |
|||
public OwnerFilter(string[] userIdList) |
|||
{ |
|||
Check.NotNullOrEmpty(userIdList, nameof(userIdList)); |
|||
|
|||
if (userIdList.Length > 100) |
|||
{ |
|||
throw new ArgumentException("The maximum number of parameters allowed for group owner filtering is only 100!"); |
|||
} |
|||
|
|||
UserIdList = userIdList; |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
/// <summary>
|
|||
/// 客户群跟进状态过滤
|
|||
/// </summary>
|
|||
[Description("客户群跟进状态过滤")] |
|||
public enum StatusFilter |
|||
{ |
|||
/// <summary>
|
|||
/// 所有列表
|
|||
/// </summary>
|
|||
[Description("所有列表")] |
|||
All = 0, |
|||
/// <summary>
|
|||
/// 跟进人离职
|
|||
/// </summary>
|
|||
[Description("跟进人离职")] |
|||
Leaves = 1, |
|||
/// <summary>
|
|||
/// 离职继承中
|
|||
/// </summary>
|
|||
[Description("离职继承中")] |
|||
Resiging = 2, |
|||
/// <summary>
|
|||
/// 离职继承完成
|
|||
/// </summary>
|
|||
[Description(" 离职继承完成")] |
|||
ResignCompleted = 3, |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request; |
|||
/// <summary>
|
|||
/// 获取客户群列表请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92120" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetGroupChatListRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 客户群跟进状态过滤
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("status_filter")] |
|||
[JsonPropertyName("status_filter")] |
|||
public StatusFilter? StatusFilter { get; set; } |
|||
/// <summary>
|
|||
/// 客户群跟进状态过滤
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("owner_filter")] |
|||
[JsonPropertyName("owner_filter")] |
|||
public OwnerFilter[]? OwnerFilter { get; set; } |
|||
/// <summary>
|
|||
/// 用于分页查询的游标,字符串类型,由上一次调用返回,首次调用不填
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("cursor")] |
|||
[JsonPropertyName("cursor")] |
|||
public string? Cursor { get; set; } |
|||
/// <summary>
|
|||
/// 分页,预期请求的数据量,取值范围 1 ~ 1000
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("limit")] |
|||
[JsonPropertyName("limit")] |
|||
public int Limit { get; } |
|||
public WeChatWorkGetGroupChatListRequest(int limit = 1000) |
|||
{ |
|||
Check.Range(limit, nameof(limit), 1, 1000); |
|||
|
|||
Limit = limit; |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request; |
|||
/// <summary>
|
|||
/// 获取客户群详情
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92122" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetGroupChatRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 客户群ID
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("chat_id")] |
|||
[JsonPropertyName("chat_id")] |
|||
public string ChatId { get; } |
|||
/// <summary>
|
|||
/// 是否需要返回群成员的名字group_chat.member_list.name。0-不返回;1-返回。默认不返回
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("need_name")] |
|||
[JsonPropertyName("need_name")] |
|||
public int? NeedName { get; } |
|||
public WeChatWorkGetGroupChatRequest(string chatId, bool needName = false) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(chatId, nameof(chatId)); |
|||
|
|||
ChatId = chatId; |
|||
NeedName = needName ? 1 : 0; |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request; |
|||
/// <summary>
|
|||
/// 客户群opengid转换请求参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94822" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkOpengIdToChatIdRequest : WeChatWorkRequest |
|||
{ |
|||
/// <summary>
|
|||
/// 小程序在微信获取到的群ID
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("opengid")] |
|||
[JsonPropertyName("opengid")] |
|||
public string OpengId { get; } |
|||
public WeChatWorkOpengIdToChatIdRequest(string opengId) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(opengId, nameof(opengId)); |
|||
|
|||
OpengId = opengId; |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response; |
|||
/// <summary>
|
|||
/// 获取客户群列表响应结果
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92120" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetGroupChatListResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 客户群列表
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("group_chat_list")] |
|||
[JsonPropertyName("group_chat_list")] |
|||
public GroupChat[] GroupChatList { get; set; } |
|||
/// <summary>
|
|||
/// 分页游标,下次请求时填写以获取之后分页的记录。如果该字段返回空则表示已没有更多数据
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
[JsonProperty("next_cursor")] |
|||
[JsonPropertyName("next_cursor")] |
|||
public string? NextCursor { get; set; } |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response; |
|||
/// <summary>
|
|||
/// 获取客户群详情响应结果
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92122" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkGetGroupChatResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 客户群详情
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("group_chat")] |
|||
[JsonPropertyName("group_chat")] |
|||
public GroupChatInfo GroupChat { get; set; } |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response; |
|||
/// <summary>
|
|||
/// 客户群opengid转换响应结果
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94822" />
|
|||
/// </remarks>
|
|||
public class WeChatWorkOpengIdToChatIdResponse : WeChatWorkResponse |
|||
{ |
|||
/// <summary>
|
|||
/// 客户群ID,可以用来调用获取客户群详情
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("chat_id")] |
|||
[JsonPropertyName("chat_id")] |
|||
public string ChatId { get; set; } |
|||
} |
|||
@ -0,0 +1,76 @@ |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request; |
|||
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response; |
|||
using LINGYUN.Abp.WeChat.Work.Token; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System.Net.Http; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats; |
|||
|
|||
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)] |
|||
public class WeChatWorkGroupChatProvider : IWeChatWorkGroupChatProvider, ISingletonDependency |
|||
{ |
|||
protected IHttpClientFactory HttpClientFactory { get; } |
|||
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
|||
|
|||
public WeChatWorkGroupChatProvider( |
|||
IHttpClientFactory httpClientFactory, |
|||
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
|||
{ |
|||
HttpClientFactory = httpClientFactory; |
|||
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkGetGroupChatListResponse> GetGroupChatListAsync( |
|||
WeChatWorkGetGroupChatListRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
Check.NotNull(request, nameof(request)); |
|||
|
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.GetGroupChatListAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetGroupChatListResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkGetGroupChatResponse> GetGroupChatAsync( |
|||
WeChatWorkGetGroupChatRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
Check.NotNull(request, nameof(request)); |
|||
|
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.GetGroupChatAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetGroupChatResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
|
|||
public async virtual Task<WeChatWorkOpengIdToChatIdResponse> OpengIdToChatIdAsync( |
|||
WeChatWorkOpengIdToChatIdRequest request, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
Check.NotNull(request, nameof(request)); |
|||
|
|||
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
|||
var client = HttpClientFactory.CreateWeChatWorkApiClient(); |
|||
|
|||
using var response = await client.OpengIdToChatIdAsync(token.AccessToken, request, cancellationToken); |
|||
|
|||
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkOpengIdToChatIdResponse>(); |
|||
wechatResponse.ThrowIfNotSuccess(); |
|||
return wechatResponse; |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Features:ExternalContactEnable": "Enable External Contact", |
|||
"Features:ExternalContactEnableDesc": "Enable the ability to provide the application with an Enterprise wechat customer contact interface." |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Features:ExternalContactEnable": "启用客户联系", |
|||
"Features:ExternalContactEnableDesc": "启用以使应用拥有企业微信客户联系接口的能力." |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using System.Xml.Serialization; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群成员退群事件推送
|
|||
/// </summary>
|
|||
[EventName("external_chat_del_member")] |
|||
public class ExternalChaDelMemberEvent : ExternalChatChangeMemberEvent |
|||
{ |
|||
/// <summary>
|
|||
/// 当是成员退群时有值。表示成员的退群方式<br />
|
|||
/// 0 - 自己退群<br />
|
|||
/// 1 - 群主/群管理员移出<br />
|
|||
/// </summary>
|
|||
[XmlElement("QuitScene")] |
|||
public ExternalChatMemberQuitScene QuitScene { get; set; } |
|||
|
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalChaDelMemberEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using System.Xml.Serialization; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群成员入群事件推送
|
|||
/// </summary>
|
|||
[EventName("external_chat_add_member")] |
|||
public class ExternalChatAddMemberEvent : ExternalChatChangeMemberEvent |
|||
{ |
|||
/// <summary>
|
|||
/// 当是成员入群时有值。表示成员的入群方式<br />
|
|||
/// 0 - 由成员邀请入群(包括直接邀请入群和通过邀请链接入群)<br />
|
|||
/// 3 - 通过扫描群二维码入群<br />
|
|||
/// </summary>
|
|||
[XmlElement("JoinScene")] |
|||
public ExternalChatMemberJoinScene JoinScene { get; set; } |
|||
|
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalChatAddMemberEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using System.Xml.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群变更事件推送
|
|||
/// </summary>
|
|||
public abstract class ExternalChatChangeEvent : WeChatWorkEventMessage |
|||
{ |
|||
/// <summary>
|
|||
/// 变更类型
|
|||
/// </summary>
|
|||
[XmlElement("ChangeType")] |
|||
public string ChangeType { get; set; } |
|||
/// <summary>
|
|||
/// 群ID
|
|||
/// </summary>
|
|||
[XmlElement("ChatId")] |
|||
public string ChatId { get; set; } |
|||
} |
|||
|
|||
@ -0,0 +1,39 @@ |
|||
using System.Collections.Generic; |
|||
using System.Xml.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群成员变更事件推送
|
|||
/// </summary>
|
|||
public abstract class ExternalChatChangeMemberEvent : ExternalChatUpdateEvent |
|||
{ |
|||
/// <summary>
|
|||
/// 成员变更数量
|
|||
/// </summary>
|
|||
[XmlElement("MemChangeCnt")] |
|||
public int MemChangeCnt { get; set; } |
|||
/// <summary>
|
|||
/// 变更的成员列表
|
|||
/// </summary>
|
|||
[XmlElement("MemChangeList")] |
|||
public List<ExternalChatChangeMember> MemChangeList { get; set; } = new List<ExternalChatChangeMember>(); |
|||
/// <summary>
|
|||
/// 变更前的群成员版本号
|
|||
/// </summary>
|
|||
[XmlElement("LastMemVer")] |
|||
public string LastMemVer { get; set; } |
|||
/// <summary>
|
|||
/// 变更后的群成员版本号
|
|||
/// </summary>
|
|||
[XmlElement("CurMemVer")] |
|||
public string CurMemVer { get; set; } |
|||
} |
|||
|
|||
public class ExternalChatChangeMember |
|||
{ |
|||
/// <summary>
|
|||
/// 成员Id
|
|||
/// </summary>
|
|||
[XmlElement("Item")] |
|||
public string UserId { get; set; } |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群群名变更事件推送
|
|||
/// </summary>
|
|||
[EventName("external_chat_change_name")] |
|||
public class ExternalChatChangeNameEvent : ExternalChatUpdateEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalChatChangeNameEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群群公告变更事件推送
|
|||
/// </summary>
|
|||
[EventName("external_chat_change_notice")] |
|||
public class ExternalChatChangeNoticeEvent : ExternalChatUpdateEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalChatChangeNoticeEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群群主变更事件推送
|
|||
/// </summary>
|
|||
[EventName("external_chat_change_owner")] |
|||
public class ExternalChatChangeOwnerEvent : ExternalChatUpdateEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalChatChangeOwnerEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群创建事件推送
|
|||
/// </summary>
|
|||
[EventName("external_chat_create")] |
|||
public class ExternalChatCreateEvent : ExternalChatChangeEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalChatCreateEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群解散事件推送
|
|||
/// </summary>
|
|||
[EventName("external_chat_dismiss")] |
|||
public class ExternalChatDismissEvent : ExternalChatChangeEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalChatDismissEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 成员的入群方式
|
|||
/// </summary>
|
|||
[Description("成员的入群方式")] |
|||
public enum ExternalChatMemberJoinScene |
|||
{ |
|||
/// <summary>
|
|||
/// 由成员邀请入群
|
|||
/// </summary>
|
|||
[Description("由成员邀请入群")] |
|||
MemberInvitation = 0, |
|||
/// <summary>
|
|||
/// 通过扫描群二维码入群
|
|||
/// </summary>
|
|||
[Description("通过扫描群二维码入群")] |
|||
ScanQrCode = 3 |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.ComponentModel; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 成员的退群方式
|
|||
/// </summary>
|
|||
[Description("成员的退群方式")] |
|||
public enum ExternalChatMemberQuitScene |
|||
{ |
|||
/// <summary>
|
|||
/// 自己退群
|
|||
/// </summary>
|
|||
[Description("自己退群")] |
|||
UserSelf = 0, |
|||
/// <summary>
|
|||
/// 群主/群管理员移出
|
|||
/// </summary>
|
|||
[Description("群主/群管理员移出")] |
|||
Admin = 1 |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.Xml.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户群变更事件推送
|
|||
/// </summary>
|
|||
public abstract class ExternalChatUpdateEvent : ExternalChatChangeEvent |
|||
{ |
|||
/// <summary>
|
|||
/// 变更详情。目前有以下几种:<br />
|
|||
/// add_member : 成员入群<br />
|
|||
/// del_member : 成员退群<br />
|
|||
/// change_owner : 群主变更<br />
|
|||
/// change_name : 群名变更<br />
|
|||
/// change_notice : 群公告变更
|
|||
/// </summary>
|
|||
[XmlElement("UpdateDetail")] |
|||
public string UpdateDetail { get; set; } |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using System.Xml.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 企业客户变更事件推送
|
|||
/// </summary>
|
|||
public abstract class ExternalContactChangeEvent : WeChatWorkEventMessage |
|||
{ |
|||
/// <summary>
|
|||
/// 变更类型
|
|||
/// </summary>
|
|||
[XmlElement("ChangeType")] |
|||
public string ChangeType { get; set; } |
|||
/// <summary>
|
|||
/// 企业服务人员的UserID
|
|||
/// </summary>
|
|||
[XmlElement("UserID")] |
|||
public string UserId { get; set; } |
|||
/// <summary>
|
|||
/// 外部联系人的userid,注意不是企业成员的账号
|
|||
/// </summary>
|
|||
[XmlElement("ExternalUserID")] |
|||
public string ExternalUserId { get; set; } |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using System.Xml.Serialization; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 添加企业客户事件推送
|
|||
/// </summary>
|
|||
[EventName("external_contact_create")] |
|||
public class ExternalContactCreateEvent : ExternalContactChangeEvent |
|||
{ |
|||
/// <summary>
|
|||
/// 添加此用户的「联系我」方式配置的state参数,或在获客链接中指定的customer_channel参数,可用于识别添加此用户的渠道
|
|||
/// </summary>
|
|||
[XmlElement("State")] |
|||
public string State { get; set; } |
|||
/// <summary>
|
|||
/// 欢迎语code,可用于发送欢迎语
|
|||
/// </summary>
|
|||
[XmlElement("WelcomeCode")] |
|||
public string WelcomeCode { get; set; } |
|||
|
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalContactCreateEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using System.Xml.Serialization; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 外部联系人免验证添加成员事件
|
|||
/// </summary>
|
|||
[EventName("external_contact_create_half")] |
|||
public class ExternalContactCreateHalfEvent : ExternalContactChangeEvent |
|||
{ |
|||
/// <summary>
|
|||
/// 添加此用户的「联系我」方式配置的state参数,或在获客链接中指定的customer_channel参数,可用于识别添加此用户的渠道
|
|||
/// </summary>
|
|||
[XmlElement("State")] |
|||
public string State { get; set; } |
|||
/// <summary>
|
|||
/// 欢迎语code,可用于发送欢迎语
|
|||
/// </summary>
|
|||
[XmlElement("WelcomeCode")] |
|||
public string WelcomeCode { get; set; } |
|||
|
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalContactCreateHalfEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using System.Xml.Serialization; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 删除企业客户事件
|
|||
/// </summary>
|
|||
[EventName("external_contact_delete")] |
|||
public class ExternalContactDeleteEvent : ExternalContactChangeEvent |
|||
{ |
|||
/// <summary>
|
|||
/// 删除客户的操作来源,DELETE_BY_TRANSFER表示此客户是因在职继承自动被转接成员删除
|
|||
/// </summary>
|
|||
[XmlElement("Source")] |
|||
public string Source { get; set; } |
|||
|
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalContactDeleteEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 删除跟进成员事件
|
|||
/// </summary>
|
|||
[EventName("external_contact_del_follow_user")] |
|||
public class ExternalContactDeleteFollowUserEvent : ExternalContactChangeEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalContactDeleteFollowUserEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using System.Xml.Serialization; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 客户接替失败事件
|
|||
/// </summary>
|
|||
[EventName("external_contact_transfer_fail")] |
|||
public class ExternalContactTransferFailEvent : ExternalContactChangeEvent |
|||
{ |
|||
/// <summary>
|
|||
/// 接替失败的原因, customer_refused-客户拒绝, customer_limit_exceed-接替成员的客户数达到上限
|
|||
/// </summary>
|
|||
[XmlElement("FailReason")] |
|||
public string FailReason { get; set; } |
|||
|
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalContactTransferFailEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 编辑企业客户事件推送
|
|||
/// </summary>
|
|||
[EventName("external_contact_update")] |
|||
public class ExternalContactUpdateEvent : ExternalContactChangeEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalContactUpdateEvent>(this); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,20 @@ |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using System.Xml.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 企业客户标签变更事件推送
|
|||
/// </summary>
|
|||
public abstract class ExternalTagChangeEvent : WeChatWorkEventMessage |
|||
{ |
|||
/// <summary>
|
|||
/// 变更类型
|
|||
/// </summary>
|
|||
[XmlElement("ChangeType")] |
|||
public string ChangeType { get; set; } |
|||
/// <summary>
|
|||
/// 标签或标签组所属的规则组id,只回调给“客户联系”应用
|
|||
/// </summary>
|
|||
[XmlElement("StrategyId")] |
|||
public string StrategyId { get; set; } |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 企业客户标签创建事件推送
|
|||
/// </summary>
|
|||
[EventName("change_external_tag_create")] |
|||
public class ExternalTagCreateEvent : ExternalTagChangeEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalTagCreateEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 企业客户标签删除事件推送
|
|||
/// </summary>
|
|||
[EventName("change_external_tag_delete")] |
|||
public class ExternalTagDeleteEvent : ExternalTagChangeEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalTagDeleteEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 企业客户标签重排事件推送
|
|||
/// </summary>
|
|||
[EventName("change_external_tag_shuffle")] |
|||
public class ExternalTagShuffleEvent : ExternalTagChangeEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalTagShuffleEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.WeChat.Common.Messages; |
|||
using LINGYUN.Abp.WeChat.Work.Common.Messages; |
|||
using Volo.Abp.EventBus; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models; |
|||
/// <summary>
|
|||
/// 企业客户标签变更事件推送
|
|||
/// </summary>
|
|||
[EventName("change_external_tag_update")] |
|||
public class ExternalTagUpdateEvent : ExternalTagChangeEvent |
|||
{ |
|||
public override WeChatMessageEto ToEto() |
|||
{ |
|||
return new WeChatWorkEventMessageEto<ExternalTagUpdateEvent>(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using JetBrains.Annotations; |
|||
using Newtonsoft.Json; |
|||
using System.Text.Json.Serialization; |
|||
|
|||
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Models; |
|||
/// <summary>
|
|||
/// 成员对外属性
|
|||
/// </summary>
|
|||
public abstract class ExternalAttribute |
|||
{ |
|||
/// <summary>
|
|||
/// 属性名称: 需要先确保在管理端有创建该属性,否则会忽略
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("name")] |
|||
[JsonPropertyName("name")] |
|||
public string Name { get; set; } |
|||
/// <summary>
|
|||
/// 属性类型
|
|||
/// </summary>
|
|||
[NotNull] |
|||
[JsonProperty("type")] |
|||
[JsonPropertyName("type")] |
|||
public ExternalAttributeType Type { get; set; } |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue