use serde::{Serialize, Deserialize};
use serde_json::{json, Value};
use crate::{session::SessionStore, LabradorResult, RequestType, WechatCpClient, LabraError, WechatCommonResponse};
use crate::wechat::cp::constants::{CURSOR, EXTERNAL_USERID, USERID, WELCOME_MSG_TYPE_FILE, WELCOME_MSG_TYPE_IMAGE, WELCOME_MSG_TYPE_LINK, WELCOME_MSG_TYPE_MINIPROGRAM, WELCOME_MSG_TYPE_VIDEO};
use crate::wechat::cp::method::{CpExternalContactMethod, WechatCpMethod};
#[derive(Debug, Clone)]
pub struct WechatCpExternalContact<'a, T: SessionStore> {
client: &'a WechatCpClient<T>,
}
#[allow(unused)]
impl<'a, T: SessionStore> WechatCpExternalContact<'a, T> {
#[inline]
pub fn new(client: &WechatCpClient<T>) -> WechatCpExternalContact<T> {
WechatCpExternalContact {
client,
}
}
pub async fn add_contact_way(&self, req: WechatCpContactWayInfo) -> LabradorResult<WechatCpContactWayInfoResponse> {
if let Some(user) = &req.contact_way.user {
if user.len() > 100 {
return Err(LabraError::RequestError("「联系我」使用人数默认限制不超过100人(包括部门展开后的人数)".to_string()));
}
}
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::AddContactWay), vec![], req.contact_way, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpContactWayInfoResponse>(v)
}
pub async fn get_contact_way(&self, config_id: &str) -> LabradorResult<WechatCpContactWayInfo> {
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetContactWay), vec![], json!({"config_id": config_id}), RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpContactWayInfo>(v)
}
pub async fn update_contact_way(&self, req: WechatCpContactWayInfo) -> LabradorResult<WechatCommonResponse> {
if req.contact_way.config_id.is_none() {
return Err(LabraError::RequestError("更新「联系我」方式需要指定configId".to_string()));
}
if let Some(user) = &req.contact_way.user {
if user.len() > 100 {
return Err(LabraError::RequestError("「联系我」使用人数默认限制不超过100人(包括部门展开后的人数)".to_string()));
}
}
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::UpdateContactWay), vec![], req, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn delete_contact_way(&self, config_id: &str) -> LabradorResult<WechatCommonResponse> {
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::DeleteContactWay), vec![], json!({"config_id": config_id}), RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn close_temp_chat(&self, user_id: &str, external_user_id: &str) -> LabradorResult<WechatCommonResponse> {
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::CloseTmpChat), vec![], json!({"userid": user_id, "external_userid": external_user_id}), RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn get_contact_detail(&self, user_id: &str, cursor: &str) -> LabradorResult<WechatCpExternalContactInfoResponse> {
let v = self.client.get(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetContactWayDetail), vec![(EXTERNAL_USERID.to_string(), user_id.to_string()), (CURSOR.to_string(), cursor.to_string())], RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpExternalContactInfoResponse>(v)
}
pub async fn convert_openid(&self, external_userid: &str) -> LabradorResult<String> {
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::ConvertToOpenid), vec![], json!({"external_userid": external_userid}), RequestType::Json).await?.json::<Value>()?;
let v = WechatCommonResponse::parse::<Value>(v)?;
let openid = v["openid"].as_str().unwrap_or_default().to_string();
Ok(openid)
}
pub async fn unionid_to_external_userid(&self, unionid: &str, openid: Option<&str>) -> LabradorResult<String> {
let mut req = json!({
"unionid": unionid
});
if let Some(openid) = openid {
req["openid"] = openid.into();
}
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::UnionidToExternalUserid), vec![], req, RequestType::Json).await?.json::<Value>()?;
let v = WechatCommonResponse::parse::<Value>(v)?;
let external_userid = v["external_userid"].as_str().unwrap_or_default().to_string();
Ok(external_userid)
}
pub async fn add_join_way(&self, unionid: &str, req: WechatCpGroupJoinWayInfo) -> LabradorResult<WechatCpGroupJoinWayResponse> {
if let Some(chat_ids) = &req.join_way.chat_id_list {
if chat_ids.len() > 5 {
return Err(LabraError::RequestError("使用该配置的客户群ID列表,支持5个".to_string()));
}
}
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GroupChatAddJoinWay), vec![], req.join_way, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpGroupJoinWayResponse>(v)
}
pub async fn update_join_way(&self, unionid: &str, req: WechatCpGroupJoinWayInfo) -> LabradorResult<WechatCommonResponse> {
if let Some(chat_ids) = &req.join_way.chat_id_list {
if chat_ids.len() > 5 {
return Err(LabraError::RequestError("使用该配置的客户群ID列表,支持5个".to_string()));
}
}
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GroupChatUpdateJoinWay), vec![], req.join_way, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn get_join_way(&self, unionid: &str, config_id: &str) -> LabradorResult<WechatCpContactWayInfo> {
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GroupChatGetJoinWay), vec![], json!({"config_id": config_id}), RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpContactWayInfo>(v)
}
pub async fn delete_join_way(&self, unionid: &str, config_id: &str) -> LabradorResult<WechatCommonResponse> {
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GroupChatDeleteJoinWay), vec![], json!({"config_id": config_id}), RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn get_contact_detail_batch(&self, userid_list: Vec<String>, cursor: Option<&str>, limit: Option<i32>) -> LabradorResult<WechatCpExternalContactBatchInfoResponse> {
let mut req = json!({
"userid_list": userid_list,
});
if let Some(cursor) = cursor {
req["cursor"] = cursor.into();
}
if let Some(limit) = limit {
req["limit"] = limit.into();
}
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::BatchGetByUser), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpExternalContactBatchInfoResponse>(v)
}
pub async fn update_remark(&self, req: WechatCpUpdateRemarkRequest) -> LabradorResult<WechatCommonResponse> {
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::Remark), vec![], req, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn list_external_contacts(&self, userid: &str) -> LabradorResult<Vec<String>> {
let v = self.client.get(WechatCpMethod::ExternalContact(CpExternalContactMethod::List), vec![(USERID.to_string(), userid.to_string())], RequestType::Json).await?.json::<Value>()?;
let v = WechatCommonResponse::parse::<Value>(v)?;
let external_userids = v["external_userid"].as_array().unwrap_or(&vec![]).iter().map(|v| v.as_str().unwrap_or_default().to_string()).collect::<Vec<String>>();
Ok(external_userids)
}
pub async fn list_followers(&self) -> LabradorResult<Vec<String>> {
let v = self.client.get(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetFollowUserList), vec![], RequestType::Json).await?.json::<Value>()?;
let v = WechatCommonResponse::parse::<Value>(v)?;
let follow_users = v["follow_user"].as_array().unwrap_or(&vec![]).iter().map(|v| v.as_str().unwrap_or_default().to_string()).collect::<Vec<String>>();
Ok(follow_users)
}
pub async fn list_unassigned(&self, page_id: Option<u64>, cursor: &str, page_size: Option<u64>) -> LabradorResult<WechatCpUserExternalUnassignList> {
let mut req = json!({
"cursor": cursor,
"page_size": page_size.unwrap_or(1000)
});
if let Some(page_id) = page_id {
req["page_id"] = page_id.into();
}
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetUnassignedList), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserExternalUnassignList>(v)
}
pub async fn transfer_customer(&self, req: WechatCpUserTransferCustomerRequest) -> LabradorResult<WechatCpUserTransferCustomerResponse> {
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::TransferCustomer), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserTransferCustomerResponse>(v)
}
pub async fn transfer_result(&self, hand_over_userid: &str, take_over_userid: &str, cursor: &str) -> LabradorResult<WechatCpUserTransferResultResponse> {
let req = json!({
"cursor": cursor,
"handover_userid": hand_over_userid,
"takeover_userid": take_over_userid,
});
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::TransferResult), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserTransferResultResponse>(v)
}
pub async fn resigned_transfer_customer(&self, req: WechatCpUserTransferCustomerRequest) -> LabradorResult<WechatCpUserTransferCustomerResponse> {
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::ResignedTransferCustomer), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserTransferCustomerResponse>(v)
}
pub async fn resigned_transfer_result(&self, hand_over_userid: &str, take_over_userid: &str, cursor: &str) -> LabradorResult<WechatCpUserTransferResultResponse> {
let req = json!({
"cursor": cursor,
"handover_userid": hand_over_userid,
"takeover_userid": take_over_userid,
});
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::ResignedTransferResult), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserTransferResultResponse>(v)
}
pub async fn list_group_chat(&self, limit: Option<u64>, cursor: &str, status: u8, user_ids: Vec<String>) -> LabradorResult<WechatCpUserExternalGroupChatList> {
let mut req = json!({
"cursor": cursor,
"limit": limit.unwrap_or(100),
"status_filter": status,
});
if !user_ids.is_empty() {
req["owner_filter"] = json!({
"userid_list": user_ids
});
}
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GroupChatList), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserExternalGroupChatList>(v)
}
pub async fn get_group_chat(&self, chat_id: &str, need_name: u8) -> LabradorResult<WechatCpUserExternalGroupChatInfoResponse> {
let req = json!({
"chat_id": chat_id,
"need_name": need_name,
});
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GroupChatGet), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserExternalGroupChatInfoResponse>(v)
}
pub async fn transfer_group_chat(&self, chat_ids: Vec<&str>, new_owner: &str) -> LabradorResult<WechatCpUserExternalGroupChatTransferResponse> {
let mut req = json!({
"new_owner": new_owner,
});
if !chat_ids.is_empty() {
req["chat_id_list"] = chat_ids.into()
}
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GroupChatTransfer), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserExternalGroupChatTransferResponse>(v)
}
pub async fn get_user_behavior_statistic(&self, start_time: u64, end_time: u64, user_ids: Vec<&str>, party_ids: Vec<String>) -> LabradorResult<WechatCpUserExternalUserBehaviorStatistic> {
let mut req = json!({
"start_time": start_time / 1000,
"end_time": end_time / 1000,
});
if !user_ids.is_empty() {
req["userid"] = user_ids.into()
}
if !party_ids.is_empty() {
req["partyid"] = party_ids.into()
}
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetUserBehaviorData), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserExternalUserBehaviorStatistic>(v)
}
pub async fn get_group_chat_statistic(&self, start_time: u64, order_by: Option<u8>, order_asc: Option<u8>, page_index: Option<u64>, page_size: Option<u64>, user_ids: Vec<&str>, party_ids: Vec<String>) -> LabradorResult<WechatCpUserExternalGroupChatStatistic> {
let mut req = json!({
"day_begin_time": start_time / 1000,
"order_by": order_by.unwrap_or(1),
"order_asc": order_asc.unwrap_or(0),
"offset": page_index.unwrap_or(0),
"limit": page_size.unwrap_or(500),
});
if !user_ids.is_empty() || !party_ids.is_empty() {
req["owner_filter"] = json!({
"userid_list": user_ids,
"partyid_list": party_ids,
});
}
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GroupChatStatistic), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserExternalGroupChatStatistic>(v)
}
pub async fn add_msg_template(&self, msg_template: WechatCpMsgTemplate) -> LabradorResult<WechatCpMsgTemplateAddResponse> {
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::AddMsgTemplate), vec![], msg_template, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpMsgTemplateAddResponse>(v)
}
pub async fn send_welcome_msg(&self, msg: WechatCpWelcomeMsg) -> LabradorResult<WechatCommonResponse> {
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::SendWelcomeMsg), vec![], msg, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn get_corp_tag_list(&self, tag_id: Vec<&str>, group_id: Vec<Vec<&str>>) -> LabradorResult<WechatCpUserExternalTagGroupInfo> {
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetCorpTagList), vec![], json!({"tag_id": tag_id, "group_id": group_id}), RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpUserExternalTagGroupInfo>(v)
}
pub async fn add_corp_tag(&self, req: TagGroup) -> LabradorResult<WechatCommonResponse> {
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::AddCorpTag), vec![], req, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn edit_corp_tag(&self, id: &str, name: &str, order: u64) -> LabradorResult<WechatCommonResponse> {
let req = json!({
"id": id,
"name": name,
"order": order
});
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::EditCorpTag), vec![], req, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn delete_corp_tag(&self, tag_id: Vec<&str>, group_id: Vec<&str>) -> LabradorResult<WechatCommonResponse> {
let req = json!({
"tag_id": tag_id,
"group_id": group_id
});
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::DeleteCorpTag), vec![], req, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn mark_tag(&self, userid: &str, external_userid: &str, add_tag: Vec<&str>, remove_tag: Vec<&str>) -> LabradorResult<WechatCommonResponse> {
let req = json!({
"userid": userid,
"external_userid": external_userid,
"add_tag": add_tag,
"remove_tag": remove_tag
});
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::MarkTag), vec![], req, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn get_group_msg_list_v2(&self, chat_type: &str, start_time: u64, end_time: u64, creator: &str, filter_type: u8, limit: i32, cursor: &str) -> LabradorResult<WechatCpGroupMsgListResult> {
let req = json!({
"chat_type": chat_type,
"start_time": start_time / 1000,
"end_time": end_time / 1000,
"creator": creator,
"filter_type": filter_type,
"limit": limit,
"cursor": cursor
});
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetGroupMsgListV2), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpGroupMsgListResult>(v)
}
pub async fn get_group_msg_send_result(&self, msgid: &str, userid: &str, limit: i32, cursor: &str) -> LabradorResult<WechatCpGroupMsgSendResult> {
let req = json!({
"msgid": msgid,
"userid": userid,
"limit": limit,
"cursor": cursor
});
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetGroupMsgSendResult), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpGroupMsgSendResult>(v)
}
pub async fn get_group_msg_result(&self, msgid: &str, limit: i32, cursor: &str) -> LabradorResult<WechatCpGroupMsgResult> {
let req = json!({
"msgid": msgid,
"limit": limit,
"cursor": cursor
});
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetGroupMsgResult), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpGroupMsgResult>(v)
}
pub async fn get_group_msg_task(&self, msgid: &str, limit: i32, cursor: &str) -> LabradorResult<WechatCpGroupMsgTaskResult> {
let req = json!({
"msgid": msgid,
"limit": limit,
"cursor": cursor
});
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetGroupMsgTask), vec![], req, RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpGroupMsgTaskResult>(v)
}
pub async fn add_group_welcome_template(&self, req: WechatCpGroupWelcomeTemplateInfo) -> LabradorResult<String> {
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::AddGroupWelcomeTemplate), vec![], req, RequestType::Json).await?.json::<Value>()?;
let v = WechatCommonResponse::parse::<Value>(v)?;
let template_id = v["template_id"].as_str().unwrap_or_default().to_string();
Ok(template_id)
}
pub async fn edit_group_welcome_template(&self, req: WechatCpGroupWelcomeTemplateInfo) -> LabradorResult<WechatCommonResponse> {
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::EditGroupWelcomeTemplate), vec![], req, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn get_group_welcome_template(&self, template_id: &str) -> LabradorResult<WechatCpGroupWelcomeTemplateInfo> {
let v = self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::GetGroupWelcomeTemplate), vec![], json!({"template_id": template_id}), RequestType::Json).await?.json::<Value>()?;
WechatCommonResponse::parse::<WechatCpGroupWelcomeTemplateInfo>(v)
}
pub async fn delete_group_welcome_template(&self, template_id: &str, agent_id: Option<&str>) -> LabradorResult<WechatCommonResponse> {
let mut req = json!({"template_id": template_id});
if let Some(agent) = agent_id {
req["agentid"] = agent.into();
}
self.client.post(WechatCpMethod::ExternalContact(CpExternalContactMethod::DeleteGroupWelcomeTemplate), vec![], req, RequestType::Json).await?.json::<WechatCommonResponse>()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpContactWayInfo {
pub contact_way: ContactWay,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContactWay {
pub config_id: Option<String>,
#[serde(rename = "type")]
pub r#type: u8,
pub scene: u8,
pub style: Option<u8>,
pub remark: Option<String>,
pub skip_verify: Option<bool>,
pub state: Option<String>,
pub qr_code: Option<String>,
pub user: Option<Vec<String>>,
pub party: Option<Vec<String>>,
pub is_temp: Option<bool>,
pub expires_in: Option<i64>,
pub chat_expires_in: Option<i64>,
pub unionid: Option<String>,
pub conclusions: Option<Conclusion>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Conclusion {
pub text_content: Option<String>,
pub img_media_id: Option<String>,
pub img_pic_url: Option<String>,
pub link_title: Option<String>,
pub link_pic_url: Option<String>,
pub link_desc: Option<String>,
pub link_url: Option<String>,
pub mini_program_title: Option<String>,
pub mini_program_pic_media_id: Option<String>,
pub mini_program_app_id: Option<String>,
pub mini_program_page: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpContactWayInfoResponse {
pub config_id: Option<String>,
pub qr_code: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpExternalContactInfoResponse {
pub external_contact: Option<ExternalContact>,
pub follow_user: Option<Vec<FollowedUser>>,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalContact {
pub external_userid: Option<String>,
pub position: Option<String>,
pub name: Option<String>,
pub nickname: Option<String>,
pub avatar: Option<String>,
pub corp_name: Option<String>,
pub corp_full_name: Option<String>,
#[serde(rename = "type")]
pub r#type: Option<u8>,
pub gender: Option<u8>,
pub unionid: Option<String>,
pub external_profile: Option<ExternalProfile>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalProfile {
pub external_corp_name: Option<String>,
pub external_attr: Option<ExternalAttribute>,
pub wechat_channels: Option<WechatChannel>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatChannel {
pub nickname: Option<String>,
pub status: Option<u8>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalAttribute {
#[serde(rename = "type")]
pub r#type: Option<u8>,
pub name: Option<String>,
pub text: Option<Text>,
pub web: Option<Web>,
pub miniprogram: Option<MiniProgram>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Text {
pub value: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Web {
pub title: Option<String>,
pub url: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MiniProgram {
pub pagepath: Option<String>,
pub appid: Option<String>,
pub title: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FollowedUserTag {
pub group_name: Option<String>,
pub tag_name: Option<String>,
pub tag_id: Option<String>,
#[serde(rename = "type")]
pub r#type: Option<u8>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FollowedUser {
pub userid: Option<String>,
pub remark: Option<String>,
pub description: Option<String>,
pub state: Option<String>,
pub remark_company: Option<String>,
pub remark_corp_name: Option<String>,
pub add_way: Option<u8>,
pub oper_userid: Option<String>,
pub tags: Option<Vec<FollowedUserTag>>,
pub remark_mobiles: Option<Vec<String>>,
pub tag_id: Option<Vec<String>>,
pub createtime: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpGroupJoinWayInfo {
pub join_way: JoinWay,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JoinWay {
pub config_id: Option<String>,
pub scene: Option<u8>,
pub remark: Option<String>,
pub auto_create_room: Option<u8>,
pub room_base_name: Option<String>,
pub room_base_id: Option<u64>,
pub chat_id_list: Option<Vec<String>>,
pub qr_code: Option<Vec<String>>,
pub state: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpGroupJoinWayResponse {
pub config_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpExternalContactBatchInfoResponse {
pub external_contact_list: Option<ExternalContactInfo>,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalContactInfo {
pub external_contact: Option<ExternalContact>,
pub follow_info: Option<FollowedUser>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUpdateRemarkRequest {
pub userid: String,
pub external_userid: String,
pub remark: Option<String>,
pub description: Option<String>,
pub remark_company: Option<String>,
pub remark_mobiles: Option<Vec<String>>,
pub remark_pic_mediaid: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserExternalUnassignList {
pub info: Option<Vec<ExternalContact>>,
pub is_last: Option<bool>,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnassignInfo {
pub handover_userid: Option<String>,
pub external_userid: Option<String>,
pub dimission_time: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserTransferCustomerRequest {
pub handover_userid: String,
pub takeover_userid: String,
pub transfer_success_msg: String,
pub external_userid: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserTransferCustomerResponse {
pub customer: Vec<TransferCustomer>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransferCustomer {
pub errcode: u8,
pub external_userid: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserTransferResultResponse {
pub customer: Vec<TransferResult>,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransferResult {
pub status: u8,
pub external_userid: Option<String>,
pub takeover_time: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserExternalGroupChatList {
pub group_chat_list: Vec<ChatStatus>,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatStatus {
pub chat_id: Option<String>,
pub status: Option<u8>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserExternalGroupChatInfoResponse {
pub group_chat: GroupChat,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GroupChat {
pub chat_id: Option<String>,
pub name: Option<String>,
pub owner: Option<String>,
pub notice: Option<String>,
pub create_time: Option<u64>,
pub member_list: Option<Vec<GroupMember>>,
pub admin_list: Option<Vec<GroupAdmin>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GroupMember {
pub userid: Option<String>,
#[serde(rename = "type")]
pub r#type: Option<u8>,
pub join_scene: Option<u8>,
pub unionid: Option<String>,
pub state: Option<String>,
pub group_nickname: Option<String>,
pub name: Option<String>,
pub join_time: Option<u64>,
pub invitor: Option<Invitor>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GroupAdmin {
pub userid: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Invitor {
pub userid: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserExternalGroupChatTransferResponse {
pub failed_chat_list: Vec<GroupChatFailedTransfer>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GroupChatFailedTransfer {
pub chat_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserExternalUserBehaviorStatistic {
pub behavior_data: Vec<Behavior>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Behavior {
pub stat_time: Option<u64>,
pub chat_cnt: Option<u64>,
pub message_cnt: Option<u64>,
pub avg_reply_time: Option<u64>,
pub negative_feedback_cnt: Option<u64>,
pub new_apply_cnt: Option<u64>,
pub new_contact_cnt: Option<u64>,
pub reply_percentage: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserExternalGroupChatStatistic {
pub total: Vec<u64>,
pub next_offset: Vec<u64>,
pub items: Vec<StatisticItem>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StatisticItem {
pub owner: Option<String>,
pub data: Option<ItemData>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ItemData {
pub new_chat_cnt: Option<u64>,
pub chat_total: Option<u64>,
pub chat_has_msg: Option<u64>,
pub new_member_cnt: Option<u64>,
pub member_total: Option<u64>,
pub member_has_msg: Option<u64>,
pub msg_total: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpMsgTemplate {
pub chat_type: Option<String>,
pub external_userid: Option<Vec<String>>,
pub sender: Option<String>,
pub text: Option<WechatCpTextMsg>,
pub attachments: Option<Vec<WechatCpAttachment>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpTextMsg {
pub content: String,
}
impl WechatCpTextMsg {
pub fn new(content: &str) -> Self {
Self {
content: content.to_string()
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpImageMsg {
pub media_id: String,
pub pic_url: String,
}
impl WechatCpImageMsg {
pub fn new() -> Self {
Self {
media_id: "".to_string(),
pic_url: "".to_string()
}
}
pub fn media_id(mut self, media_id: &str) -> Self {
self.media_id = media_id.to_string();
self
}
pub fn pic_url(mut self, pic_url: &str) -> Self {
self.pic_url = pic_url.to_string();
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpLinkMsg {
pub title: String,
pub picurl: String,
pub desc: String,
pub url: String,
pub media_id: String,
}
impl WechatCpLinkMsg {
pub fn new() -> Self {
Self {
title: "".to_string(),
picurl: "".to_string(),
desc: "".to_string(),
url: "".to_string(),
media_id: "".to_string(),
}
}
pub fn url(mut self, url: &str) -> Self {
self.url = url.to_string();
self
}
pub fn desc(mut self, desc: &str) -> Self {
self.desc = desc.to_string();
self
}
pub fn picurl(mut self, picurl: &str) -> Self {
self.picurl = picurl.to_string();
self
}
pub fn media_id(mut self, media_id: &str) -> Self {
self.media_id = media_id.to_string();
self
}
pub fn title(mut self, title: &str) -> Self {
self.title = title.to_string();
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpMiniProgramMsg {
pub title: String,
pub pic_media_id: String,
pub appid: String,
pub page: String,
}
impl WechatCpMiniProgramMsg {
pub fn new() -> Self {
Self {
title: "".to_string(),
pic_media_id: "".to_string(),
appid: "".to_string(),
page: "".to_string()
}
}
pub fn pic_media_id(mut self, pic_media_id: &str) -> Self {
self.pic_media_id = pic_media_id.to_string();
self
}
pub fn appid(mut self, appid: &str) -> Self {
self.appid = appid.to_string();
self
}
pub fn page(mut self, page: &str) -> Self {
self.page = page.to_string();
self
}
pub fn title(mut self, title: &str) -> Self {
self.title = title.to_string();
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpVideoMsg {
pub media_id: String,
pub thumb_media_id: String,
}
impl WechatCpVideoMsg {
pub fn new() -> Self {
Self {
media_id: "".to_string(),
thumb_media_id: "".to_string()
}
}
pub fn media_id(mut self, media_id: &str) -> Self {
self.media_id = media_id.to_string();
self
}
pub fn thumb_media_id(mut self, thumb_media_id: &str) -> Self {
self.thumb_media_id = thumb_media_id.to_string();
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpFileMsg {
pub media_id: String,
}
impl WechatCpFileMsg {
pub fn new() -> Self {
Self {
media_id: "".to_string(),
}
}
pub fn media_id(mut self, media_id: &str) -> Self {
self.media_id = media_id.to_string();
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpAttachment {
pub msgtype: String,
pub image: Option<WechatCpImageMsg>,
pub link: Option<WechatCpLinkMsg>,
pub miniprogram: Option<WechatCpMiniProgramMsg>,
pub video: Option<WechatCpVideoMsg>,
pub file: Option<WechatCpFileMsg>,
}
impl WechatCpAttachment {
pub fn new() -> Self {
Self {
msgtype: "".to_string(),
image: None,
link: None,
miniprogram: None,
video: None,
file: None,
}
}
pub fn image(mut self, image: WechatCpImageMsg) -> Self {
self.image = image.into();
self.msgtype = WELCOME_MSG_TYPE_IMAGE.to_string();
self
}
pub fn link(mut self, link: WechatCpLinkMsg) -> Self {
self.link = link.into();
self.msgtype = WELCOME_MSG_TYPE_LINK.to_string();
self
}
pub fn video(mut self, video: WechatCpVideoMsg) -> Self {
self.video = video.into();
self.msgtype = WELCOME_MSG_TYPE_VIDEO.to_string();
self
}
pub fn file(mut self, file: WechatCpFileMsg) -> Self {
self.file = file.into();
self.msgtype = WELCOME_MSG_TYPE_FILE.to_string();
self
}
pub fn miniprogram(mut self, miniprogram: WechatCpMiniProgramMsg) -> Self {
self.miniprogram = miniprogram.into();
self.msgtype = WELCOME_MSG_TYPE_MINIPROGRAM.to_string();
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpMsgTemplateAddResponse {
pub fail_list: Option<Vec<String>>,
pub msgid: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpWelcomeMsg {
pub welcome_code: String,
pub text: Option<WechatCpTextMsg>,
pub attachments: Option<Vec<WechatCpAttachment>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpUserExternalTagGroupInfo {
pub tag_group: Option<Vec<TagGroup>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TagGroup {
pub group_id: Option<String>,
pub group_name: Option<String>,
pub create_time: Option<u64>,
pub order: Option<u64>,
pub deleted: Option<bool>,
pub tag: Option<Vec<CustomerTag>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomerTag {
pub id: Option<String>,
pub name: Option<String>,
pub create_time: Option<u64>,
pub order: Option<u64>,
pub deleted: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpGroupMsgListResult {
pub group_msg_list: Vec<ExternalContactGroupMsgInfo>,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpGroupMsgSendResult {
pub send_list: Vec<ExternalContactGroupMsgSendInfo>,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalContactGroupMsgInfo {
pub msgid: Option<String>,
pub creator: Option<String>,
pub create_type: Option<u8>,
pub create_time: Option<u64>,
pub text: Option<WechatCpTextMsg>,
pub attachments: Option<Vec<WechatCpAttachment>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalContactGroupMsgSendInfo {
pub external_userid: Option<String>,
pub chat_id: Option<String>,
pub userid: Option<String>,
pub status: Option<u8>,
pub send_time: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpGroupMsgResult {
pub detail_list: Vec<ExternalContactGroupMsgDetailInfo>,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalContactGroupMsgDetailInfo {
pub external_userid: Option<String>,
pub chat_id: Option<String>,
pub userid: Option<String>,
pub status: Option<u8>,
pub send_time: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpGroupMsgTaskResult {
pub task_list: Vec<ExternalContactGroupMsgTaskInfo>,
pub next_cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalContactGroupMsgTaskInfo {
pub userid: Option<String>,
pub status: Option<u8>,
pub send_time: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatCpGroupWelcomeTemplateInfo {
pub text: Option<WechatCpTextMsg>,
pub image: Option<WechatCpImageMsg>,
pub link: Option<WechatCpLinkMsg>,
pub miniprogram: Option<WechatCpMiniProgramMsg>,
pub file: Option<WechatCpFileMsg>,
pub video: Option<WechatCpVideoMsg>,
pub template_id: Option<String>,
pub notify: Option<u8>,
}