import logging from typing import Optional from django.db import models logger = logging.getLogger(__name__) class LarkMessage(models.Model): class MessageType(models.TextChoices): POST = "post" MARKDOWN = "markdown" class Status(models.TextChoices): PENDING = "pending" SUCCEEDED = "succeeded" FAILED = "failed" message_type = models.CharField( max_length=10, choices=MessageType.choices, default=MessageType.POST, ) payload = models.JSONField() response_body = models.JSONField(null=True, blank=True) comment = models.CharField(max_length=255, null=True, blank=True) status = models.CharField( max_length=10, choices=Status.choices, default=Status.PENDING, ) send_at = models.DateTimeField(null=True, blank=True) webhook_url = models.CharField(max_length=255, null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = "lark_messages" @classmethod def send( cls, *, webhook: str, message_type: MessageType, content: str, title: Optional[str] = None, comment: Optional[str] = None, _async: bool = True, send_countdown: int = 0, ) -> bool: if not webhook: logger.error("No webhook provided, skipping message send") return False if message_type == cls.MessageType.POST: payload = { "msg_type": "post", "content": { "post": {"en_us": {"content": [[{"tag": "text", "text": content}]]}} }, } if title: payload["content"]["post"]["en_us"]["title"] = title elif message_type == cls.MessageType.MARKDOWN: payload = { "msg_type": "interactive", "card": { "config": {"wide_screen_mode": True, "enable_forward": True}, "elements": [ {"tag": "div", "text": {"content": content, "tag": "lark_md"}} ], }, } if title: payload["card"]["header"] = { "title": {"content": title, "tag": "plain_text"}, "template": "blue", "padding": "12px 12px 12px 12px", } else: raise ValueError(f"Invalid message type: {message_type}") success = False message = cls.objects.create( webhook_url=webhook, message_type=message_type, payload=payload, comment=comment, ) from labs.tasks import send_lark_message if _async: send_lark_message.apply_async(args=(message.id,), countdown=send_countdown) # async task will be executed in the background # always return True without waiting for the task to complete success = True else: success = send_lark_message(message.id) return message, success