
翻訳者から: Slackと統合されたアプリケーションを開発する方法について、井村知美の記事 を公開しています。
アクションは、Slackユーザーがメッセージを使用してアプリケーションと対話できるようにするものです。バグの問題を報告したり、ヘルプデスクにリクエストを送信したり、他のことを行ったりします。 この機能は、コメントや共有などの組み込み機能に似ています。
このチュートリアルでは、ライブアプリケーションを作成するプロセス全体をガイドします。
Skillboxの推奨事項: 2年間の実践コース「私はPRO Web開発者です。 」
「Habr」の読者には、「Habr」プロモーションコードを使用してSkillboxコースに登録すると10,000ルーブルの割引があります。
このチュートリアルは、Slack APIを学習したい人に役立ちます。 アプリケーションの開発時にはNode.jsが使用されるため、会話の内容を繰り返したい場合はインストールしてください。
完成したプロジェクトはGitHubにあり、 Glitchの簡易バージョンがあります。
ClipIt! たるみ
仮想のClipItアプリケーション用にSlack-appを開発します! データベースにWebページを保存することでWebページの一部を「レイアウト」できるWebサービスを管理していると想像してみましょう。 ユーザーは、モバイルデバイスまたはPCから保存されたコンテンツにアクセスできます。サービスはマルチプラットフォームです。 また、ClipIt! Actionを使用してSlackメッセージング環境にテキストを添付できます。
以下は、アプリケーションの動作を示すgifです。

そして、これがClipItとのユーザーインタラクションアルゴリズムです! Slackから:
- ユーザーはメッセージにカーソルを合わせ、ドロップダウンメニューで[メッセージをクリップ]を選択します。
- ダイアログが開き、より多くの機会が与えられます。
- ユーザーがアクションを確認します。
- ClipIt! SlackはメッセージをClipIt!データベースにエクスポートします。
- ClipIt! Slackは確認メッセージとともにDMをユーザーに送信します。
アプリケーションをカスタマイズする
Slackアカウントにログインし、 このリンクを使用してアプリケーションを作成します。 名前とスコープを入力します。

[アプリの作成]ボタン、[基本情報]の順にクリックして、[アプリの資格情報]までスクロールします。

その後、Signing Secretを開き、ルートノードの.envファイルで環境変数SLACK_SIGNING_SECRETとして使用するコードをコピーします。 以下の「リクエストの確認」セクションで、その内容とその使用方法を説明します。
SLACK_SIGNING_SECRET = 15770a ...
さらに下にスクロールして、アプリケーションのアイコンと説明を表示情報に入力します。
次に、インタラクティブコンポーネントでインタラクティブ機能を有効にします。 これにより、ページにさらにフィールドが表示されます。

リクエストURLを入力します-これは、ユーザーがアクションを開始したときにSlackが対応するデータを送信するアドレスです。
これは、アプリケーションコードが実行されているサーバーのURLである必要があります。 たとえば、これをすべてグリッチに投稿した場合、URLはexample.glitch.me/actionsのようになります 。 ngrokなどのサービスを使用しているときにトンネリングを使用する場合は、サービスURL(たとえば、 example.ngrok.io 、次に追加/アクション)を使用します。
リクエストURLを入力したら、[アクション]まで下にスクロールし、[新しいアクションを作成]をクリックします。 フォームに入力します。

[作成]、[変更を保存]の順にクリックします。
次に、ボットユーザーに移動します。 [ボットユーザーの追加]をクリックし、アプリケーションボットに名前を付けます。

[ボットユーザーの追加]をクリックして保存します。
次の手順では、OAuthとアクセス許可に移動し、[ワークスペースにアプリをインストール]をクリックします。 インストールが完了すると、ページはアクセストークンを使用してOAuthと権限に戻ります。 ボットトークンをコピーして、すべてを.envファイルに保存します。
SLACK_ACCESS_TOKEN = xoxb-214 ...
さらに、同じページでスコープをアクティブにする必要があります。 これを行った後、ボットとコマンドの両方が強調表示されていることを確認してください。
すべての設定が準備できたので、作成を開始します-アプリケーションを作成しています。
アプリケーション作成
前述のように、アプリケーションの作成時には、Node.jsとExpressJSが使用されます。 これらすべてを使用するには、ExpressJSの依存関係、bodyParserなどをインストールします。 そこで、私はaxios HTTPリクエストクライアントとqsを使用します。
$ npm install express body-parser axios qs dotenv --save
最も重要なものから始めましょう。 後で機能を追加するときにコードを変更します。 まず、index.jsファイルを作成します。 このファイルでは、対応するポートでリッスンするようにサーバーを設定します。
/* Snippet 1 */ require('dotenv').config(); // To grab env vers from the .env file const express = require('express'); const bodyParser = require('body-parser'); const axios = require('axios'); const qs = require('qs'); const app = express(); // The next two lines will be modified later app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); const server = app.listen(5000); // port
続行する前に、これから説明するすべての操作の原則を説明する図を見てみましょう。

ユーザーがメッセージメニューにあるアクションを実行すると、各スレッドが初期化されます。 message_actionイベントが発生するとすぐに、Slackは以前に登録されたリクエストのURLをペイロードアプリケーションに送信します。

エンドポイントは次のように記述できます。
/* Snippet 2 */ app.post('/actions', (req, res) => { const payload = JSON.parse(req.body.payload); const {type, user, submission} = payload; // Verifying the request. I'll explain this later in this tutorial! if (!signature.isVerified(req)) { res.sendStatus(404); return; } if(type === 'message_action') { // open a dialog! } else if (type === 'dialog_submission') { // dialog is submitted } });
イベントタイプがmessage_actionの場合、アプリケーションはダイアログを開きます。
次に、dialog.openメソッドを使用して、Slackクライアントで開くダイアログコンテンツの構造を定義するコードを追加します。
/* Snippet 2.1 */ const dialogData = { token: process.env.SLACK_ACCESS_TOKEN, trigger_id: payload.trigger_id, dialog: JSON.stringify({ title: 'Save it to ClipIt!', callback_id: 'clipit', submit_label: 'ClipIt', elements: [ { label: 'Message Text', type: 'textarea', name: 'message', value: payload.message.text }, { label: 'Importance', type: 'select', name: 'importance', value: 'Medium ', options: [ { label: 'High', value: 'High ' }, { label: 'Medium', value: 'Medium ' }, { label: 'Low', value: 'Low ️' } ], }, ] }) }; // open the dialog by calling the dialogs.open method and sending the payload axios.post('https://slack.com/api/dialog.open', qs.stringify(dialogData)) .then((result) => { if(result.data.error) { res.sendStatus(500); } else { res.sendStatus(200); } }) .catch((err) => { res.sendStatus(500); });
ここでは、axiosモジュールを使用してSlackへのPOSTリクエストを実行します。 その後、dialog.openメソッドはHTTPステータス200を送信してダイアログを開きます。

ユーザーがダイアログを開始すると、エンドポイントもアクティブになります。 スニペット2のコードでは、ビューが受信されたことをSlackが認識できるように、空のHTTP 200要求で応答する必要があります。
最後に、chat.postMessageメソッドを使用して確認メッセージをユーザーに送信します。
/* Snippet 2.2 */ else if (type === 'dialog_submission') { res.send(''); // Save the data in DB db.set(user.id, submission); // this is a pseudo-code! // DM the user a confirmation message const attachments = [ { title: 'Message clipped!', title_link: `http://example.com/${user.id}/clip`, fields: [ { title: 'Message', value: submission.message }, { title: 'Importance', value: submission.importance, short: true }, ], }, ]; const message = { token: process.env.SLACK_ACCESS_TOKEN, channel: user.id, as_user: true, // DM will be sent by the bot attachments: JSON.stringify(attachments) }; }
それでは、コードを実行して、アプリケーションがSlackと統合してどのように機能するかを見てみましょう。 すべてが順調であれば、最後の手順を実行します。
確認をリクエスト
それでは、アプリケーションのセキュリティを管理し、リクエストの検証を追加しましょう。 Slackからのリクエストを確認してから、作業に移してください。
これを行うには、最上部にあるスニペット1に戻ります。 コメントがある場所を置き換えます//次の2行は次のように変更されます。
/* Snippet 3 */ const rawBodyBuffer = (req, res, buf, encoding) => { if (buf && buf.length) { req.rawBody = buf.toString(encoding || 'utf8'); } }; app.use(bodyParser.urlencoded({verify: rawBodyBuffer, extended: true })); app.use(bodyParser.json({ verify: rawBodyBuffer }));
すでに暗号化をverifySignature.jsに接続しているので、index.jsの先頭に関数を追加するだけです。
const signature = require('./verifySignature');
次に、検証を実行します。
if(!signature.isVerified(req)) { // when the request is NOT coming from Slack! res.sendStatus(404); // a good idea to just make it “not found” to the potential attacker! return; }
アプリケーションがSlackからリクエストを受信するたびに、リクエストを検証することをお勧めします。
コードを再度実行し、すべてが正常に機能する場合、成功を祝うことができます! おめでとうございます!
- オンラインコース「Profession frontend-developer」
- 実践コース「Mobile Developer PRO」 。
- 実用的な年次コース「PHP開発者0からPRO」 。