🦔

Python: Slackへのpost blockをメソッドチェーンで簡単に構築できるようにする

2023/02/13に公開

やりたいこと

Slackにpostする文字を、メソッドチェーンで構築できるようにしたい

イメージ:

slack_post: SlackPost = SlackPost.Generator(SLACK_TOKEN) \
    .set_color("blue") \
    .add_markdown("test") \
    .add_divider() \
    .generate()

実装

※ python3.9

from __future__ import annotations

import json
import logging
from enum import Enum

from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

logger = logging.getLogger()
logger.setLevel(logging.INFO)


class Color(Enum):
   RED = "#cc3300"
   GRAY = "#aaaaaa"
   GREEN = "#339900"
   YELLOW = "#ffcc00"


class SlackPost:
   def __init__(self, generator):
       self._attachments = [
           {
               "color": generator.color.value,
               "blocks": generator.blocks,
           }
       ]
       self._slack_client: WebClient = generator.slack_client

   def post(self, channel: str) -> None:
       try:
           self._slack_client.chat_postMessage(
               channel=channel,
               attachments=json.dumps(self._attachments),
           )
       except SlackApiError as e:
           logger.exception(e)


class SlackPostGenerator:
   def __init__(self, slack_token):
       self.serial = "AZ12345678"

       self.slack_client: WebClient = WebClient(token=slack_token)
       self.blocks: list[dict] = []
       self.color: Color = None

   def set_color(self, color: Color) -> SlackPostGenerator:
       self.color = color
       return self

   def add_title(self, message) -> SlackPostGenerator:
       self.blocks.append(
           {
               "type": "header",
               "text": {
                   "type": "plain_text",
                   "text": message,
                   "emoji": True
               }
           }
       )
       return self

   def add_markdown(self, message) -> SlackPostGenerator:
       self.blocks.append(
           {
               "type": "section",
               "text": {
                   "type": "mrkdwn",
                   "text": message
               }
           }
       )
       return self

   def add_plain_text(self, message) -> SlackPostGenerator:
       self.blocks.append(
           {
               "type": "section",
               "text": {
                   "type": "plain_text",
                   "text": message,
                   "emoji": True
               }
           }
       )
       return self

   def add_divider(self) -> SlackPostGenerator:
       self.blocks.append(
           {
               "type": "divider"
           }
       )
       return self

   def generate(self) -> SlackPost:
       if self.color is None:
           raise Exception("colorを指定してください")
       return SlackPost(self)

使い方の例

slack_post: SlackPost = SlackPost.Generator(SLACK_TOKEN) \
    .set_color(Color.RED) \
    .add_markdown("test") \
    .add_markdown("test") \
    .generate()
slack_post.post("#random")

Discussion