# coding=utf-8 from __future__ import absolute_import import json import random from datetime import timedelta, datetime from distutils.version import LooseVersion from django.conf import settings from django.db.models import Q, Count from celery import shared_task from gm_types.antispam import DocType from gm_types.gaia import AUTHOR_TYPE, TAG_TYPE, DIARY_ORDER_TYPE, QUESTION_ORDER_TYPE from gm_types.mimas import SPAM_LABEL, CONTENT_CLASS, SEND_ANSWER_STATUS, MEDIA_IMAGE_URL_SOURCE from gm_types.mimas import APPLET_PAGE_FROM, APPLET_SUBSCRIBE_MSG_TYPE from gm_types.push import PUSH_INFO_TYPE, AUTOMATED_PUSH from gm_upload.utils.image_utils import Picture from helios.rpc import RPCFaultException from gm_protocol import GmProtocol from talos.services.other import get_user_lastest_device_app_version_by_user_id from utils.protocol import gm_protocol from utils.rpc import rpc_client, logging_exception from utils.push import push_task_to_user_multi, limit_get_comment_push, vote_push, send_applet_subscribe_msg from qa.models import ( Answer, AnswerVote, Question, AnswerReply, QuestionInviter, QuestionTag, SendAnswer, QuestionImage, AnswerImage, AnswerVoteReply, AnswerTag, AnswerReplyImages) from talos.models.doctor import DoctorMessageList from talos.logger import qiniu_logger from qa.tasks.view import view_increase_amount from qa.utils import const_strings from qa.cache import ( high_quality_question_cache, question_inviter_cache, complains_question_cache, ) from qa.libs import get_media_extra_info, _get_content_text from talos.services import UserService, get_user_from_context from talos.portal import get_doctor_from_user_ids # 引用的是 talos services doctor 下的方法 from talos.tools.vote_tool import VoteTool from talos.cache.base import vote_cache from talos.cache.base import fake_vote_cache from communal.normal_manager import ( tag_manager, ) from talos.rpc import get_current_rpc_invoker from communal.tasks import intelligent_push_task @shared_task def add_answer_view(answer_ids=[]): for answer_id in answer_ids: view_increase_amount(const_strings.ANSWER_VIEW, answer_id, 1) @shared_task def add_question_view(question_ids=[]): for question_id in question_ids: view_increase_amount(const_strings.QUESTION_VIEW, question_id, 1) @shared_task def add_questions_view(question_ids): for question_id in question_ids: if question_id['question']: view_increase_amount(const_strings.QUESTION_VIEW, question_id['question'], 1) if question_id['qa']: view_increase_amount(const_strings.ANSWER_VIEW, question_id['qa'], 1) @shared_task def fake_vote_to_answer(repeat_times, answer_id, force_push=False): user_ids = rpc_client['api/user/get_sleep_user'](number=repeat_times).unwrap() add_fake_vote_to_answer(user_ids, answer_id, force_push=force_push) def add_fake_vote_to_answer(user_ids, answer_id, force_push=False): answer_fake_vote_key = "answer_fake_vote_{id}".format(id=answer_id) is_set = fake_vote_cache.set(answer_fake_vote_key, 1, nx=True, ex=30) if not is_set: return answer = Answer.objects.get(id=answer_id) push_url = gm_protocol.get_answer_list(answer=answer_id) content = _get_content_text(answer.content) content = (content[:25] + '...') if len(content) > 25 else content if not answer.is_online: return for user_id in user_ids: answer_vote, created = AnswerVote.objects.get_or_create(user=user_id, answer_id=answer.id, is_fake=True) if created: # 对作者增加点赞数 rpc_client['api/person/incr_vote'](user_id=user_id).unwrap() vt_v1 = VoteTool(vote_cache, answer.user_id, new_version=True) vt_v1.receive_answer_vote(answer_vote.id) vt_v1 = VoteTool(vote_cache, answer.user_id, new_version=True) vt_v1.receive_answer_vote(answer_vote.id) if force_push: try: user_name = UserService.get_user_by_user_id(user_id).nickname except: logging_exception() return vt_v1 = VoteTool(vote_cache, answer.user_id, new_version=True) vt_v1.receive_answer_vote(answer_vote.id) vote_push( user_id=answer.user_id, push_url=push_url, alert=u'{}赞了你的回复{}'.format(user_name, content), push_type=AUTOMATED_PUSH.ANSWER_GET_VOTE ) vote_count = AnswerVote.objects.filter(answer_id=answer.id).count() answer.like_num = vote_count answer.save() def bayes_antispam(doc_id, doc_type, content): """ is spam. :param doc_id: document id. :param doc_type: document type. :param content: content :return: """ try: return rpc_client['antispam/classify'](doc_id=doc_id, doc_type=doc_type, content=content).unwrap()['spam'] except RPCFaultException: return False except: logging_exception() return False def yidun_antispam(text): """ 易盾反垃圾 http://support.dun.163.com/antispam/api/#_1 :param text: :return: """ try: data = rpc_client['antispam/yidun'](text=text).unwrap() except RPCFaultException: return False if data['result']['action'] == 2: label = data['result']['labels'][0]['label'] if label == 100: return SPAM_LABEL.EROTICISM elif label == 200: return SPAM_LABEL.ADVERTISE elif label == 400: return SPAM_LABEL.PROHIBIT elif label == 600: return SPAM_LABEL.ABUSE elif label == 700: return SPAM_LABEL.WATERING return False @shared_task def check_spam(pk, fields, cls_type): """ check spam. :param pk: :param fields: :param cls: :return: """ clsMap = { DocType.ANSWER: Answer, DocType.QUESTION: Question, DocType.COMMENT: AnswerReply, } cls = clsMap.get(cls_type) if not cls: return False try: instance = cls.objects.get(pk=pk) except cls.DoesNotExist: return False content = u"" for field in fields: content += getattr(instance, field, u"") instance.spam_label = bayes_antispam(doc_id=pk, doc_type=cls_type, content=content) yidun_label = yidun_antispam(content) if yidun_label: instance.spam_label = yidun_label instance.save() @shared_task def build_high_quality_cache(): """ :return: """ start_time = datetime.now() - timedelta(days=90) condition = Q(is_online=True) & Q(is_recommend=True) & Q(create_time__gt=start_time) total = Question.objects.filter(condition).count() offset = random.randint(0, total) ids = list(Question.objects.filter(condition).values_list('id', flat=True)[offset:offset + 100]) random.shuffle(ids) high_quality_question_cache.set('high_quality', json.dumps(ids)) @shared_task def build_inviter_pool(): """ 邀请人列表池 :return: """ start_time = datetime.now() - timedelta(days=150) query = Q(is_online=True, level__gte=CONTENT_CLASS.FINE, create_time__gt=start_time) users = Answer.objects.filter(query).values("user", "create_time") user_dic = {} # 用于构建用来比较的数据结构 {user_id:{"id":user_id, "cnt": count, "create_time": datetime类型}} for user in users: uid = user["user"] if uid not in user_dic: user_dic[uid] = {"id": uid, "cnt": 1, "create_time": user["create_time"]} else: user_dic[uid]['cnt'] += 1 if user["create_time"] > user_dic[uid]["create_time"]: user_dic[uid]['create_time'] = user["create_time"] user_list = list(filter(lambda x: x["cnt"] > settings.INVITER_LIMIT_FORM_ANSWER, user_dic.values())) user_list.sort(key=lambda user: (user["cnt"], user["create_time"]), reverse=True) user_ids = [user["id"] for user in user_list] # 筛选完毕,满足需求的所有user_id # 剔除 医生 or 医院用户 doctors = get_doctor_from_user_ids(user_ids) doctor_user_ids = [int(doctor.user_id) for doctor in doctors] user_ids = list(filter(lambda y: y not in doctor_user_ids, user_ids)) # 通过请求 gaia 的方法,过滤掉马甲账号,需要先做一次预处理,user_is_puppet_dic:{"user_id": "is_puppet"} user_infos = rpc_client["api/user/get_fundamental_info_by_user_ids"](user_ids=user_ids).unwrap() user_is_puppet_dic = {user["id"]: user["is_puppet"] for user in user_infos} user_ids = list(filter(lambda user_id: not user_is_puppet_dic[user_id], user_ids)) question_inviter_cache.set("question_inviter_pool", json.dumps(user_ids)) @shared_task def time_push_to_invited_user(): """ 定时推送给被邀请者 :return: """ # 数据池 每天下午五点到上一天下午五点,被邀请的用户未回答的问题。 today = datetime.now().replace(hour=17, minute=0, second=0) last_day = today - timedelta(days=1) need_push_info = QuestionInviter.objects.filter( answer_id__isnull=True, invite_time__range=[last_day, today]).values("inviter").annotate(nums=Count("inviter")) for info in need_push_info: push_url = GmProtocol().get_webview(settings.BACKEND_API_HOST + settings.INVITE_QUESTION_LIST_PAGE) kwargs = { "user_ids": [info["inviter"]], "platform": ['android', 'iPhone'], "alert": u'{count}位用户邀请你来回答医美问题,赶紧去为他们解答哦~'.format(count=info["nums"]), "extra": { 'type': PUSH_INFO_TYPE.GM_PROTOCOL, 'msgType': 4, 'pushUrl': push_url, 'push_url': push_url, }, 'push_type': AUTOMATED_PUSH.INVITATION_TO_ANSWER, # "labels": {}, # 不知道是否需要埋点,先预留 } push_task_to_user_multi(**kwargs) @shared_task def get_relation_college_tag_questions(): """ 获取关联大学标签的所有问题id及,后台设置的小程序推荐问题id :return: """ tag_info = rpc_client["api/tag/hera_search"](query="", tag_type_in=[TAG_TYPE.COLLEGE, ], is_online=True).unwrap() tag_ids = [int(tag.get("id")) for tag in tag_info] question_ids = QuestionTag.objects.filter(tag__in=tag_ids).values_list("question_id", flat=True).distinct() recommends = Question.objects.filter(id__in=question_ids, is_online=True, recommend_xiaochengxu=True).values_list( "id", flat=True) complains_question_cache.set("tag_ids", json.dumps(tag_ids)) complains_question_cache.set("recommend", json.dumps(list(recommends))) def push_to_question_provider(user_id, answer_id, eta=None, question_title=None, user_name=None): """ push 给提出问题的用户 :param user_id: 用户ID :param question_id: 问题ID :param eta: :param question_title: :param user_name: :return: """ push_url = gm_protocol.get_answer_list(answer=answer_id) extra = { 'type': PUSH_INFO_TYPE.GM_PROTOCOL, 'msgType': 4, 'pushUrl': push_url, 'push_url': push_url, } push_task_to_user_multi( user_ids=[user_id], push_type=AUTOMATED_PUSH.QUESTION_POSTED_ANSWER, extra=extra, labels={'event_type': 'push', 'event': 'question_received_answer'}, alert=u'{user_name} 刚刚回答了你的问题"{question_title}"'.format( user_name=user_name, question_title=question_title), eta=eta, ) @shared_task def send_answer_on_time(sa_id, question_user_id, question_title, nick_name, push_time): send_answer = SendAnswer.objects.get(id=sa_id) if send_answer.status != SEND_ANSWER_STATUS.SUCCESS: Answer.objects.update_or_create(**send_answer.data) send_answer.status = SEND_ANSWER_STATUS.SUCCESS send_answer.save() push_to_question_provider(user_id=question_user_id, eta=push_time, question_title=question_title, user_name=nick_name) @shared_task def comment_push(answer_id, comment_id=None, user_id=None, author_name=None, content=None, is_commented_reply=None): """1、2级评论push统一走 demeter 防干扰push""" if not user_id: return {} user_ids = [user_id] if is_commented_reply: content_id = comment_id push_type = AUTOMATED_PUSH.COMMENT_RECEIVED_REPLY else: content_id = answer_id push_type = AUTOMATED_PUSH.ANSWER_RECEIVED_COMMENTS images = list(AnswerReplyImages.objects.using(settings.SLAVE_DB_NAME).filter( reply_id=comment_id, ).values_list('url', flat=True)) push_image = images and Picture(images[0]).watermarked or '' push_url = gm_protocol.get_user_answer_list() alert = u'@{}:{}...'.format(author_name, content[:25]) intelligent_push_task.apply_async( args=( content_id, user_ids, push_type, { 'type': PUSH_INFO_TYPE.GM_PROTOCOL, 'pushUrl': push_url, 'push_url': push_url, 'image': push_image, 'push_image': push_image, } ), kwargs={ "platform": None, "alert": alert, "others": { "title": "你收到了一条新评论", "alert": alert, }, "labels": { 'event_type': 'push', 'event': 'received_qa_comments' }, }, ) @shared_task def add_doctor_question(question_id): """添加医生关联的问题""" try: question = Question.objects.get(id=question_id, is_online=True) except Question.DoesNotExist: return if question.answer_num: return user = question.user if not user.current_city_id: return try: doctors = rpc_client["doctor/getdoctorinfo_bycityid"](city_id=user.current_city_id).unwrap() doctor_ids = [doctor.get("doctor_id") for doctor in doctors] except: logging_exception() return messages = [] for doctor_id in doctor_ids: messages.append(DoctorMessageList( user_id=user.id, doctor_id=doctor_id, question=question )) DoctorMessageList.objects.bulk_create(messages) @shared_task def qa_image_add_base_info(images_list, params_info): """ 更新问答图片的基础信息 :param images_list: [] 不带后缀的完整图片地址链接 :param params_info: {"model": answer_image, "param_name": "answer_id", "id": 111} :return: """ mapping_dic = { "question_image": (QuestionImage, "question_id"), "answer_image": (AnswerImage, "answer_id"), } model, param_name = mapping_dic.get(params_info.get("model", ""), (None, "")) _id = params_info.get("id", 0) if model: _image_list = get_media_extra_info(images_list) for image_dic in _image_list: if param_name: _kw = { "image_url_source": MEDIA_IMAGE_URL_SOURCE.RICH_TEXT, "image_url": image_dic.get("image_url", ""), param_name: _id, } _default = { "width": image_dic.get("width", 0), "height": image_dic.get("height", 0), } model.objects.get_or_create(**_kw, defaults=_default) else: continue @shared_task def applet_replied_push(answer_reply_id): """ 回答的评论被评论,给回答评论的用户 发送小程序推送 自己给自己评论无效 回答被评论,给回答的用户发 自己给自己评论无效 :param answer_reply_id: 评论id :return: """ if not answer_reply_id: return try: answer_reply = AnswerReply.objects.get(id=answer_reply_id) except AnswerReply.DoesNotExist: return reply_content = answer_reply.content[:20] nickname = answer_reply.user.nickname[:10] data = { "name1": { "value": nickname }, "thing2": { "value": reply_content }, "date3": { "value": "{date}".format(date=datetime.now().strftime('%Y年%m月%d日 %H:%M')) }, "thing4": { "value": "点击快速查看>>" } } # 模板id template_id = settings.APPLET_SUBSCRIBE_MSG.get("comment", "") # 跳转页面 page = '/packageBBS/pages/ask/answerDetail/answerDetail?answerId={answer_id}&' \ 'comment_id={comment_id}&from={from_page}&from_action={from_action}'.format( answer_id=answer_reply.answer_id, comment_id=answer_reply.id, from_page=APPLET_PAGE_FROM.CARD, from_action=APPLET_SUBSCRIBE_MSG_TYPE.COMMENT ) # 给回答用户发 answer_user_id = answer_reply.answer.user_id if answer_reply.user_id != answer_user_id: send_applet_subscribe_msg(answer_user_id, template_id, data=data, page=page) if not answer_reply.commented_reply_id: return try: commented_answer_reply = AnswerReply.objects.get(id=answer_reply.commented_reply_id) except AnswerReply.DoesNotExist: return # 给一级评论用户发 if answer_reply.commented_reply_id != answer_reply.first_reply_id: try: level_1_reply = AnswerReply.objects.get(id=answer_reply.first_reply_id) except: level_1_reply = None if level_1_reply: # 自己给自己评论无效 if answer_reply.user_id != level_1_reply.user_id: # 发送小程序推送 send_applet_subscribe_msg(level_1_reply.user_id, template_id, data=data, page=page) # 自己给自己评论无效 if answer_reply.user_id == commented_answer_reply.user_id: return # 发送小程序推送 send_applet_subscribe_msg(commented_answer_reply.user_id, template_id, data=data, page=page) @shared_task def applet_reply_summary_push(answer_reply_id): """ 用户评论完24小时后, 如果没有收到评论或点赞,则给用户推送回答的新增评论总数,或回答的相关内容 如果被赞,且被赞数大于1,则推送新增被赞数 :param answer_reply_id: 当前评论id :return: """ if not answer_reply_id: return try: answer_reply = AnswerReply.objects.get(id=answer_reply_id) except AnswerReply.DoesNotExist: return user_id = answer_reply.user_id new_answer_reply = AnswerReply.objects.using(settings.SLAVE_DB_NAME).\ filter(id__gt=answer_reply_id, user=user_id, is_online=True).exists() if new_answer_reply: return replied_count = AnswerReply.objects.using(settings.SLAVE_DB_NAME).\ filter(commented_reply_id=answer_reply_id, is_online=True).exclude(user=user_id).count() voted_count = AnswerVoteReply.objects.using(settings.SLAVE_DB_NAME).\ filter(answerreply_id=answer_reply_id).exclude(user=user_id).count() answer_content =Answer.objects.filter(id=answer_reply.answer_id).first().content answer_content = _get_content_text(answer_content)[:10] # 当前评论有被评论或被赞 if replied_count or voted_count: return answer_id = answer_reply.answer_id # 回答新增一级评论数(不包含自己的) additional_reply_count = AnswerReply.objects.using(settings.SLAVE_DB_NAME).\ filter(id__gt=answer_reply_id, answer_id=answer_id, first_reply__isnull=True, is_online=True).\ exclude(user=user_id).count() # 有新增评论,发送24小内新增评论总数 if additional_reply_count: data = { "thing1": { "value": answer_content }, "thing2": { "value": "你评论的回答,新增{reply_count}条吐槽,立即查看".format(reply_count=additional_reply_count)[:20] } } # 模板id template_id = settings.APPLET_SUBSCRIBE_MSG.get("vote", "") # 跳转页面 page = '/packageBBS/pages/ask/answerDetail/answerDetail?answerId={answer_id}&' \ 'from={from_page}&from_action={from_action}'.format( answer_id=answer_reply.answer_id, from_page=APPLET_PAGE_FROM.CARD, from_action=APPLET_SUBSCRIBE_MSG_TYPE.NEW_COMMENT ) # 无新增评论,推送评论的帖子的相同标签下的其它内容详情页 else: data = { "thing2": { "value": answer_content }, "thing4": { "value": "亲!你关注过的话题又有新内容啦>>" } } # 模板id template_id = settings.APPLET_SUBSCRIBE_MSG.get("recommend", "") # 获取当前回答的标签 tag_id_list = AnswerTag.objects.filter(answer_id=answer_id).values_list('tag', flat=True) tag_info = list(tag_manager.get_tags_info_by_ids(tag_id_list).values()) tag_name = tag_info and tag_info[0] and tag_info[0].get("tag_name") if not tag_name: return # 调策略 获取相关内容 def get_new_answer_id(rpc_client, offset, tag_name): res = rpc_client['doris/query/answer'](sort_type=DIARY_ORDER_TYPE.DEFAULT, query=tag_name, size=1, offset=offset).unwrap() new_answer_id = res and res.get("answer_ids") and res.get("answer_ids")[0] return new_answer_id rpc_client = get_current_rpc_invoker() offset = random.randint(0, 200) origin_offset = offset new_answer_id = None num = 6 while not new_answer_id and num: try: new_answer_id = get_new_answer_id(rpc_client, offset, tag_name) except: new_answer_id = None offset = origin_offset % num if num > 1: offset += random.randint(0, 10) num -= 1 if not new_answer_id: return # 跳转页面 page = '/packageBBS/pages/ask/answerDetail/answerDetail?answerId={answer_id}&' \ 'from={from_page}&from_action={from_action}'.format( answer_id=new_answer_id, from_page=APPLET_PAGE_FROM.CARD, from_action=APPLET_SUBSCRIBE_MSG_TYPE.RELATED_CONTENT ) # 发送小程序推送 send_applet_subscribe_msg(user_id, template_id, data=data, page=page) @shared_task def applet_voted_push(answer_reply_vote_id): """ 回答的评论被点赞,给回答评论的用户 发送小程序推送 自己给自己点赞无效 :param answer_reply_id: 评论id :return: """ if not answer_reply_vote_id: return try: answer_reply_vote = AnswerVoteReply.objects.get(id=answer_reply_vote_id) except AnswerVoteReply.DoesNotExist: return try: answer_reply = AnswerReply.objects.get(id=answer_reply_vote.answerreply_id, is_online=True) except AnswerReply.DoesNotExist: return # 自己给自己点赞不用发 if answer_reply_vote.user_id == answer_reply.user_id: return answer_content = Answer.objects.filter(id=answer_reply.answer_id).first().content answer_content = _get_content_text(answer_content)[:10] data = { "thing1": { "value": answer_content }, "thing2": { "value": "你的评论收到了新的支持,快来看看吧>>" } } # 模板id template_id = settings.APPLET_SUBSCRIBE_MSG.get("vote", "") # 跳转页面 page = '/packageBBS/pages/ask/answerDetail/answerDetail?answerId={answer_id}&' \ 'comment_id={comment_id}&from={from_page}&from_action={from_action}'.format( answer_id=answer_reply.answer_id, comment_id=answer_reply.id, from_page=APPLET_PAGE_FROM.CARD, from_action=APPLET_SUBSCRIBE_MSG_TYPE.VOTE ) # 发送小程序推送 send_applet_subscribe_msg(answer_reply.user_id, template_id, data=data, page=page) @shared_task def applet_answer_summary_push(answer_id): """ 用户回答完24小时后, 如果没有收到评论或点赞,则给用户推送问题的新增回答总数,或问题的相关内容 如果被赞,且被赞数大于1,则推送新增被赞数 :param answer_reply_id: 当前评论id :return: """ if not answer_id: return try: answer_info = Answer.objects.get(id=answer_id) except Answer.DoesNotExist: return user_id = answer_info.user_id new_answer = Answer.objects.using(settings.SLAVE_DB_NAME).\ filter(id__gt=answer_id, user=user_id, is_online=True).exists() if new_answer: return replied_count = AnswerReply.objects.using(settings.SLAVE_DB_NAME).filter(answer_id=answer_id, is_online=True).\ exclude(user=user_id).count() voted_count = AnswerVote.objects.using(settings.SLAVE_DB_NAME).filter(answer_id=answer_id).\ exclude(user=user_id).count() answer_content = _get_content_text(answer_info.content)[:10] # 当前回答有被评论或被赞 if replied_count or voted_count: return question_id = answer_info.question_id # 问题新增回答数(不包含自己的) additional_answer_count = Answer.objects.using(settings.SLAVE_DB_NAME).\ filter(id__gt=answer_id, question_id=question_id, is_online=True).exclude(user=user_id).count() # 有新增回答,发送24小内新增回答总数 if additional_answer_count: data = { "thing1": { "value": answer_content }, "thing2": { "value": "你评论的问题,新增{reply_count}条吐槽,立即查看".format(reply_count=additional_answer_count)[:20] } } # 模板id template_id = settings.APPLET_SUBSCRIBE_MSG.get("vote", "") # 跳转页面 page = '/packageBBS/pages/ask/questionDetail/questionDetail?questionId={question_id}&' \ 'from={from_page}&from_action={from_action}'.format( question_id=answer_info.question_id, from_page=APPLET_PAGE_FROM.CARD, from_action=APPLET_SUBSCRIBE_MSG_TYPE.NEW_COMMENT ) # 无新增回答,推送回答的问题的相同标签下的其它内容详情页 else: data = { "thing2": { "value": answer_content }, "thing4": { "value": "亲!你关注过的话题又有新内容啦>>" } } # 模板id template_id = settings.APPLET_SUBSCRIBE_MSG.get("recommend", "") # 获取当前问题的标签 tag_id_list = QuestionTag.objects.filter(question_id=question_id).values_list('tag', flat=True) tag_info = list(tag_manager.get_tags_info_by_ids(tag_id_list).values()) tag_name = tag_info and tag_info[0] and tag_info[0].get("tag_name") if not tag_name: return # 获取相关问题内容 def get_new_question_id(rpc_client, offset): res = rpc_client['doris/search/question'](query=tag_name, size=1, offset=offset, sort_type=QUESTION_ORDER_TYPE.DEFAULT).unwrap() new_question_id = res and res.get("question_ids") and res.get("question_ids")[0] return new_question_id rpc_client = get_current_rpc_invoker() offset = random.randint(0, 200) origin_offset = offset new_question_id = None num = 6 while not new_question_id and num: try: new_question_id = get_new_question_id(rpc_client, offset) except: new_question_id = None offset = origin_offset % num if num > 1: offset += random.randint(0, 10) num -= 1 if not new_question_id: return # 跳转页面 page = '/packageBBS/pages/ask/questionDetail/questionDetail?questionId={question_id}&' \ 'from={from_page}&from_action={from_action}'.format( question_id=new_question_id, from_page=APPLET_PAGE_FROM.CARD, from_action=APPLET_SUBSCRIBE_MSG_TYPE.RELATED_CONTENT ) # 发送小程序推送 send_applet_subscribe_msg(user_id, template_id, data=data, page=page) @shared_task def applet_answer_voted_push(answer_vote_id): """ 回答被点赞,给回答的用户 发送小程序推送 自己给自己点赞无效 :param answer_reply_id: 评论id :return: """ if not answer_vote_id: return try: answer_vote = AnswerVote.objects.get(id=answer_vote_id, is_fake=False) except AnswerVote.DoesNotExist: return try: answer_info = Answer.objects.get(id=answer_vote.answer_id, is_online=True) except AnswerReply.DoesNotExist: return # 自己给自己点赞不用发 if answer_vote.user_id == answer_info.user_id: return answer_content = _get_content_text(answer_info.content)[:10] data = { "thing1": { "value": answer_content }, "thing2": { "value": "你的评论收到了新的支持,快来看看吧>>" } } # 模板id template_id = settings.APPLET_SUBSCRIBE_MSG.get("vote", "") # 跳转页面 page = '/packageBBS/pages/ask/questionDetail/questionDetail?questionId={question_id}&answer_id={answer_id}&' \ 'from={from_page}&from_action={from_action}'.format( answer_id=answer_info.id, question_id=answer_info.question_id, from_page=APPLET_PAGE_FROM.CARD, from_action=APPLET_SUBSCRIBE_MSG_TYPE.VOTE ) # 发送小程序推送 send_applet_subscribe_msg(answer_info.user_id, template_id, data=data, page=page)