回调地址调整

This commit is contained in:
AKW 2023-12-14 18:43:01 +08:00
parent cdeda772c5
commit bfffdf48fc
6 changed files with 203 additions and 30 deletions

View File

@ -2,6 +2,7 @@ import base64
from rest_framework import serializers from rest_framework import serializers
from apps.jqr.tasks import save_add_contact, delete_add_contact, edit_add_contact
from libs.weworkapi.callback.WXBizMsgCrypt3 import WXBizMsgCrypt, Prpcrypt from libs.weworkapi.callback.WXBizMsgCrypt3 import WXBizMsgCrypt, Prpcrypt
from utils.tools import sha1_encoder, get_attribute, camel_to_snake from utils.tools import sha1_encoder, get_attribute, camel_to_snake
import xml.etree.cElementTree as ET import xml.etree.cElementTree as ET
@ -50,8 +51,9 @@ class WechatEncryptSerializer(serializers.Serializer):
data = self.parse_xml(xmltext) data = self.parse_xml(xmltext)
print(data) print(data)
event = data.get('event') event = data.get('event')
change_type = data.get('change_type') changetype = data.get('changetype')
event_handler = getattr(self, f'handle_{event}_{change_type}', None) event_handler = getattr(self, f'handle_{event}_{changetype}', None)
print(f'handle_{event}_{changetype}')
if event_handler: if event_handler:
event_handler(data) event_handler(data)
return {} return {}
@ -75,17 +77,79 @@ class WechatEncryptSerializer(serializers.Serializer):
for child in xml_tree: for child in xml_tree:
tag = child.tag tag = child.tag
key = camel_to_snake(tag) key = camel_to_snake(tag)
data[key] = get_attribute(xml_tree.find(key), 'text') key = ''.join(key.split('_'))
data[key] = get_attribute(xml_tree.find(tag), 'text')
return data return data
def handle_change_external_contact_add_external_contact(self, data): def handle_change_external_contact_add_external_contact(self, data):
""" """
处理添加企业客户事件 处理添加企业客户事件
""" """
print('添加客户事件')
corp = self.context.get('corp')
data.pop('tousername')
data['corpid'] = corp.corpid
data['agentid'] = corp.agentid
data['uid'] = corp.uid
print(data) print(data)
save_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
def handle_change_external_contact_edit_external_contact(self, data): def handle_change_external_contact_edit_external_contact(self, data):
""" """
处理编辑企业客户事件 处理编辑企业客户事件
""" """
pass print('编辑客户事件')
corp = self.context.get('corp')
data.pop('tousername')
data['corpid'] = corp.corpid
data['agentid'] = corp.agentid
data['uid'] = corp.uid
print(data)
edit_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
def handle_change_external_contact_add_half_external_contact(self, data):
"""
处理外部联系人免验证添加成员事件
"""
print('外部联系人免验证添加成员事件')
corp = self.context.get('corp')
data.pop('tousername')
data['corpid'] = corp.corpid
data['agentid'] = corp.agentid
data['uid'] = corp.uid
print(data)
save_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
def handle_change_external_contact_del_follow_user(self, data):
"""
处理删除跟进成员事件 (客户删我们)
"""
print('删除跟进成员事件')
corp = self.context.get('corp')
data.pop('tousername')
data['corpid'] = corp.corpid
data['agentid'] = corp.agentid
data['uid'] = corp.uid
print(data)
delete_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
def handle_change_external_chat_create(self, data):
"""
处理客户群创建事件
"""
print('客户群创建事件')
print(data)
def handle_change_external_chat_update(self, data):
"""
处理客户群更新事件
"""
print('客户群更新事件')
print(data)
def handle_change_external_chat_dismiss(self, data):
"""
处理客户群解散事件
"""
print('客户群解散事件')
print(data)

View File

@ -1,11 +1,92 @@
from celery import shared_task from celery import shared_task
from datetime import datetime
import logging import logging
from apps.jqr.choices import JqrWechatbizuserinfoDeleteTypeChoices, JqrAddTypeChoices
from apps.qc.choices import QcWechatbizeventAddcontactIsDeleteChoices
from apps.qc.models import QcWechatbizeventAddcontact
from apps.jqr.models import JqrExternalFollowUser, JqrExternalUser
from libs.wechat import WechatWorkerUtil
logger = logging.getLogger('apps') logger = logging.getLogger('apps')
@shared_task(name='save_add_contact') @shared_task(name='save_add_contact', queue='contact')
def save_add_contact(*args, **kwargs): def save_add_contact(data, corpinfo, *args, **kwargs):
logger.info('save_add_contact') state = data.get('state')
while True: if state and state.startswith('mg'):
pass [_, _, qrcodeid] = state.split('_')
data['qrcodeid'] = qrcodeid
# TODO 处理我们自己的活码
userid = data.get('userid')
externaluserid = data.get('externaluserid')
corpid = data.get('corpid')
QcWechatbizeventAddcontact.objects.update_or_create(
userid=userid,
externaluserid=externaluserid,
corpid=corpid,
defaults={
**data,
'isdelete': QcWechatbizeventAddcontactIsDeleteChoices.NOT_DELETE,
'deletetime': None
}
)
edit_add_contact.delay(data, corpinfo, *args, **kwargs)
@shared_task(name='edit_add_contact', queue='contact')
def edit_add_contact(data, corpinfo, *args, **kwargs):
# 更新 关系表
externaluserid = data.get('externaluserid')
corpid = corpinfo.get('corpid')
appsecret = corpinfo.get('appsecret')
wechat_worker = WechatWorkerUtil(corpid, appsecret)
cursor = ''
while cursor is not None:
success, data = wechat_worker.get_external_contact(externaluserid, cursor=cursor)
if not success:
logger.error(f'获取外部联系人信息失败,{data}')
return
(external_contact, follow_user, cursor) = data
JqrExternalUser.objects.update_or_create(
corpid=corpid,
external_userid=externaluserid,
defaults={
**external_contact,
'addtype': JqrAddTypeChoices.EVENT_CALLBACK,
'deletetype': None,
'dtime': None
}
)
for follow_info in follow_user:
userid = follow_info.get('userid')
follow_info['tags'] = [tag.get('tag_id') for tag in follow_info.get('tags', [])]
JqrExternalFollowUser.objects.update_or_create(
userid=userid,
corpid=corpid,
external_userid=externaluserid,
defaults={
**follow_info,
'addtype': JqrAddTypeChoices.EVENT_CALLBACK,
'deletetype': None,
'dtime': None
}
)
@shared_task(name='delete_add_contact', queue='contact')
def delete_add_contact(data, corpinfo, *args, **kwargs):
userid = data.get('userid')
externaluserid = data.get('externaluserid')
corpid = data.get('corpid')
agentid = data.get('agentid')
# 更新add_contact 表删除字段
QcWechatbizeventAddcontact.objects.filter(userid=userid, externaluserid=externaluserid, corpid=corpid,
agentid=agentid).update(
isdelete=QcWechatbizeventAddcontactIsDeleteChoices.DELETED,
deletetime=datetime.now()
)
JqrExternalFollowUser.objects.filter(userid=userid, external_userid=externaluserid, corpid=corpid).update(
deletetype=JqrWechatbizuserinfoDeleteTypeChoices.EVENT_CALLBACK,
dtime=datetime.now()
)

View File

@ -15,13 +15,13 @@ class WechatWorkerViewSet(viewsets.GenericViewSet):
@action(methods=['GET'], detail=False, serializer_class=WechatPublicTokenSerializer, @action(methods=['GET'], detail=False, serializer_class=WechatPublicTokenSerializer,
url_path=r'callback/(?P<path>\w+)', ) url_path=r'callback/(?P<path>\w+)', )
def verify(self, request, path, *args, **kwargs): def verify(self, request, path, *args, **kwargs):
if not settings.DEBUG: # if not settings.DEBUG:
params = request.query_params # params = request.query_params
# cbtest.xbtool.cn # # cbtest.xbtool.cn
url = f'https://46i859447w.yicp.fun/event/callback/{path}' # url = f'https://46i859447w.yicp.fun/event/callback/{path}'
res = requests.get(url, params=params) # res = requests.get(url, params=params)
data = res.text # data = res.text
return Response(data=int(data)) # return Response(data=int(data))
[business, corpid, agentid, uid] = path.split('_') [business, corpid, agentid, uid] = path.split('_')
corp = QcCorpinfo.objects.get(corpid=corpid, agentid=agentid, uid=uid) corp = QcCorpinfo.objects.get(corpid=corpid, agentid=agentid, uid=uid)
@ -35,14 +35,14 @@ class WechatWorkerViewSet(viewsets.GenericViewSet):
@verify.mapping.post @verify.mapping.post
def message(self, request, path, *args, **kwargs): def message(self, request, path, *args, **kwargs):
if not settings.DEBUG: # if not settings.DEBUG:
data = request.data # data = request.data
# cbtest.xbtool.cn # # cbtest.xbtool.cn
renderer = WechatPublicContentRenderer() # renderer = WechatPublicContentRenderer()
data = renderer.render(data) # data = renderer.render(data)
url = f'https://46i859447w.yicp.fun/event/callback/{path}' # url = f'https://46i859447w.yicp.fun/event/callback/{path}'
res = requests.post(url, data=data, headers={'Content-Type': 'text/xml'}) # res = requests.post(url, data=data, headers={'Content-Type': 'text/xml'})
return Response(data=res.json()) # return Response(data=res.json())
[business, corpid, agentid, uid] = path.split('_') [business, corpid, agentid, uid] = path.split('_')
corp = QcCorpinfo.objects.get(corpid=corpid, agentid=agentid, uid=uid) corp = QcCorpinfo.objects.get(corpid=corpid, agentid=agentid, uid=uid)
context = self.get_serializer_context() context = self.get_serializer_context()

View File

@ -34,6 +34,30 @@ class QcCorpinfo(models.Model):
ordering = ['-ctime'] ordering = ['-ctime']
unique_together = ('agentid', 'corpid', 'uid', 'business_type') unique_together = ('agentid', 'corpid', 'uid', 'business_type')
def to_dict(self, fields=None):
if fields:
return {
field: getattr(self, field)
for field in fields
}
return {
'id': self.id,
'uid': self.uid,
'corpname': self.corpname,
'corpid': self.corpid,
'agentid': self.agentid,
'appsecret': self.appsecret,
'token': self.token,
'encodingaeskey': self.encodingaeskey,
'ctime': self.ctime,
'utime': self.utime,
'callbackstatus': self.callbackstatus,
'callback_validate_time': self.callback_validate_time,
'business_type': self.business_type,
'taggroupid': self.taggroupid,
'settletaggroupid': self.settletaggroupid,
}
class QcQrcodes(models.Model): class QcQrcodes(models.Model):
id = models.BigAutoField(primary_key=True) id = models.BigAutoField(primary_key=True)
@ -114,11 +138,12 @@ class QcWechatbizeventAddcontact(models.Model):
isdelete = models.IntegerField(default=QcWechatbizeventAddcontactIsDeleteChoices.NOT_DELETE, isdelete = models.IntegerField(default=QcWechatbizeventAddcontactIsDeleteChoices.NOT_DELETE,
verbose_name="是否删除", choices=QcWechatbizeventAddcontactIsDeleteChoices.choices) verbose_name="是否删除", choices=QcWechatbizeventAddcontactIsDeleteChoices.choices)
deletetime = models.DateTimeField(null=True, verbose_name="删除时间") deletetime = models.DateTimeField(null=True, verbose_name="删除时间")
qrcodeid = models.IntegerField(verbose_name='二维码id') qrcodeid = models.IntegerField(verbose_name='二维码id', default=0)
hook_starttime = models.DateTimeField(null=True, verbose_name="hook最近一次启动时间", blank=True)
hook_wstime = models.DateTimeField(null=True, verbose_name="hook最近一次websocket首发消息时间", blank=True) # hook_starttime = models.DateTimeField(null=True, verbose_name="hook最近一次启动时间", blank=True)
hook_connecttime = models.DateTimeField(null=True, verbose_name="hook最近一次通信时间", blank=True) # hook_wstime = models.DateTimeField(null=True, verbose_name="hook最近一次websocket首发消息时间", blank=True)
isfirststart = models.BooleanField(verbose_name="是否首次启动", null=True, blank=True) # hook_connecttime = models.DateTimeField(null=True, verbose_name="hook最近一次通信时间", blank=True)
# isfirststart = models.BooleanField(verbose_name="是否首次启动", null=True, blank=True)
class Meta: class Meta:
db_table = 'qc_wechatbizevent_addcontact' db_table = 'qc_wechatbizevent_addcontact'

View File

@ -143,7 +143,7 @@ class WechatWorkerUtil(object):
res = requests.get(url, params=params) res = requests.get(url, params=params)
res = res.json() res = res.json()
if res.get('errcode') == 0: if res.get('errcode') == 0:
return True, (res.get('external_contact'), res.get('follow_user')) return True, (res.get('external_contact'), res.get('follow_user'), res.get('next_cursor'))
return False, res.get('errmsg') return False, res.get('errmsg')
def get_external_contact_batch_by_user(self, userid_list, cursor='', limit=100): def get_external_contact_batch_by_user(self, userid_list, cursor='', limit=100):

View File

@ -21,6 +21,9 @@ app.conf.beat_schedule = {
} }
task_routes = { task_routes = {
'save_add_contact': 'contact',
'edit_add_contact': 'contact',
'delete_add_contact': 'contact',
} }
# #
app.conf.task_routes = task_routes app.conf.task_routes = task_routes