5
1

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 1 year has passed since last update.

GASでSlackのスラッシュコマンドを作ってみた

Last updated at Posted at 2022-10-31

はじめに

Slackにはスラッシュコマンドという機能があります。/hogeで特定のアクションを実行することができます。こちらのスラッシュコマンドは自作することが可能です。今回は、Google Apps Script(GAS)を使って簡単なスラッシュコマンドを自作したので、その作成の手順を簡単にまとめたいと思います!

GASでSlackのスラッシュコマンドを作ってみた

claspとTypeScriptの導入

今回はGASのCLIツールであるclaspを使って、Slackのスラッシュコマンドを作成しました。claspのバージョンが1.5.0以上のものからGASでもTypeScriptが使えるようになったので、今回は試しに使ってみてようと思います。

claspやTypeScriptの導入の仕方は、以下のものを参考にしました。

ディレクトリ構成は以下のような感じです。

gas_slackcommand
├── .clasp.json
├── node_modules/
├── package-lock.json
├── package.json
├── src
│   ├── appsscript.json
│   └── main.ts
└── tsconfig.json

スラッシュコマンド

今回自作するスラッシュコマンドは、以下のようにTodoを登録・表示・削除できるようなものを作成しようと思います。

  • /todo register hogeでスプレッドシートにhogeを登録する
  • /todo listでスプレッドシートに登録されているTodoを表示する
  • /todo done hogeでスプレッドシートからhogeを削除する

GASでの準備

まずはGASのコードをかきます。

main.ts
// トークンなどは、GASのプロパティ機能を使って登録しておく
const VERIFICATION_TOKEN = PropertiesService.getScriptProperties().getProperty('VERIFICATION_TOKEN');
const CHANNEL_NAME = PropertiesService.getScriptProperties().getProperty('CHANNEL_NAME');

const SHEET_ID = PropertiesService.getScriptProperties().getProperty('SHEET_ID');
const SHEET_NAME = PropertiesService.getScriptProperties().getProperty('SHEET_NAME');

// POSTメソッドを使うとき、GASでは必ずdoPostという関数を用意しておく
const doPost = (e) => {
    if (e.parameter.token != VERIFICATION_TOKEN) {
        throw new Error('Invalid token');
    }

    const command = e.parameter.text;

    // コマンドのオプションによって使い分けできるようにしておく
    const blocks = /^register .+/.test(command) ? registerTodo(command.replace("register ", "")) :
                   /^list$/.test(command) ? showTodos() :
                   /^delete .+/.test(command) ? deleteTodo(command.replace("done ", "")) :
                   {
                    "blocks": [
                        {
                            "type": "section",
                            "text": {
                                "type": "mrkdwn",
                                "text": "残念...コマンドが違うよ..."
                            }
                        }
                    ]
                   };

    return ContentService.createTextOutput(JSON.stringify(blocks)).setMimeType(ContentService.MimeType.JSON);
}

// Todoを登録しておく関数
const registerTodo = (todo) => {
    const sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName(SHEET_NAME);
    sheet.appendRow([todo]);
    console.log('Registered!')

    const blocks = {
        "blocks": [
            {
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": `*ToDoを登録したよー!* \n Todo:${todo}`
                }
            }
        ]
    }

    return blocks; 
}

// Todoを削除する関数
const deleteTodo = (todo) => {
    const sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName(SHEET_NAME);
    const lastRow = sheet.getLastRow();
    const values = sheet.getRange(1,1,lastRow,1).getValues();
    const todos = values.map(value => value[0]);

    const deleteTodoRow = todos.indexOf(todo) + 1;
    sheet.deleteRow(deleteTodoRow);
    console.log('Deleted!');

    const blocks = {
        "blocks": [
            {
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": `*ToDoを削除したよー!* \n Todo:${todo}`
                }
            }
        ]
    }

    return blocks; 
}

// Todoの一覧を返す関数
const showTodos = () => {
    const sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName(SHEET_NAME);
    const lastRow = sheet.getLastRow();
    const values = sheet.getRange(1,1,lastRow,1).getValues();
    const todos = values.map(value => {
        const todoBlock = {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": `・ ${value[0]}`
            }
        }

        return todoBlock;
    });

    const blocks = {
        "blocks": [
            {
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": "*ToDoの一覧だよー!*"
                } 
            },
            {
                "type": "divider"
            },
            ...todos
        ]
    }

    return blocks;
}

今回Slackに送るメッセージの内容は、Block Kit Builderを使って作成しました。Slack Appでは、結構リッチなメッセージが表示されたりするものもありますが、そちらはこちらで作成することが可能です!

個人的に結構面白かったので、興味ある方はぜひ使ってみてください!

コードが書き終わったら、GASのIDE上でデプロイします。デプロイする手順は以下です。

  1. GASのIDEを表示して、画面右上のデプロイ > 新しいデプロイを選択
  2. モーダルが表示されるので、種類の選択 > ウェブアプリを選択し、設定ではアクセスできるユーザーを全員に変更してデプロイ
    • デプロイする際に、諸々の許可が求められるので許可する
  3. デプロイが完了するとURLが表示されるのでコピー
    • 後で行うSlackの設定で利用

Slackでの準備

以下の手順を踏んでスラッシュコマンドの設定を行いました!

  1. アプリを作成する
    • スラッシュコマンドを作成するために、まずはSlack Appを作成する
    • Slack API: Applications | SlackにアクセスしてCreate New Appをクリック
    • アプリの設定方法を選択するモーダルが出てくるのでFrom scratchをクリック
    • 作成するアプリの名前と、それを導入するSlack workspaceを選択して、アプリを作成する
  2. アプリの設定を行う
    • 具体的にスラッシュコマンドを設定する
    • Basic Information > Add features and functionality > Slash Commands > Create New Commandの順に遷移
    • スラッシュコマンドに必要な情報を入力する
      • スラッシュコマンド
      • GASをウェブアプリとしてデプロイした時に表示されたURLをRequest URLに入力
      • 簡単なスラッシュコマンドの説明
      • スラッシュコマンドにオプション等をつける場合の簡単な説明
    • コードで使用しているVerification Tokenは、Basic Information > App Credentials > Verification Tokenの順で辿ると取得できる
      • 取得後は、GASのプロパティ機能を使い登録する
    • Install App > Install to Workspaceの順にクリックし、問題なければ許可する

実際に使ってみる

実際に使ってみると、Todoの登録、削除、一覧の表示ができました!
スクリーンショット 2022-10-20 14.14.22.png

さいごに

今回はSlackで簡単なスラッシュコマンドを作成してみました!コードに関しては要改善といった感じですが、参考になれば幸いです。

5
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?