import json from django.db import models from django.conf import settings from django.utils.translation import gettext_lazy as _ class LarkMessage(models.Model): MESSAGE_TYPE_POST = 'post' MESSAGE_TYPE_MARKDOWN = 'markdown' MESSAGE_TYPE_CHOICES = ( (MESSAGE_TYPE_POST, _('post')), (MESSAGE_TYPE_MARKDOWN, _('markdown')), ) STATUS_PENDING = 'pending' STATUS_SUCCESS = 'success' STATUS_FAILED = 'failed' STATUS_CHOICES = ( (STATUS_PENDING, _('pending')), (STATUS_SUCCESS, _('success')), (STATUS_FAILED, _('failed')), ) message_type = models.CharField( max_length=32, choices=MESSAGE_TYPE_CHOICES, default=MESSAGE_TYPE_POST) payload = models.TextField() response_body = models.TextField(blank=True, null=True) remark = models.CharField( max_length=255, blank=True, null=True) status = models.CharField( max_length=32, choices=STATUS_CHOICES, default=STATUS_PENDING) send_at = models.DateTimeField(blank=True, null=True) webhook = models.CharField(max_length=255, blank=True, null=True) creator = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = 'pingcap_lark_messages' @classmethod def send(cls, *, webhook, message_type, content, remark=None, creator=None, _async=True, send_countdown=0): # send_countdown only works when _async is True, it means the message will be sent after `send_countdown` seconds from pingcap_sso.tasks.lark import send_lark_message if message_type == cls.MESSAGE_TYPE_MARKDOWN: payload = { "msg_type": "interactive", "card": { "config": { "wide_screen_mode": True, "enable_forward": True }, "elements": [{ "tag": "div", "text": { "content": content, "tag": "lark_md" } }], } } elif message_type == cls.MESSAGE_TYPE_POST: payload = { 'msg_type': 'post', 'content': { 'post': {'zh_cn': content} } } else: raise ValueError(f'Invalid message_type: {message_type}') send_success = False message = cls.objects.create( webhook=webhook, message_type=message_type, payload=json.dumps(payload), remark=remark, creator=creator, status=cls.STATUS_PENDING ) if _async: send_lark_message.apply_async((message.id, ), countdown=send_countdown) # always set send_success as True in async mode send_success = True else: send_success = send_lark_message(message.id) return send_success