SlackからSMSを送信するNode.jsアプリケーションを開発する方法

March 30, 2022
執筆者
レビュー担当者

SlackからSMSを送信するNode.jsアプリケーションを開発する方法

背景

Slackは企業やコミュニティ内のメンバーや情報、ツールをまとめてくれる、便利なコミュニケーションツールです。

Slackで取り扱う情報は多種多様ですが、Slackが提供するSlack APIを使用すると、これまでSlack上で手作業で行っていたことを、自動化できます。SMSの送信も、自動化できることの1つです。

本稿では、Slack APIとTwilio、Node.jsを使って、SlackからSMSを送信するアプリを構築する方法をご紹介します。

目標

このチュートリアルを最後まで進めると、以下のような、Node.jsを使ったSlackからSMSを送信できるアプリケーションを開発できます。

完成アプリイメージ


チャンネル内で/smsとコマンドを送信すると、モーダルが出現し、 その後電話番号とメッセージを入力してSMSを送信します。送信がうまく実行されると、「SMSを送信しました」メッセージがアプリからチャンネルに送信されます。

必要事項

このチュートリアルを進めるには、以下の項目が必要です。

  • Node.js v16以降とnpm
  • JavaScriptとNode.jsの基礎知識。
  • Slackのワークスペース。作成方法について詳しくは、Slack公式ヘルプセンターを参照してください。
  • Twilioのアカウント。Twilioホームページをブラウザで開き、[今すぐ無料サインアッ]ボタンをクリックするか、Twilioアカウントの作成リンクからサインアップします。このリンクを使用するとアカウントのアップグレード時に10米国ドル相当分のクレジットが追加で付与されます。

Slackの設定

本稿では、Slackアプリを構築するためのJavaScriptフレームワークである、Bolt for JavaScriptを使用します。

Slackアプリを作成する

Slack APIページから、アプリを新規作成します。Create New Appをクリックします。

アプリの作成方法を選択するためのポップアップが表示されます。From scratchを選択します。

任意のアプリ名を入力し、アプリをインストールするワークスペースを選択します。本稿では、アプリ名を「Slack-Twilio-App」とします。

アプリを作成するワークスペースを選択します。

Create Appボタンをクリックします。

アプリケーション作成画面

アプリが作成されたら、Slack APIページのサイドナビゲーションのOAuth & Permissionsをクリックします。Bot Token Scopesセクションまでスクロールし、Add an OAuth Scopeをクリックします。

Scopesから、以下のスコープを選択します。

  • commands
  • chat.write

スコープ設定

ページトップの、Install to Workspace をクリックします。

インストールを承認すると、OAuth & Permissionsページに移動し、Bot User OAuth Tokenが表示されます。

トークン設定

このBot User OAuth Tokenは、Slackワークスペースにインストールされたアプリに紐づいたボットを表すトークンです。

トークンは後ほど利用しますので、コピーし、記録しておきます。

Slack APIページのサイドナビゲーションのBasic Informationをクリックし、App Credentialsまでスクロールします。Signing Secretをコピーし、記録します。

アプリ認証情報

ソケットモードを使用する

本稿で構築するアプリでは、「ユーザーが/smsコマンドを使用する」や、「ユーザーが電話番号とSMSメッセージを送信する」などのイベントを検知し、イベントに対して「モーダルを表示する」や「SMSを送信する」などのアクションを実行します。

イベントの検知には、SlackのEvents APIを使用します。

Events APIを使ったイベント検知の方法は複数ありますが、本稿ではEvents APIのソケットモードを使用します。ソケットモードは、公開されたHTTPエンドポイントを使用しなくてもEvents APIを使用できるSlackが提供する機能です。

本稿では、開発の方法をご紹介することを目的として、ソケットモードを使用しています。アプリをAWSやHerokuなどにホストする場合は、HTTPエンドポイントを使用してください。

詳しくは、Slack公式ドキュメントを参照してください。

Slack APIページのサイドナビゲーションのSocket Modeをクリックします。

Enable Socket Modeを有効化します。以下のようなポップアップが表示されます。

ソケットモード

ポップアップの設定方法は、次項で紹介します。

アプリレベルのトークンを生成する

本稿では、既に取得したBot User OAuth Token以外に、Events APIを使用するために必要なアプリレベルのトークンを生成します。

ポップアップに、任意のトークン名を入力します。

Add Scopeをクリックし、connections:writeを追加します。Generateをクリックします。

アプリのトークンが表示されます。コピーし、記録しておきます。

コマンドの作成

アプリで/smsコマンドが使用できるよう、コマンドを作成します。

Slack APIページのサイドナビゲーションのSlash Commandsをクリックします。

Create New Commandをクリックします。

新しいページが表示されます。

Commandフィールドに、/smsと入力し、Short Descriptionに簡単なコマンドの説明を入力します。

コマンド設定

Saveをクリックします。


Twilioの設定

SMSの送信にはTwilioを使用します。Twilioコンソールにログインします。

Account InfoAccount SIDAuth Tokenをコピーし、記録します。

認証情報

電話番号を購入する

SMSの送信に使用する電話番号を購入します。

TwilioコンソールのBuy a Numberにアクセスします。

Countryで、電話番号が属する国を選択します。現在、TwilioではSMS送信機能付きの日本の電話番号は販売しておりませんので、米国等を選択してください。

電話番号設定

各国の電話番号で使用できる機能について詳しくは、TwilioヘルプセンターのTwilioの国際電話番号の利用と機能(英語)を参照してください。

CapabilitiesSMSがチェックされていることを確認してください。

リストから希望の電話番号を探し、Buyをクリックして、購入します。電話番号をコピーし、記録しておきます。

プロジェクトの設定

プロジェクトフォルダを任意のディレクトリに作成し、移動します。以下のコマンドをターミナルで入力します。

mkdir slack-twilio-app
cd slack-twilio-app

環境変数の設定

環境変数を設定します。プロジェクトのルートディレクトリに、.envファイルを作成します。

.envファイルに以下の内容を追加します。

SLACK_BOT_TOKEN=XXXXX
SLACK_SIGNING_SECRET=XXXXX
SLACK_APP_TOKEN=XXXXX
TWILIO_ACCOUNT_SID=XXXXX
TWILIO_AUTH_TOKEN=XXXXX
TWILIO_PHONE_NUMBER=XXXXX

各環境変数の、XXXXXに、以下の値を割り当てます。

環境変数
SLACK_BOT_TOKENSlackのBot User OAuth Token。
SLACK_SIGNING_SECRETSlackのSigning Secret。
SLACK_APP_TOKENSlackのアプリレベルのトークン。
TWILIO_ACCOUNT_SIDTwilioのAccount SID。
TWILIO_AUTH_TOKENTwilioのAuth Token。
TWILIO_PHONE_NUMBER購入したTwilioの電話番号。E.164形式*で入力してください。

*E.164形式について詳しくは、Twilioヘルプセンターの「Twilioがサポートする国際電話番号のフォーマット(E164) とは?」を参照してください。

依存パッケージのインストール

プロジェクトに必要な依存パッケージをインストールします。

ターミナルで、以下のコマンドを実行します。

npm install @slack/bolt twilio dotenv

インストールしたパッケージの詳細は以下のとおりです。

  • @slack/bolt: Slackアプリを構築するためのJavaScriptフレームワーク。
  • twilio: Twilio APIに対するHTTPリクエストを、Node.jsで書けるようにするライブラリ。
  • dotenv: .env ファイルから環境変数を読み込めるようにするためのライブラリ。

コードを記述する

次に、Slackで/smsとコマンドを送信すると、モーダルが出現し、電話番号とメッセージを入力してSMSを送信する機能のコードを記述します。

プロジェクトのルートディレクトリで、server.jsファイルを作成します。

server.jsに、以下のコードを貼り付けます。

require('dotenv').config();

const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const fromPhoneNumber = process.env.TWILIO_PHONE_NUMBER;

// SlackとTwilioクライアントをインポート
const {App} = require('@slack/bolt');
const twilioClient = require('twilio')(accountSid, authToken);

// ソケットモードでアプリを初期化
// 署名シークレットとトークンを渡す
const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  socketMode: true,
  appToken: process.env.SLACK_APP_TOKEN,
});

// スラッシュコマンドの起動を検知
app.command('/sms', async ({ack, body, client, logger}) => {
  // コマンドのリクエストを確認
  await ack();
  const channelId = body.channel_id;
  try {
    // views.openメソッドでモーダルを表示
    const result = await client.views.open({
      // 有効なtrigger_idを渡す
      'trigger_id': body.trigger_id,
      // viewの値をペイロードに含める
      'view': {
        'type': 'modal',
        // viewを特定するための識別子
        'callback_id': 'modal_view',
        'title': {
          'type': 'plain_text',
          'text': 'SMS送信',
        },
        // モーダルBlockを設定
        'blocks': [
          {
            'type': 'input',
            'block_id': 'modal_phone_number',
            'label': {
              'type': 'plain_text',
              'text': '電話番号',
            },
            'element': {
              'type': 'plain_text_input',
              'action_id': 'phone_number',
              'placeholder': {
                'type': 'plain_text',
                'text': 'SMS送信先の電話番号をE.164形式で入力してください。',
              },
            },
          },
          {
            'type': 'input',
            'block_id': 'modal_message',
            'label': {
              'type': 'plain_text',
              'text': 'メッセージ',
            },
            'element': {
              'type': 'plain_text_input',
              'multiline': true,
              'action_id': 'message',
              'placeholder': {
                'type': 'plain_text',
                'text': 'SMSとして送信するメッセージを入力してください。',
              },
            },
          },
        ],
        'private_metadata': channelId,
        'submit': {
          'type': 'plain_text',
          'text': '送信',
        },
        'close': {
          'type': 'plain_text',
          'text': 'キャンセル',
        },
      },
    });
    logger.info(result);
  } catch (error) {
    logger.error(error);
  }
});

app.view('modal_view', async ({ack, view, body}) => {
  // モーダルでのデータ送信リクエストを確認
  await ack();
  const toPhoneNumber = view.state.values.modal_phone_number.phone_number.value;
  const message = view.state.values.modal_message.message.value;

  // ユーザーにメッセージを送信
  twilioClient.messages
      .create({
        body: message,
        from: fromPhoneNumber,
        to: toPhoneNumber,
      })
      .then((message) => {
        console.log(message.sid);
        app.client.chat.postMessage({
          channel: body['view']['private_metadata'],
          text: 'SMSを送信しました。',
        });
      })
      .catch((error)=> {
        console.log(error);
        app.client.chat.postMessage({
          channel: body['view']['private_metadata'],
          text: 'SMSの送信に失敗しました。',
        });
      });
});


(async () => {
  // アプリをスタート
  await app.start(process.env.PORT || 3000);
  console.log('⚡️ Bolt app is running!');
})();

ファイルを保存します。

コードを上から順に説明します。

まず、プロジェクトに必要な環境変数を設定し、BoltとTwilioのクライアントをインポートします。

ソケットモードや認証情報などを渡して、Slackアプリを初期化します。

次に、Boltのapp.commandメソッドで、/smsスラッシュコマンドの実行を検知します。

ack()で、スラッシュコマンドのリクエストを受け取ったことを、Slackに通知します。

tryブロックで、views.openメソッドを呼び出し、モーダルを開始します。

モーダルの設定を定義します。

trigger_idはスラッシュコマンドを実行した際に送信される、リクエストbodyに含まれるtrigger_idを指定し、コマンドとモーダルを紐付けます。

モーダルの内容を表現するblocks配列を含む、viewを設定します。

blocksは、Slackが提供するBlock Kit Builderで自由にデザインを設計し、表示を確認できます。blocksに指定できる設定について詳しくは、Slack公式ドキュメントを参照してください。

最後に、app.viewメソッドで、ユーザーが入力した内容を送信するアクションを検知し、TwilioでSMSを送信します。

ユーザーがモーダルからデータを送信すると、Slackからview_submissionリクエストが送信されます。

リクエストの内容はstateオブジェクトから取得します。stateオブジェクトには、valuesオブジェクトがあり、block_idと一位なaction_idと紐付けて値を保持しています。

valuesオブジェクトからユーザーが入力した電話番号とSMSメッセージを取得し、Twilioで電話番号宛にSMSメッセージを送信します。

メッセージ画面

お疲れ様でした!アプリの開発は以上です。次に、アプリをテストします。

アプリをテストする

アプリを作成したワークスペースで、任意のチャンネルを開きます。

チャンネル名をクリックします。ポップアップが表示されます。

チャンネル設定

[インテグレーション]をクリックします。

App配下の[アプリを追加する]をクリックし、作成したアプリを追加します。

アプリケーション追加

ターミナルで、プロジェクトのルートディレクトリで、以下のコマンドを実行します。

node server.js

問題なく実行されると、ターミナルに以下のメッセージが表示されます。

ターミナルメッセージ

Slackを開き、アプリを追加したチャンネルで/smsと入力し、送信します。

モーダルが表示されます。

SMSの送信先の電話番号をE.164形式で入力し、SMSとして送信するメッセージも入力します。

[送信]をクリックします。

指定した電話番号に、SMSメッセージが送信されます。

SMS

SlackからSMSを送信するNode.jsアプリが完成しました!

最後に

Slackは日々のコミュニケーションを円滑に進めてくれる、強力なツールです。そんなSlackと、Twilioを組み合わせて、SMSを送信するSlackアプリを開発しました。

次のステップとして、入力した電話番号をTwilioのLookup APIで検証する機能を追加してみるのは、いかがでしょうか?

ぜひ、本稿の内容を基盤に、独自のアプリを開発してみてください。

フィードバック、登壇、勉強会のお誘いなど気軽にsnakajima[at]twilio.comまでご連絡ください。開発中のプロジェクトに関してはGithub(smwilk)を覗いてみて下さい。