事件回调修改

This commit is contained in:
AKW 2023-12-25 11:06:08 +08:00
parent c187d106cf
commit c935be72f5
7 changed files with 220 additions and 25 deletions

65
apps/jqr/pubsub.py Normal file
View File

@ -0,0 +1,65 @@
import json
import logging
import os
import time
from django_redis import get_redis_connection
from django.conf import settings
from threading import Thread
from yzk_wechat_event.settings.constant import Constant
from django.utils.module_loading import import_string
logger = logging.getLogger('apps')
class JQREventCallbackPubSub:
rc = get_redis_connection()
@classmethod
def publish(cls, data):
cls.rc.lpush(Constant.JQR_EVENT_CALLBACK_PUBSUB_CHANNEL, json.dumps(data))
@classmethod
def event_callback_listener(cls):
while True:
data = cls.rc.brpop(Constant.JQR_EVENT_CALLBACK_PUBSUB_CHANNEL, 5)
if data is None:
time.sleep(5)
continue
data = json.loads(data[1])
callback_data = json.loads(data['data'])
corpinfo = data['corpinfo']
handler = data['handler']
handler = import_string(handler)
handler(callback_data, corpinfo)
class JQRQrcodeCallbackPubSub:
rc = get_redis_connection()
@classmethod
def publish(cls, data):
cls.rc.lpush(Constant.JQR_QRCODE_PUBSUB_CHANNEL, json.dumps(data))
@classmethod
def qrcode_callback_listener(cls):
while True:
data = cls.rc.brpop(Constant.JQR_QRCODE_PUBSUB_CHANNEL, 5)
if data is None:
time.sleep(5)
continue
data = json.loads(data[1])
qrcodeid = data['qrcodeid']
userid = data['userid']
externaluserid = data['externaluserid']
corpinfo = data['corpinfo']
handler = data['handler']
handler = import_string(handler)
handler(qrcodeid, userid, externaluserid, corpinfo)
t = Thread(target=JQREventCallbackPubSub.event_callback_listener)
t.start()
t2 = Thread(target=JQRQrcodeCallbackPubSub.qrcode_callback_listener)
t2.start()

View File

@ -1,10 +1,14 @@
import base64
import json
from datetime import datetime
from django.utils.module_loading import import_string
from rest_framework import serializers
from apps.jqr.models import JqrHookUser
from apps.jqr.tasks import save_add_contact, delete_add_contact, edit_add_contact
from apps.jqr.pubsub import JQREventCallbackPubSub
from apps.jqr.tasks import save_add_contact, delete_add_contact, edit_add_contact, save_add_contact_by_channel, \
edit_add_contact_by_channel, delete_add_contact_by_channel
from apps.msg.models import TbMessage
from apps.msg.utils import JQRMSGPubSubUtils
from apps.qc.choices import QcCorpInfoCallbackStatusChoices
@ -100,9 +104,16 @@ class WechatEncryptSerializer(serializers.Serializer):
state = data.get('state')
data['corpid'] = corp.corpid
if state and state.startswith('mg') and '_' in state:
[_, _, qrcodeid] = state.split('_')
data['qrcodeid'] = qrcodeid
data['agentid'] = corp.agentid
data['uid'] = corp.uid
save_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
# save_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
JQREventCallbackPubSub.publish({
'handler': f'{save_add_contact_by_channel.__module__}.{save_add_contact_by_channel.__name__}',
'data': json.dumps(data),
'corpinfo': corp.to_dict(['corpid', 'appsecret']),
})
def handle_change_external_contact_edit_external_contact(self, data):
"""
@ -115,9 +126,16 @@ class WechatEncryptSerializer(serializers.Serializer):
state = data.get('state')
data['corpid'] = corp.corpid
if state and state.startswith('mg') and '_' in state:
[_, _, qrcodeid] = state.split('_')
data['qrcodeid'] = qrcodeid
data['agentid'] = corp.agentid
data['uid'] = corp.uid
edit_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
# edit_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
JQREventCallbackPubSub.publish({
'handler': f'{edit_add_contact_by_channel.__module__}.{save_add_contact_by_channel.__name__}',
'data': json.dumps(data),
'corpinfo': corp.to_dict(['corpid', 'appsecret']),
})
def handle_change_external_contact_add_half_external_contact(self, data):
"""
@ -130,9 +148,16 @@ class WechatEncryptSerializer(serializers.Serializer):
state = data.get('state')
data['corpid'] = corp.corpid
if state and state.startswith('mg') and '_' in state:
[_, _, qrcodeid] = state.split('_')
data['qrcodeid'] = qrcodeid
data['agentid'] = corp.agentid
data['uid'] = corp.uid
save_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
# save_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
JQREventCallbackPubSub.publish({
'handler': f'{save_add_contact_by_channel.__module__}.{save_add_contact_by_channel.__name__}',
'data': json.dumps(data),
'corpinfo': corp.to_dict(['corpid', 'appsecret']),
})
def handle_change_external_contact_del_follow_user(self, data):
"""
@ -147,7 +172,12 @@ class WechatEncryptSerializer(serializers.Serializer):
if state and state.startswith('mg') and '_' in state:
data['agentid'] = corp.agentid
data['uid'] = corp.uid
delete_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
# delete_add_contact.delay(data, corp.to_dict(['corpid', 'appsecret']))
JQREventCallbackPubSub.publish({
'handler': f'{delete_add_contact_by_channel.__module__}.{delete_add_contact.__name__}',
'data': json.dumps(data),
'corpinfo': corp.to_dict(['corpid', 'appsecret']),
})
def handle_change_external_chat_create(self, data):
"""

View File

@ -5,6 +5,7 @@ import logging
from django.db.models import Count, Sum, When, Case, Value
from apps.jqr.choices import JqrWechatbizuserinfoDeleteTypeChoices, JqrAddTypeChoices
from apps.jqr.pubsub import JQRQrcodeCallbackPubSub
from apps.qc.choices import QcWechatbizeventAddcontactIsDeleteChoices, QcQrcodesEditLogOperateTypeChoices, \
QcQrcodesEditLogTypeChoices
from apps.qc.models import QcWechatbizeventAddcontact, QcQrcodes, QcWechatbizuserinfo, QcQrcodesEditLog, QcCorpinfo
@ -48,6 +49,36 @@ def save_add_contact(data, corpinfo, *args, **kwargs):
# TODO 请求API 发送消息
def save_add_contact_by_channel(data, corpinfo, *args, **kwargs):
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,
'ctime': datetime.now(),
}
)
qrcodeid = data.get('qrcodeid')
if qrcodeid:
JQRQrcodeCallbackPubSub.publish({
'qrcodeid': qrcodeid,
'userid': userid,
'externaluserid': externaluserid,
'corpinfo': corpinfo,
'handler': f'{qrcode_channel_handler.__module__}.{qrcode_channel_handler.__name__}'
})
# 修复客户关系
edit_add_contact(data, corpinfo, *args, **kwargs)
# TODO 请求API 发送消息
@shared_task(name='edit_add_contact', queue='contact')
def edit_add_contact(data, corpinfo, *args, **kwargs):
# 更新 关系表
@ -88,6 +119,45 @@ def edit_add_contact(data, corpinfo, *args, **kwargs):
)
def edit_add_contact_by_channel(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')
@ -106,6 +176,23 @@ def delete_add_contact(data, corpinfo, *args, **kwargs):
)
def delete_add_contact_by_channel(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()
)
@shared_task(name='check_qrcode', queue='qrcode')
def check_qrcode(qrcodeid, userid, corpinfo):
qrcode = QcQrcodes.objects.get(id=qrcodeid)
@ -414,3 +501,10 @@ def online_qrcode():
type=QcQrcodesEditLogTypeChoices.AUTO,
operatetype=QcQrcodesEditLogOperateTypeChoices.ONLINE,
)
def qrcode_channel_handler(qrcodeid, userid, externaluserid, corpinfo):
check_qrcode(qrcodeid, userid, corpinfo)
alarm_userid_by_qrcodeid(qrcodeid)
# 打标签备注
tag_remark_contact(qrcodeid, userid, externaluserid, corpinfo)

View File

@ -1,6 +1,7 @@
import json
import logging
import os
import time
from django_redis import get_redis_connection
from django.conf import settings
@ -31,6 +32,7 @@ def listen():
print(JQRMSGPubSubUtils.msg_list)
TbMessage.objects.bulk_create(JQRMSGPubSubUtils.msg_list)
JQRMSGPubSubUtils.msg_list = []
time.sleep(5)
continue
data = json.loads(data[1])
serializer = TbMessageModelSerializer(data=data)
@ -41,5 +43,6 @@ def listen():
JQRMSGPubSubUtils.msg_list.clear()
t = Thread(target=listen)
t.start()
if not settings.DEBUG:
t = Thread(target=listen)
t.start()

View File

@ -16,16 +16,16 @@ services:
networks:
- yzk_wechat_event
celery_worker:
container_name: yzk_wechat_event-celery_worker
build:
context: .
dockerfile: ./Dockerfile
command: ./start-celeryworker
volumes:
- .:/app
networks:
- yzk_wechat_event
# celery_worker:
# container_name: yzk_wechat_event-celery_worker
# build:
# context: .
# dockerfile: ./Dockerfile
# command: ./start-celeryworker
# volumes:
# - .:/app
# networks:
# - yzk_wechat_event
networks:
yzk_wechat_event:

View File

@ -15,14 +15,14 @@ app.autodiscover_tasks()
# 定时任务的调度列表,用于注册定时任务
app.conf.beat_schedule = {
'online_qrcode': {
'task': 'online_qrcode',
'schedule': crontab(minute="0", hour="0"),
},
'check_follow_user': {
'task': 'check_follow_user',
'schedule': timedelta(minutes=3),
},
# 'online_qrcode': {
# 'task': 'online_qrcode',
# 'schedule': crontab(minute="0", hour="0"),
# },
# 'check_follow_user': {
# 'task': 'check_follow_user',
# 'schedule': timedelta(minutes=3),
# },
}
task_routes = {

View File

@ -4,6 +4,9 @@ class Constant:
WECHAT_WORKER_TOKEN = 'wechat:worker:token:'
WECHAT_WORKER_TOKEN_EXPIRES = 6000
JQR_MSG_PUBSUB_CHANNEL = 'jqr:msg'
JQR_EVENT_CALLBACK_PUBSUB_CHANNEL = 'jqr:event:cb'
JQR_EVENT_CALLBACK_TYPE = ''
JQR_QRCODE_PUBSUB_CHANNEL = 'jqr:qrcode'
ONE = 1
TWO = 2
THREE = 3