KINTO Tech Blog
Slack

【学びの道の駅シリーズ】超エキサイティングなSlack bot「まなびぃ」つくった

Cover Image for 【学びの道の駅シリーズ】超エキサイティングなSlack bot「まなびぃ」つくった

この記事は KINTOテクノロジーズアドベントカレンダー2024 の4日目の記事です🎅🎄


メリークリスマス✌️🎅
KINTOテクノロジーズ(以下KTC)で my route(iOS) を開発しているRyommです…が、今回は幻のbot職人 Ryommとして、学びの道の駅プロジェクトと共同で開発した超エキサイティングなSlack bot「まなびぃ」を紹介します。

まなびぃとは

社内の勉強会やイベントを収集し、集めたデータを活用するための超エキサイティングなSlack botです。
イベント関係のすべてを内包しています。

まなびぃ

まなびぃの主な役割としては、以下の2つがあります。

  • イベントの検索
  • 新規イベントの登録・周知

まなびぃに新規立ち上げイベントを入力すると、然るべきチャンネルにイベントを周知します。
また、ユーザは上記のチャンネルをウォッチしたり、まなびぃに問い合わせることで社内イベントにアクセスできます。

直接の関係者じゃなくても情報を得られる
直接の関係者じゃなくても情報を得られる

まなびぃの活用に関しては別日の【学びの道の駅シリーズ】にて言及がある(はず)なので、本記事ではまなびぃ周辺の技術に関して紹介します。

まなびぃの技術

まなびぃはSlack CLIを使用して作成しています。

https://api.slack.com/automation/quickstart

Slack CLIは、Slack側でDataStoreを立ててくれたりなど、インフラを構築する手間が省けるところが気軽です。
また、開発用の環境もSlack CLI側で作れるところも良いですね。

まなびぃのざっくりとした構成は以下のようになっています。

ざっくりとした構成

トリガー

まなびぃには3つのトリガーが生えています。

機能 トリガーの種類
イベントの追加 linkトリガー
イベントの削除 linkトリガー
イベントの検索 eventトリガー

リンクトリガー
リンクトリガーフォーム

eventトリガー

Slackのワークフローのトリガーには4種類あります。

トリガー名 説明
linkトリガー 作成するとURLが発行され、Slack上でそのリンクが押されたら実行(Slack以外では無効)
scheduledトリガー 時間で実行
eventトリガー メンションやリアクションきっかけで実行
webhookトリガー 特定のURLがPOSTリクエストを受信したときに実行

https://api.slack.com/automation/triggers

まなびぃでは基本的にユーザーは検索機能を使用し、イベント運営者のみが追加・削除機能を使用する想定をしています。
そのため、うっかり間違えてイベントを追加・削除されてしまわないようにトリガーの種類を分けています。

またイベントの登録が完了すると、botを呼び出したチャンネルと登録を周知するチャンネル(#notice-new-event)の2つに通知されます。

通知

こうすることで、作成したチャンネルに関わらず新規に立ち上がったイベントを知ることができます。
もちろん、興味があるキーワードでまなびぃに問い合わせることでも情報を得ることができます。

Block Kit

SlackはBlock Kitというフレームワークを使ってリッチなビジュアルのメッセージを作成できます。

以下のBlock Kit Builderというツールを使って体験できるので、使ったことがない方は試してみてください。
https://api.slack.com/tools/block-kit-builder

イベント情報の取得結果もBlock Kitを使用してみやすくしています。

https://api.slack.com/block-kit

Block Kitを使ったメッセージ

参照ページのリンク先がSlackチャンネルへのリンクや、Confluenceページ、キックオフ時の動画など、ものによってはとても長くなりノイズとなってしまうため、「詳細」ボタンのリンクとして設定しています。
文字列だけでなくリンクを含ませたいなどの要望もあり、説明テキストのフィールドはrich_text型を採用しています。

🕺Slack bot開発Tipsのコーナー🕺

送信時にBlock Kitを使うかどうかははじめに決めておく

まなびぃはstring型で少し運用してからrich_text型に変更することにしたのですが、string型とrich_text型は互換性がないためDataStoreのマイグレーションが一筋縄ではいきません。
さらに、登録済データもrich_textになったなら改行やリンクを含めたい!など諸々の事情を踏まえた判断の上、1回DataStoreのデータを吹き飛ばす荒技を行いました。超エキサイティング!
決められるなら、はじめにBlock Kitを使うかどうかを判断しておくと苦労せずに済みます。

https://api.slack.com/automation/datastores

block_idの扱いに気をつける

詳細はこちらの記事へ: 【Slack CLI】block_idが衝突してSlackにメッセージを送れない

Workflowはビルド時しか実行されない

テストを考えたとき、UUIDを渡すようなメソッドを作成する際はidをメソッド外から渡すようにしたいです。

const addEventFunctionStep = AddEventWorkflow.addStep(
  AddEventFunction,
  {
    id: crypto.randomUUID(), // メソッドの呼び出し側でIDを生成したい
    title: formData.outputs.fields.title
  }
)

しかし、Workflowの定義部分はビルド時のみ実行され、その後の呼び出し時にはfunctionの中のみが実行されます。
そのため、UUIDの生成など、処理のたびに実行されてほしいコードはメソッドの中に含めるようにします。

ドキュメントを見つけるのが大変すぎる

基本的にSlack APIのドキュメントがそのまま適用できることが多いです。

特に、私はtriggerのinputや、フォーム、DataStoreでどんな型が使えるのか彷徨いました。
そんなあなたにはこのドキュメントで万事解決です!

https://api.slack.com/automation/types


まなびぃを支える技術

まなびぃは一応インナーソースという扱いであり、開発環境もかなり整えてあるのでご紹介します。

CI/CD

【テスト】

Slack CLIはDenoで動いているため、 deno test でテストを実行できます。

name: 🧪 Slack App Test

on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
    - uses: actions/checkout@v4
    - name: Install Deno runtime
      uses: denoland/setup-deno@v1
      with:
        deno-version: v1.x

    - name: Install Slack CLI
      if: steps.cache-slack.outputs.cache-hit != 'true'
      run: |
        curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash

    - name: Test the app
      run: |
        cd app/
        deno test --no-check

【デプロイ】

手元のコンソールで slack auth token コマンドを実行すると xoxp- からはじまるサービストークンが取得できます。これをGitHubのシークレットに登録しておきます。

ワークフローの定義は以下のとおりです。

name: 🏃‍➡️ Slack App Deploy

on:
  push:
    branches: [ main ]
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
    - uses: actions/checkout@v4
    - name: Install Deno runtime
      uses: denoland/setup-deno@v1
      with:
        deno-version: v1.x

    - name: Install Slack CLI
      if: steps.cache-slack.outputs.cache-hit != 'true'
      run: |
        curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash

    - name: Deploy the app
      env:
        SLACK_SERVICE_TOKEN: ${{ secrets.SLACK_SERVICE_TOKEN }}
      run: |
        cd app/
        slack deploy -s --token $SLACK_SERVICE_TOKEN

これで通常のアプリのコードの更新はデプロイできるようになりました。ただし、トリガーの更新とデータストアの構成変更は自動化できないため、これらのデプロイについては手元で実行する必要がある点に注意です。

Issue Template

バグや機能リクエスト、質問などを受け付けられるようにテンプレートを用意しています。

テンプレート

正直ほぼ使われてはいないですが、OSSっぽくて気に入っています。

Project

GitHub Projectを使っています。

社内のプロジェクトでは基本Jiraを使用していますが、まなびぃではConfluenceを使っていないこともあり、GitHubに寄せた方が便利なので寄せてます。(あとGitHub Projectの良さを体験して欲しかった)

GitHub Project

というわけで、全体的にGitHub上で完結するようにしてみました。

私の所属はモバイル開発GなのでSwiftやKotlinがメインで、TypeScriptを書くとなるとハードルが高く感じられる方が多いです。また、部署外にこんなプロジェクトがあるということをアピールするのが難しいためインナーソースプロジェクトとしてはまだまだ課題が多いのが現状です。
まなびぃが成長して大きくなったら、いつか誰かコントリビュートしてくれるかな…と願いながら開発環境を整えています。

おわりに

まなびぃを紹介しました。
まだまだ生まれたてのまなびぃですが、KTCのカルチャーと共に成長していければと思います...!

Facebook

関連記事 | Related Posts

We are hiring!

【部長・部長候補】/プラットフォーム開発部/東京

プラットフォーム開発部 について共通サービス開発GWebサービスやモバイルアプリの開発において、必要となる共通機能=会員プラットフォームや決済プラットフォームの開発を手がけるグループです。KINTOの名前が付くサービスやTFS関連のサービスをひとつのアカウントで利用できるよう、様々な共通機能を構築することを目的としています。

生成AIエンジニア/生成AI活用PJT/東京・名古屋・大阪

生成AI活用PJTについて生成AIの活用を通じて、KINTO及びKINTOテクノロジーズへ事業貢献することをミッションに2024年1月に新設されたプロジェクトチームです。生成AI技術は生まれて日が浅く、その技術を業務活用する仕事には定説がありません。