事件回调修改

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 base64
import json
from datetime import datetime from datetime import datetime
from django.utils.module_loading import import_string
from rest_framework import serializers from rest_framework import serializers
from apps.jqr.models import JqrHookUser 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.models import TbMessage
from apps.msg.utils import JQRMSGPubSubUtils from apps.msg.utils import JQRMSGPubSubUtils
from apps.qc.choices import QcCorpInfoCallbackStatusChoices from apps.qc.choices import QcCorpInfoCallbackStatusChoices
@ -100,9 +104,16 @@ class WechatEncryptSerializer(serializers.Serializer):
state = data.get('state') state = data.get('state')
data['corpid'] = corp.corpid data['corpid'] = corp.corpid
if state and state.startswith('mg') and '_' in state: if state and state.startswith('mg') and '_' in state:
[_, _, qrcodeid] = state.split('_')
data['qrcodeid'] = qrcodeid
data['agentid'] = corp.agentid data['agentid'] = corp.agentid
data['uid'] = corp.uid 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): def handle_change_external_contact_edit_external_contact(self, data):
""" """
@ -115,9 +126,16 @@ class WechatEncryptSerializer(serializers.Serializer):
state = data.get('state') state = data.get('state')
data['corpid'] = corp.corpid data['corpid'] = corp.corpid
if state and state.startswith('mg') and '_' in state: if state and state.startswith('mg') and '_' in state:
[_, _, qrcodeid] = state.split('_')
data['qrcodeid'] = qrcodeid
data['agentid'] = corp.agentid data['agentid'] = corp.agentid
data['uid'] = corp.uid 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): def handle_change_external_contact_add_half_external_contact(self, data):
""" """
@ -130,9 +148,16 @@ class WechatEncryptSerializer(serializers.Serializer):
state = data.get('state') state = data.get('state')
data['corpid'] = corp.corpid data['corpid'] = corp.corpid
if state and state.startswith('mg') and '_' in state: if state and state.startswith('mg') and '_' in state:
[_, _, qrcodeid] = state.split('_')
data['qrcodeid'] = qrcodeid
data['agentid'] = corp.agentid data['agentid'] = corp.agentid
data['uid'] = corp.uid 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): 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: if state and state.startswith('mg') and '_' in state:
data['agentid'] = corp.agentid data['agentid'] = corp.agentid
data['uid'] = corp.uid 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): 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 django.db.models import Count, Sum, When, Case, Value
from apps.jqr.choices import JqrWechatbizuserinfoDeleteTypeChoices, JqrAddTypeChoices from apps.jqr.choices import JqrWechatbizuserinfoDeleteTypeChoices, JqrAddTypeChoices
from apps.jqr.pubsub import JQRQrcodeCallbackPubSub
from apps.qc.choices import QcWechatbizeventAddcontactIsDeleteChoices, QcQrcodesEditLogOperateTypeChoices, \ from apps.qc.choices import QcWechatbizeventAddcontactIsDeleteChoices, QcQrcodesEditLogOperateTypeChoices, \
QcQrcodesEditLogTypeChoices QcQrcodesEditLogTypeChoices
from apps.qc.models import QcWechatbizeventAddcontact, QcQrcodes, QcWechatbizuserinfo, QcQrcodesEditLog, QcCorpinfo from apps.qc.models import QcWechatbizeventAddcontact, QcQrcodes, QcWechatbizuserinfo, QcQrcodesEditLog, QcCorpinfo
@ -48,6 +49,36 @@ def save_add_contact(data, corpinfo, *args, **kwargs):
# TODO 请求API 发送消息 # 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') @shared_task(name='edit_add_contact', queue='contact')
def edit_add_contact(data, corpinfo, *args, **kwargs): 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') @shared_task(name='delete_add_contact', queue='contact')
def delete_add_contact(data, corpinfo, *args, **kwargs): def delete_add_contact(data, corpinfo, *args, **kwargs):
userid = data.get('userid') 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') @shared_task(name='check_qrcode', queue='qrcode')
def check_qrcode(qrcodeid, userid, corpinfo): def check_qrcode(qrcodeid, userid, corpinfo):
qrcode = QcQrcodes.objects.get(id=qrcodeid) qrcode = QcQrcodes.objects.get(id=qrcodeid)
@ -414,3 +501,10 @@ def online_qrcode():
type=QcQrcodesEditLogTypeChoices.AUTO, type=QcQrcodesEditLogTypeChoices.AUTO,
operatetype=QcQrcodesEditLogOperateTypeChoices.ONLINE, 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 json
import logging import logging
import os import os
import time
from django_redis import get_redis_connection from django_redis import get_redis_connection
from django.conf import settings from django.conf import settings
@ -31,6 +32,7 @@ def listen():
print(JQRMSGPubSubUtils.msg_list) print(JQRMSGPubSubUtils.msg_list)
TbMessage.objects.bulk_create(JQRMSGPubSubUtils.msg_list) TbMessage.objects.bulk_create(JQRMSGPubSubUtils.msg_list)
JQRMSGPubSubUtils.msg_list = [] JQRMSGPubSubUtils.msg_list = []
time.sleep(5)
continue continue
data = json.loads(data[1]) data = json.loads(data[1])
serializer = TbMessageModelSerializer(data=data) serializer = TbMessageModelSerializer(data=data)
@ -41,5 +43,6 @@ def listen():
JQRMSGPubSubUtils.msg_list.clear() JQRMSGPubSubUtils.msg_list.clear()
t = Thread(target=listen) if not settings.DEBUG:
t.start() t = Thread(target=listen)
t.start()

View File

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

View File

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

View File

@ -4,6 +4,9 @@ class Constant:
WECHAT_WORKER_TOKEN = 'wechat:worker:token:' WECHAT_WORKER_TOKEN = 'wechat:worker:token:'
WECHAT_WORKER_TOKEN_EXPIRES = 6000 WECHAT_WORKER_TOKEN_EXPIRES = 6000
JQR_MSG_PUBSUB_CHANNEL = 'jqr:msg' 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 ONE = 1
TWO = 2 TWO = 2
THREE = 3 THREE = 3