5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SlackAdvent Calendar 2020

Day 6

Bolt+jsx-slack+Glitchで伝書鳩botをつくってみた

Last updated at Posted at 2020-12-06

はじめに

@75asa さんの誘いで入部した社内部活「OSS部」の活動の一貫として作成する事になりました。
Slackbotは以前Hubotを少し触ったことがある程度で、ほぼ初チャレンジです。

使用技術

  • 環境
    • macOS 10.15.7
  • 言語
    • Node.js
    • JavaScript
  • FrameWork
    • Slack Bolt for JS
  • PaaS
    • Glitch

実装

まず今回のSlackAppを作成するにあたって、下記の記事を参考にさせていただきました。
jsx-slackの開発者様の記事で、初めてでも非常に分かりやすかったです。感謝。

参考:実践 jsx-slack: jsx-slack + Bolt で Slack のモーダルを自在に操ろう

ディレクトリ構成はこんな感じ。

./
├── .env
├── .gitignore
├── app.js
├── node_modules
├── package-lock.json
└── package.json

package.json

{
  "name": "pigeon-message",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "sync": "sync-glitch"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@slack/bolt": "^2.4.1",
    "@speee-js/jsx-slack": "^2.6.0",
    "dotenv": "^8.2.0"
  },
  "devDependencies": {
    "sync-glitch-cli": "^2.0.1"
  }
}

app.js

基本構造としてはこんな感じ


const { App } = require('@slack/bolt');
const { jsxslack } = require('@speee-js/jsx-slack');
require('dotenv').config();

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET
});

// ここに処理を書いていく

(async () => {
  await app.start(process.env.PORT || 3000);
  console.log('⚡️ Bolt app is running!');
})();

TimePickerコンポーネント部分で参考記事の通りに進まなかった点が2つほどありました。


const options = (count, start, suffix) => {
    return [...Array(count)].map((_, i) => { // returnを追記
        const s = (i + start).toString();
        return jsxslack`
            <Option value="${s}">${s.padStart(2, '0')}${suffix}</Option>
        `
    });
};

const TimePicker = props => jsxslack` // fragmentは不要
    <Section>
        <b>${props.label}</b>
    </Section>
    <Actions id="${props.id}">
        <Select name="hour" value="${props.hour}" placeholder="時">
            <Optgroup label="午前">${options(12, 0, '')}</Optgroup>
            <Optgroup label="午後">${options(12, 12, '')}</Optgroup>
        </Select>
        <Select name="minute" value="${props.minute}" placeholder="分">
            ${options(60, 0, '')}
        </Select>
    </Actions>

    <!-- error message -->
    ${props.error & jsxslack`<Context>:warning: <b>${props.error}</b></Context>`}

    <Input type="hidden" name="hour" value="${props.hour}" />
    <Input type="hidden" name="minute" value="${props.minute}" />
`

カスタマイズ

元記事から追加した点としては、ポスト先のチャンネルを指定できるように、ConversationsSelectコンポーネントをモーダル内に追加したのと、ショートカットでモーダルを展開できるようにしました。

スクリーンショット 2020-12-06 0.28.44.png
スクリーンショット 2020-12-06 0.28.09.png

const modal = props => jsxslack`
    <Modal title="伝言を送る" callbackId="post">
        <Section>
            私にお任せ下さい!
            <Image src="https://source.unsplash.com/ic-13C3QhAI/256x256" alt="鳩" />
        </Section>

        <Textarea id="message" name="message" label="伝言" placeholder="伝言をどうぞ…" required />
        <UsersSelect id="users" name="users" label="送付先" multiple required />
        <ConversationsSelect
            id="channel"
            name="channel"
            label="チャンネル"
            required
            include="public im"
            excludeBotUsers
            responseUrlEnabled
        />
        <DatePicker id="date" name="date" label="日付" required />

        <${TimePicker}
            id="time"
            label="時刻"
            hour="${props.hour}"
            minute="${props.minute}"
            error="${props.timePickerError}"
        />

        <Input type="hidden" name="userId" value="${props.userId}" />
    </Modal>
`

ショートカットはSlackAPIのAppsページにある**[Interactivity & Shortcuts]**から追加できました。

スクリーンショット 2020-12-06 0.27.02.png


app.shortcut('open_modal', ({ ack, body, context }) => {
    ack();

    app.client.views.open({
        token: context.botToken,
        trigger_id: body.trigger_id,
        view: modal({ userId: body.user.id }),
    });
});

Glitchにデプロイ

SlackAppが完成したのでGlitchにデプロイします。
ちなみに開発中のWebサーバーはngrokを使ってました。

GitHubにリポジトリを作っておけばGlitchから簡単にImportできるのですが、コード変更のたびにImportしなおすのが面倒なので自動化しました。
スクリーンショット 2020-12-06 0.07.44.png

最初はsync-glitch-cliを使わせてもらったのですが、git pushした後にコマンドラインでsync-glitchを実行する必要がありました。

mainブランチにpushされた時点で自動デプロイが理想でしたので、最終的にはGitHub Actionsにworkflowを追加することにしました。

参考:リポジトリの変更を Glitch に転送する GitHub Actions


name: Deploy To Glitch
on:
  push:
    branches:
      - main
    workflow_dispatch:
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy To Glitch
        uses: kanadgupta/glitch-sync@master
        with:
          project-id: ${{ secrets.PROJECT_ID }}
          auth-token: ${{ secrets.AUTH_TOKEN }}

はじめbranchesmasterと記載しているのに気づかずActionsが実行されませんでしたが、なんとかpushと同時にGlitchへデプロイすることができました。

スクリーンショット 2020-12-05 23.52.10.png

参考リンク

Bolt for JS :zap:
Bolt フレームワークを使って Slack Bot を作ろう
Reference: Block elements
chat.scheduleMessage
Block Kit Builder
jsx-slack→JSON
実践 jsx-slack: jsx-slack + Bolt で Slack のモーダルを自在に操ろう
Bolt + jsx-slack + TypeScript を使って Slack App をつくる
ブラウザだけで完結するウェブアプリ作成環境 Glitch

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?