This commit is contained in:
doudou201703
2026-08-02 14:07:04 +08:00
commit 046fac6dc1
339 changed files with 19435 additions and 0 deletions
@@ -0,0 +1,524 @@
"""
Author: xiao 792282@qq.com
Date: 2025-08-10 11:36:05
LastEditors: xiao 792282@qq.com
LastEditTime: 2025-08-17 13:38:39
FilePath: django_公共认证接口/企业微信认证接口.py
Description: 这是默认设置,可以在设置》工具》File Description中进行配置
"""
import dataclasses
import io
import os
from typing import Literal
import django
import requests
from rest_framework.viewsets import ViewSet
from sixGuoDjango.settings import BASE_DIR
from wechat_token.token工具包 import sixToken
from wechat_数据库.企业微信数据库.企微用户表 import wecom企微用户
from wechat_数据库.用户数据库.小程序登陆用户 import weiuser
from wechat_项目工具包.企业微信工具包.消息推送工具 import wecom消息推送
from wechat_项目工具包.数据库的工具包.更新用户积分 import miniUser积分
from 第三方工具目录.腾讯云 import oss上传腾讯云图片
os.environ.setdefault(key="DJANGO_SETTINGS_MODULE", value=f"{BASE_DIR.name}.settings")
django.setup()
import pydash
import base64
import hashlib
from pathlib import Path
import jmespath
import xmltodict
from Crypto.Cipher import AES
from django.conf import settings
from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse
from rest_framework import status
from rest_framework.request import Request
from rest_framework.response import Response
@dataclasses.dataclass
class wecomData:
"""
微信企业服务器推送事件的数据类
映射XML中的字段
"""
# 基本消息头
as_data: dict
def __post_init__(self):
self.ToUserName = pydash.get(obj=self.as_data, path="xml.ToUserName") # toUser 企业微信CorpID
self.FromUserName = pydash.get(obj=self.as_data, path="xml.FromUserName") # sys 此事件该值固定为sys,表示该消息由系统生成
self.CreateTime = pydash.get(obj=self.as_data, path="xml.CreateTime") # 1403610513 消息创建时间 (整型)
self.MsgType = pydash.get(obj=self.as_data, path="xml.MsgType") # event 消息的类型,此时固定为event
self.Event = pydash.get(obj=self.as_data, path="xml.Event", ) # change_external_contact 事件的类型,此时固定为change_external_contact
self.ChangeType = pydash.get(obj=self.as_data, path="xml.ChangeType", ) # add_external_contact 此时固定为add_external_contact
self.UserID = pydash.get(obj=self.as_data, path="xml.UserID") # UserID 企业服务人员的UserID
self.ExternalUserID = pydash.get(obj=self.as_data, path="xml.ExternalUserID", ) # woAJ2GCAAAXtWyujaWJHDDGi0mAAAA 外部联系人的userid,注意不是企业成员的账号
self.State = pydash.get(obj=self.as_data, path="xml.State", default="六果", ) # teststate 添加此用户的「联系我」方式配置的state参数,或在获客链接中指定的customer_channel参数,可用于识别添加此用户的渠道
self.WelcomeCode = pydash.get(obj=self.as_data, path="xml.WelcomeCode") # WELCOMECODE 欢迎语code,可用于发送欢迎语
self.Source = pydash.get(obj=self.as_data, path="xml.Source", ) # 删除客户的操作来源,DELETE_BY_TRANSFER表示此客户是因在职继承自动被转接成员删除
self.FailReason = pydash.get(obj=self.as_data, path="xml.FailReason", ) # 接替失败的原因, customer_refused-客户拒绝, customer_limit_exceed-接替成员的客户数达到上限
self.ChatId = pydash.get(obj=self.as_data, path="xml.ChatId") # 群🆔
self.UpdateDetail = pydash.get(obj=self.as_data, path="xml.UpdateDetail", ) # 群:变更详情。目前有以下几种: add_member : 成员入群 del_member : 成员退群 change_owner : 群主变更 change_name : 群名变更 change_notice : 群公告变更
self.JoinScene: Literal[0, 1] = pydash.get(obj=self.as_data, path="xml.JoinScene", ) # 当是成员入群时有值。表示成员的入群方式 # 0 - 由成员邀请入群(包括直接邀请入群和通过邀请链接入群) # 3 - 通过扫描群二维码入群
self.QuitScene = pydash.get(obj=self.as_data, path="xml.QuitScene") # 是用户自已退群了还是群主踢出群, 0 - 自己退群 1 - 群主/群管理员移出
self.MemChangeCnt = pydash.get(obj=self.as_data, path="xml.MemChangeCnt") # 当当是成员入群或退群时有值。表示成员变更数量
self.MemChangeList = pydash.get(obj=self.as_data, path="xml.MemChangeList") # 当是成员入群或退群时有值。变更的成员列表
self.LastMemVer = pydash.get(obj=self.as_data, path="xml.LastMemVer") # 当是成员入群或退群时有值。 变更前的群成员版本号
self.CurMemVer = pydash.get(obj=self.as_data, path="xml.CurMemVer") # 当是成员入群或退群时有值。变更后的群成员版本号
class sixwecom(ViewSet):
"""https://work.weixin.qq.com/wework_admin/frame#apps/contactsApi"""
token = "bVWt1PEUCG" # url验证的token(江苏六果科技有限公司, 元宝零售 的应用)
EncodingAESKey = "LS6VsiJA6Vpb3nJlt34vMZFAbuKDJkFuH2KxuEXYuUR" # 配置的解密(江苏六果科技有限公司 的 元宝零售应用)
corp_id = "wwbe6369dc26a9d83a" # 企业微信🆔(当前账号是,江苏六果科技有限公司的账号)
corpsecret = "SIRyum7vQh-Bt36AxnqKMX0HIiE-zkYbjYgSat7reZw" # 江苏六果科技有限公司账号 企业微信 secret
phone_secret = "WNxZZdcU3FRS5msq_kHZaaZOBauBEjJZdQV3VrAxu0c" # 通讯录 secret
def 单独处理新添加用户的数据存储(self, UserID, ChangeType, State, ExternalUserID):
"""
:param State:
:param ChangeType: 此时好友的状态
:param ExternalUserID:
:param UserID:
"""
wecom_token = sixToken.get_wecom_token()
uri = f"https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token={wecom_token}&external_userid={ExternalUserID}"
data = requests.get(url=uri).json()
# 创建数据库数据表
unionid = pydash.get(obj=data, path="external_contact.unionid") # 外部联系人在微信开放平台的唯一身份标识(微信unionid)
name = pydash.get(obj=data, path="external_contact.name") # 外部联系人的名称[注1]如果是微信用户,则返回其微信昵称。如果是企业微信联系人,则返回其设置对外展示的别名或实名
external_userid = pydash.get(obj=data, path="external_contact.external_userid") # 外部联系人的userid
avatar = pydash.get(obj=data, path="external_contact.avatar") # 外部联系人头像。第三方应用和代开发应用均不可获取,
gender = pydash.get(obj=data, path="external_contact.gender") # 外部联系人性别 0-未知 1-男性 2-女性。
follow_user = pydash.get(obj=data, path="follow_user")
for wecom in follow_user:
userid = pydash.get(obj=wecom, path="userid") # 添加了此外部联系人的企业成员userid (企微员工的userid)
userid = pydash.get(obj=wecom, path="userid") # 添加了此外部联系人的企业成员userid (企微员工的userid)
tags = pydash.get(obj=wecom, path="tags")
add_way = pydash.get(obj=wecom, path="add_way")
oper_userid = pydash.get(obj=wecom, path="oper_userid")
remark = pydash.get(obj=wecom, path="remark")
createtime = pydash.get(obj=wecom, path="createtime")
remark_mobiles = pydash.get(obj=wecom, path="remark_mobiles")
img_file = requests.get(url=avatar).content
src = oss上传腾讯云图片.上传图片(key=f"{userid}/{name}.png", file=io.BytesIO(img_file), )
avatar = src
企微用户关系对象, 企微用户是否为首次 = wecom企微用户.objects.update_or_create(wecom企微ID=UserID, )
企微用户关系对象.wecom企微状态State = State
企微用户关系对象.wecom好友的ID = external_userid
企微用户关系对象.wecom好友UNIONID = unionid
企微用户关系对象.wecom好友性别 = gender
企微用户关系对象.wecom对好友的备注信息 = remark
企微用户关系对象.wecom企微对好友添加的手机号码 = remark_mobiles
企微用户关系对象.wecom好友关系状态 = ChangeType
企微用户关系对象.wecom企微好友添加方式 = oper_userid
企微用户关系对象.wecom好友头像 = src
企微用户关系对象.wecom好友昵称 = name
企微用户关系对象.wecom对好友的添加时间 = createtime
企微用户关系对象.wecom对好友打的标签 = tags
企微用户关系对象.wecom对好友的备注名称 = remark
企微用户关系对象.save()
six六果对象, sixBool = weiuser.objects.get_or_create(unionid="六果")
six上级对象, six上级Bool = weiuser.objects.get_or_create(unionid=State) # 在这里的state是企微号绑定的 unionid
print("在这里打印一下上级的对象是否已经存丰了", six上级对象)
self自生对象, self对象是首次创建 = weiuser.objects.get_or_create(unionid=unionid, )
print("点击者对象是哪个", self自生对象, "再看看是不是首次创建的啦")
if self对象是首次创建:
print("点击者对象是哪个", self自生对象, "再看看是不是首次创建的啦再看看是不是首次创建的啦再看看是不是首次创建的啦再看看是不是首次创建的啦再看看是不是首次创建的啦再看看是不是首次创建的啦再看看是不是首次创建的啦")
weiuser.objects.update_or_create(unionid=unionid,
defaults={
"user_头像": src, "user_昵称": name, "codeQrCode": six上级对象.codeQrCode,
"codeRemark": six上级对象.codeRemark, "codeConfigId": six上级对象.codeConfigId,
"external_userid": external_userid, "user_用户当前的等级": six上级对象.user_用户当前的等级 + 1,
"parent": six上级对象, "user_绑定企微UNIONID": six上级对象.user_绑定企微UNIONID, "user_绑定企微usrID账号": six上级对象.user_绑定企微usrID账号
})
(miniUser积分(share分享者unionidID=six上级对象.unionid, click点击者unionidID=self自生对象.unionid, bind绑定的企微unionidID=State)
.add添加点击者添加企微员工双向红包积分(share积分类型="新人红包", share分享者二维码state=State))
else:
if self自生对象.parent == six六果对象:
print("判断父元素为六果公司对象的时候,进行了数据的更新")
weiuser.objects.update_or_create(unionid=unionid,
defaults={
"user_头像": src, "user_昵称": name, "codeQrCode": six上级对象.codeQrCode,
"codeRemark": six上级对象.codeRemark, "codeConfigId": six上级对象.codeConfigId,
"external_userid": external_userid, "user_用户当前的等级": six上级对象.user_用户当前的等级 + 1,
"parent": six上级对象, "user_绑定企微UNIONID": six上级对象.user_绑定企微UNIONID, "user_绑定企微usrID账号": six上级对象.user_绑定企微usrID账号
})
# 数据更新完成后: 需要调用添加积分的方法, 对新添加企微的用户,添加积分;
(miniUser积分(share分享者unionidID=six上级对象.unionid, click点击者unionidID=self自生对象.unionid, bind绑定的企微unionidID=State)
.add添加点击者添加企微员工双向红包积分(share积分类型="新人红包", share分享者二维码state=State))
# if is是否首次创建:
# # 在这里的场景值:当用户直接扫码添加企微二维码的时候就需要在这里进行处理了
# # 怎么判断的逻辑为: 当用户是首次添加的时候,则说明,这个用户以前在数据库中是不存在的;并且可以确定为这个用户一定是新添加的
# print("\n🍎 🍏 🍊 🍎首次创建首次创建首次创建首次创建 🍏 🍊 🍎 🍏 \n", 上级对象.unionid)
# self自生对象.user_头像 = src
# self自生对象.user_昵称 = name
# self自生对象.codeQrCode = 上级对象.codeQrCode
# self自生对象.codeRemark = 上级对象.codeRemark
# self自生对象.codeConfigId = 上级对象.codeConfigId
# self自生对象.external_userid = external_userid
# self自生对象.user_用户当前的等级 = 上级对象.level + 1
# self自生对象.parent = 上级对象
# self自生对象.user_绑定企微UNIONID = 上级对象.user_绑定企微UNIONID
# self自生对象.user_绑定企微usrID账号 = 上级对象.user_绑定企微usrID账号
# self自生对象.save()
#
# else:
# self自生对象.user_头像 = src
# self自生对象.user_昵称 = name
# self自生对象.external_userid = external_userid
# self自生对象.save()
return None
def 企微主动删除好友事件(self, UserID, ChangeType, State, ExternalUserID):
pass
企微用户关系对象, 企微用户是否为首次 = wecom企微用户.objects.get_or_create(wecom企微ID=UserID, wecom好友的ID=ExternalUserID)
print(企微用户关系对象, 企微用户是否为首次, "============================")
if 企微用户是否为首次:
pass
else:
企微用户关系对象.wecom好友关系状态 = ChangeType
企微用户关系对象.save()
def 好友主动删除企微事件(self, UserID, ChangeType, State, ExternalUserID):
print("\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n", UserID, State, ChangeType, ExternalUserID,
"\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n",
)
print("到底哪里报错了呀为什么啊")
企微用户关系对象, 企微用户是否为首次 = wecom企微用户.objects.get_or_create(wecom企微ID=UserID, wecom好友的ID=ExternalUserID)
print(企微用户关系对象, 企微用户是否为首次, "==========到底哪里报错了呀为什么啊到底哪里报错了呀为什么啊==================")
if 企微用户是否为首次:
pass
else:
企微用户关系对象.wecom好友关系状态 = ChangeType
企微用户关系对象.save()
def 解密POST消息(self, msg_content: bytes):
"""
微信回调消息解密;(这里是用于解决url回调认证,和用户之间推送消息的)
:param msg_content: 回调消息中的body体内容
:type msg_content: bytes 这里响应的body数据,不要序列化
:return: 返回解密后的字典对象;
:rtype: dict
"""
# 从XML中找到Encrypt标签的内容,即加密数据
xmldict = xmltodict.parse(msg_content.decode())
Encrypt = jmespath.search(data=xmldict, expression="xml.Encrypt", )
# 将EncodingAESKey进行Base64解码,并补足填充字符"="
AESKey = base64.b64decode(self.EncodingAESKey + "=")
# 创建一个AES加密器对象,使用CBC模式和指定的初始化向量(IV)
cipher = AES.new(key=AESKey, mode=AES.MODE_CBC, iv=AESKey[:16])
# 对加密数据进行Base64解码
aes_msg = base64.b64decode(Encrypt)
# 使用解密器对象解密数据
de_text = cipher.decrypt(aes_msg)
# 去除解密数据地前16个字节的随机字符串
content = de_text[16:]
# 解析前4个字节以获取XML内容的实际长度,并将其从网络字节序转换为主机字节序
# xml_len = socket.ntohl(struct.unpack("I", content[:4])[0])
xml_len = int.from_bytes(content[:4], byteorder='big')
# 根据解析出的长度提取实际的XML内容
xml_content = content[4: xml_len + 4]
# 将XML内容解析为字典格式
as_dict = xmltodict.parse(xml_input=xml_content)
# 打印解析后的字典
return as_dict
def 解密GET消息(self, echostr):
"""
:param echostr:
:type echostr:
:return:
:rtype:
"""
AESKey = base64.b64decode(self.EncodingAESKey + "=")
aes_msg = base64.b64decode(echostr)
aes = AES.new(key=AESKey, mode=AES.MODE_CBC, iv=aes_msg[:16])
de_text = aes.decrypt(aes_msg)
# rand_msg = cls.aes_decrypt(AESKey, aes_msg)
content = de_text[16:] # 去掉前16随机字节
# 取出4字节的msg_len
# xml_len = socket.ntohl(struct.unpack("I", content[:4])[0])
xml_len = int.from_bytes(content[:4], byteorder='big')
xml_content = content[4: xml_len + 4]
print("xml_content", xml_content)
return xml_content
def api_text(self, request: WSGIRequest | Request, *args, **kwargs):
"""
:param request:
:param args:
:param kwargs:
:return:
"""
print("============")
file_path = f"{settings.BASE_DIR}/django_公共认证接口/WW_verify_EhbJf3fcwi8bNijV.txt"
file_text = Path(file_path).read_text()
return HttpResponse(content=file_text)
def api_get(self, request: Request):
"""接受微信发过来的get请求,拿到参数后解决,并且回复值,结果为验证成功"""
GET_OBJ = request.query_params
signature = jmespath.search(data=GET_OBJ, expression="msg_signature", )
timestamp = jmespath.search(data=GET_OBJ, expression="timestamp", )
nonce = jmespath.search(data=GET_OBJ, expression="nonce", )
echostr = jmespath.search(data=GET_OBJ, expression="echostr", )
# TODO:sorted([token, timestamp, nonce])这是就是对三个参数进行字典排序
hashstr = "".join(sorted([self.token, timestamp, nonce, echostr])) # 这是就是对三个参数进行字典排序
sig = hashlib.sha1(string=hashstr.encode()).hexdigest()
if sig == signature:
ret = self.解密GET消息(echostr=echostr) # 调用算法,返回解密后的数值
s = ret.decode().strip()
print("成功回调")
return HttpResponse(content=s)
else:
print("没有验yghd成功")
return None
def 添加企业客户事件(self, as_data):
"""https://developer.work.weixin.qq.com/document/path/92130#%E6%B7%BB%E5%8A%A0%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%88%B7%E4%BA%8B%E4%BB%B6"""
pass
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 添加企业客户事件")
wecom_data = wecomData(as_data=as_data) # 解析返回的数据,拿到对应的值
res_welcom_code = wecom消息推送.发送新客户欢迎语(CALLBACK_CODE=wecom_data.WelcomeCode)
# 这里还需要判断, 是否要给上一级的对象添加 积分(得从用户中查看是否为推广员)
self.单独处理新添加用户的数据存储(UserID=wecom_data.UserID, ChangeType=wecom_data.ChangeType,
State=wecom_data.State, ExternalUserID=wecom_data.ExternalUserID,
)
def 外部联系人免验证添加成员事件(self, as_data):
"""https://developer.work.weixin.qq.com/document/path/92130#%E5%A4%96%E9%83%A8%E8%81%94%E7%B3%BB%E4%BA%BA%E5%85%8D%E9%AA%8C%E8%AF%81%E6%B7%BB%E5%8A%A0%E6%88%90%E5%91%98%E4%BA%8B%E4%BB%B6"""
pass
# 外部联系人添加了配置了客户联系功能且开启了免验证的成员时(此时成员尚未确认添加对方为好友),回调该事件
wecom_data = wecomData(as_data=as_data) # 解析返回的数据,拿到对应的值
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 外部联系人免验证添加成员事件")
# print(res_welcom_code)
def 删除企业客户事件(self, as_data):
"""https://developer.work.weixin.qq.com/document/path/92130#%E5%88%A0%E9%99%A4%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%88%B7%E4%BA%8B%E4%BB%B6"""
pass
def 好友主动删除企微(self, as_data):
""""""
wecom_data = wecomData(as_data=as_data)
pass
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 删除跟进成员事件")
def 删除跟进成员事件(self, as_data):
"""https://developer.work.weixin.qq.com/document/path/92130#%E5%88%A0%E9%99%A4%E8%B7%9F%E8%BF%9B%E6%88%90%E5%91%98%E4%BA%8B%E4%BB%B6"""
pass
# 配置了客户联系功能的成员被外部联系人删除时,回调该事件
wecom_data = wecomData(as_data=as_data) # 解析返回的数据,拿到对应的值
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 删除跟进成员事件")
def 客户接替失败事件(self, as_data):
"""https://developer.work.weixin.qq.com/document/path/92130#%E5%AE%A2%E6%88%B7%E6%8E%A5%E6%9B%BF%E5%A4%B1%E8%B4%A5%E4%BA%8B%E4%BB%B6"""
pass
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 客户接替失败事件")
# 企业将客户分配给新的成员接替后,客户添加失败时回调该事件
def 客户群创建事件(self, as_data):
""""""
# 有新增客户群时,回调该事件。收到该事件后,企业可以调用获取客户群详情接口获取客户群详情。
pass
def 客户群变更事件(self, as_data):
""""""
pass
wecom_data = wecomData(as_data=as_data)
print(wecom_data.UpdateDetail, "🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 这里的值是多少的呢?")
# https://developer.work.weixin.qq.com/document/path/92130#%E5%AE%A2%E6%88%B7%E7%BE%A4%E5%8F%98%E6%9B%B4%E4%BA%8B%E4%BB%B6
# 客户群被修改后(群名变更,群成员增加或移除,群主变更,群公告变更),回调该事件。收到该事件后,企业需要再调用获取客户群详情接口,以获取最新的群详情。
def 客户群解散事件(self, as_data):
"""
https://developer.work.weixin.qq.com/document/path/92130#%E5%AE%A2%E6%88%B7%E7%BE%A4%E8%A7%A3%E6%95%A3%E4%BA%8B%E4%BB%B6
"""
pass
# 当客户群被群主解散后,回调该事件。
wecom_data = wecomData(as_data=as_data) # 解析回调的数据
def 编辑企业客户事件(self, as_data):
"""https://developer.work.weixin.qq.com/document/path/92130#%E7%BC%96%E8%BE%91%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%88%B7%E4%BA%8B%E4%BB%B6"""
pass
# 配置了客户联系功能的成员修改外部联系人的备注、手机号或标签时,回调该事件
print("编辑企业客户事件编辑企业客户事件编辑企业客户事件", as_data)
def 获客链接_企业使用量即将耗尽事件(self, as_data):
""""""
pass
def 获客链接_使用量已经耗尽事件(self, as_data):
""""""
pass
def 获客链接_使用量增加事件事件(self, as_data):
""""""
pass
def 获客链接_获客链接异常事件(self, as_data):
""""""
pass
def 获客链接_删除获客链接事件(self, as_data):
""""""
pass
def 获客链接_获客使用量即将过期事件(self, as_data):
""""""
pass
def 获客链接_微信客户打开获客链接事件(self, as_data):
""""""
pass
def 获客链接_通过获客链接发起好友请求事件(self, as_data):
""""""
pass
def 获客链接_成员首次收消息事件(self, as_data):
""""""
pass
def 获客链接_成员多次收消息事件(self, as_data):
"""
参数 说明
ToUserName 企业微信CorpID
FromUserName 此事件该值固定为sys,表示该消息由系统生成
CreateTime 消息创建时间 (整型)
MsgType 消息的类型,此时固定为event
Event 固定为customer_acquisition
ChangeType 此时固定为message_from_customer
UserID 企业服务人员的UserID(2024年12月19号0点开始将不再回调该字段,请根据ChatKey参数查询收消息数据)
ExternalUserID 外部联系人的userid,注意不是企业成员的账号(2024年12月19号0点开始将不再回调该字段,请根据ChatKey参数查询收消息数据)
LinkId 获客链接ID
ChatSeq 成员收到消息的次数(2024年12月19号0点开始将不再回调该字段,请根据ChatKey参数查询收消息数据)
ChatKey 成员收消息的会话信息凭据,可通过调用获取获客链接使用成员接受消息数据接口获取详细的收消息信息,回调后30分钟内有效
应用可以根据ExternalUserID调用“获取客户详情”读取详情。
目前仅对微信客户支持此事件
"""
pass
def api_post(self, request: WSGIRequest | Request, *args, **kwargs):
""""""
as_dict = self.解密POST消息(msg_content=request.body)
wecom_data = wecomData(as_data=as_dict) # 创建了对象
print(as_dict, "回调接口回调成功了啦:sixwecom测试")
Event = pydash.get(obj=as_dict, path="xml.Event") # change_external_contact 事件的类型,此时固定为change_external_contact
print(Event)
ChangeType = pydash.get(obj=as_dict, path="xml.ChangeType") # add_external_contact 此时固定为add_external_contact
# TODO 以下为添加好友相关的接口调用事件
if Event == "change_external_contact" and ChangeType == "add_external_contact": # 好友主动添加企微回调
self.添加企业客户事件(as_data=as_dict)
# six企微回调业务处理方法().添加企业客户事件(as_data=as_dict)
# TODO 以下为删除好友
if Event == "change_external_contact" and ChangeType == "del_external_contact":
print("企微主动删除好友") # 企微主动删除好友
self.企微主动删除好友事件(UserID=wecom_data.UserID, ExternalUserID=wecom_data.ExternalUserID,
State=wecom_data.State, ChangeType=wecom_data.ChangeType,
)
if Event == "change_external_contact" and ChangeType == "del_follow_user":
print("好友主动删除企微", wecom_data) # 好友主动删除
self.好友主动删除企微事件(UserID=wecom_data.UserID, ExternalUserID=wecom_data.ExternalUserID,
State=wecom_data.State, ChangeType=wecom_data.ChangeType,
)
# TODO 编辑外部联系人好友回调事件
if Event == "change_external_contact" and ChangeType == "edit_external_contact":
self.编辑企业客户事件(as_data=as_dict)
# TODO 外部联系人免验证添加成员事件 外部联系人添加了配置了客户联系功能且开启了免验证的成员时(此时成员尚未确认添加对方为好友),回调该事件
if Event == "change_external_contact" and ChangeType == "add_half_external_contact":
self.外部联系人免验证添加成员事件(as_data=as_dict)
# TODO 以下为群相关的接口调用事件
# 客户群创建事件 有新增客户群时,回调该事件。收到该事件后,企业可以调用获取客户群详情接口获取客户群详情。
if Event == "change_external_chat" and ChangeType == "create":
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ", "客户群创建事件")
self.客户群创建事件(as_data=as_dict)
# 客户群被修改后(群名变更,群成员增加或移除,群主变更,群公告变更),回调该事件。收到该事件后,企业需要再调用获取客户群详情接口,以获取最新的群详情。
if Event == "change_external_chat" and ChangeType == "update":
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ", "客户群变更事件")
self.客户群变更事件(as_data=as_dict)
# 群解散事件
if Event == "change_external_chat" and ChangeType == "dismiss":
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ", "客户群解散事件")
self.客户群解散事件(as_data=as_dict)
# TODO 以下为标签相关的接口调用事件
# 企业客户标签创建事件
if Event == "change_external_tag" and ChangeType == "create":
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ", "企业客户标签创建事件")
# 企业客户标签变更事件当企业客户标签/标签组(包括规则组的标签)被修改时,回调此事件。收到该事件后,企业需要调用获取企业标签库来获取标签/标签组的详细信息。
if Event == "change_external_tag" and ChangeType == "update":
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ", "企业客户标签变更事件")
self.客户群变更事件(as_data=as_dict)
# 企业客户标签删除事件 当企业客户标签/标签组被删除时,回调此事件。删除标签组时,该标签组下的所有标签将被同时删除,但不会进行回调。
if Event == "change_external_tag" and ChangeType == "delete":
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ", "企业客户标签删除事件")
if Event == "change_external_tag" and ChangeType == "shuffle":
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ", "企业客户标签重排事件")
# 企业使用量即将耗尽事件
if Event == "customer_acquisition" and ChangeType == "balance_low":
pass
print("🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 ", "获客链接_企业使用量即将耗尽事件")
self.获客链接_企业使用量即将耗尽事件(as_data=as_dict)
# 当获客助手的使用量已经消耗完时,回调此事件
if Event == "customer_acquisition" and ChangeType == "balance_exhausted":
pass
self.获客链接_使用量已经耗尽事件(as_data=as_dict)
# 当获客助手的使用量从0变到非0时,回调此事件。
if Event == "customer_acquisition" and ChangeType == "balance_increased":
pass
self.获客链接_使用量增加事件事件(as_data=as_dict)
# 获客链接异常事件
if Event == "customer_acquisition" and ChangeType == "link_unavailable":
# 若链接中的成员暂时无法添加客户时,会在分配时自动跳过该成员。当链接中配置的全部成员账号异常,暂时无法继续添加客户时,回调此事件到创建相应链接的应用,可及时调整链接配置或流量曝光策略,避免流量浪费。
pass
self.获客链接_获客链接异常事件(as_data=as_dict)
if Event == "customer_acquisition" and ChangeType == "delete_link":
# 当API创建的获客链接在管理端或终端被删除时,回调此事件到创建相应链接的应用。
pass
self.获客链接_删除获客链接事件(as_data=as_dict)
# 获客使用量即将过期事件 当企业购买的获客助手使用量即将过期时,将在过期前的14天、7天、3天、2天及1天回调此事件。
if Event == "customer_acquisition" and ChangeType == "quota_expire_soon":
pass
self.获客链接_获客使用量即将过期事件(as_data=as_dict)
# 微信客户打开获客链接事件 当微信客户通过获客链接进入成员的profile页时,回调此事件。仅部分经营类目企业支持,当前企业是否支持可在「高级功能-获客助手」中查看该类目对应的功能是否包含「链接打开回调」
if Event == "customer_acquisition" and ChangeType == "open_profile":
pass
self.获客链接_微信客户打开获客链接事件(as_data=as_dict)
# 通过获客链接发起好友请求事件 当微信用户通过获客链接点击添加到通讯录,成功发起好友请求,回调此事件到创建该链接的应用。
if Event == "customer_acquisition" and ChangeType == "friend_request":
pass
self.获客链接_通过获客链接发起好友请求事件(as_data=as_dict)
# 成员首次收消息事件 授权企业中配置了客户联系功能的成员通过获客链接添加微信客户后,当成员首次收到客户消息时,回调此事件到创建相应链接的应用。
if Event == "customer_acquisition" and ChangeType == "customer_start_chat":
pass
self.获客链接_成员首次收消息事件(as_data=as_dict)
# 成员多次收消息事件授权企业中配置了客户联系功能的成员通过获客链接添加微信客户后,当成员第3、5、10次收到客户消息时,回调此事件到创建相应链接的应用。该事件仅在获客助手内测期限时免费提供。
# 注:3次、5次、10次为近期新增统计,仅能针对上线后才第1次收到消息的客户生效。
if Event == "customer_acquisition" and ChangeType == "message_from_customer":
pass
self.获客链接_通过获客链接发起好友请求事件(as_data=as_dict)
return Response(data={"message": "xiao方法被调用了"}, status=status.HTTP_200_OK)