Slack のチュートリアル - Slash コマンド

このチュートリアルでは Cloud Functions を使用して、Google Knowledge Graph API を検索する Slack Slash コマンドの実装方法について説明します。

目標

  • Slack で Slash コマンドを作成する。
  • HTTP Cloud Functions を書き込み、デプロイする。
  • Slash コマンドを使って Google Knowledge Graph API を検索する。

料金

このチュートリアルでは、以下を含む、Cloud Platform の有料コンポーネントを使用します。

  • Google Cloud Functions

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. GCP プロジェクトを選択または作成します。

    [リソースの管理] ページに移動

  3. プロジェクトに対して課金が有効になっていることを確認します。

    課金を有効にする方法について

  4. Cloud Functions と Google Knowledge Graph Search API を有効にします。

    APIを有効にする

  5. Cloud SDK をインストールして初期化します。
  6. gcloud コンポーネントを更新し、インストールします。
    gcloud components update &&
    gcloud components install beta
  7. Node.js 開発用に環境を準備します。

    セットアップ ガイドに移動

データの流れを可視化

Slack Slash コマンドのチュートリアル アプリケーションでのデータの流れでは、次の手順が行われます。

  1. ユーザーが Slack チャンネルで /kg <search_query> Slash コマンドを実行します。
  2. Slack がコマンドのペイロードを Cloud Functions のトリガー エンドポイントに送信します。
  3. Cloud Functions がユーザーの検索クエリとともにリクエストを Knowledge Graph API に送信します。
  4. Knowledge Graph API は、一致した結果を使って応答します。
  5. Cloud Function は Knowledge Graph API からの応答を Slack メッセージにフォーマット化します。
  6. Cloud Function はメッセージを Slack に送信します。
  7. ユーザーは Slack チャンネルでフォーマット化された応答を確認します。

次はこの手順を可視化した図です。

関数の作成

  1. Knowledge Graph API Key を作成します。

  2. アプリケーション コード用のディレクトリをローカル システム上に作成します。

    Linux / Mac OS X

    次のようにディレクトリを作成します。

    mkdir ~/gcf_slack

    作成したディレクトリに移動します。

    cd ~/gcf_slack

    Windows(CMD)

    次のようにディレクトリを作成します。

    mkdir %HOMEDRIVE%%HOMEPATH%\gcf_slack

    作成したディレクトリに移動します。

    cd %HOMEDRIVE%%HOMEPATH%\gcf_slack

  3. GitHub 上の Cloud Functions サンプル プロジェクトから index.js ファイルと package.json ファイルをダウンロードし、これらのファイルを gcf_slack ディレクトリに保存します。

  4. gcf_slack ディレクトリ内に config.json ファイルを作成し、次の内容を含めます。

    {
      "SLACK_TOKEN": "[YOUR_SLACK_TOKEN]",
      "KG_API_KEY": "[YOUR_KG_API_KEY]"
    }
    
    • [YOUR_SLACK_TOKEN] を、Slack から提供された検証トークンに置き換えます(アプリの設定の [基本情報] ページでこれを確認できます)。
    • [YOUR_KG_API_KEY] は、前の手順で作成した Knowledge Graph API Key に置き換えます。

関数のデプロイ

  1. HTTP トリガーを使用して kgSearch 関数をデプロイするには、gcf_slack ディレクトリで次のコマンドを実行します。

    gcloud beta functions deploy kgSearch --trigger-http
    

アプリケーションの設定

関数をデプロイした後、Slack Slash コマンドを作成する必要があります。このコマンドがトリガーされるたびに Cloud Function にクエリが送信されます。

  1. Slack Slash コマンドをホストする Slack アプリを作成します。それを、統合のインストール権限が与えられている Slack チームに関連付けます。
  2. Slash コマンドに移動し、[新しいコマンドを作成] ボタンをクリックします。
  3. コマンドの名前として「/kg」と入力します。
  4. コマンドの URL として「https://[YOUR_REGION]-[YOUR_PROJECT_ID].cloudfunctions.net/kgSearch」と入力します。ここで、YOUR_REGION は Cloud Function がデプロイされているリージョン、YOUR_PROJECT_ID は Cloud プロジェクト ID です。

    関数のデプロイが完了すると、両方の値がターミナルに表示されます。

  5. [保存] をクリックします。

  6. [基本情報] に移動します。

  7. [アプリをワークスペースにインストールする] をクリックし、画面の指示に従って、ワークスペース用にアプリケーションを有効にします。

    少し待つと、Slack Slash コマンドがオンラインになります。

コードについて

依存関係をインポートする

アプリケーションが Google Cloud Platform サービスと対話するには、いくつかの依存関係をインポートする必要があります。

Node.js

const config = require('./config.json');
const googleapis = require('googleapis');

// Get a reference to the Knowledge Graph Search component
const kgsearch = googleapis.kgsearch('v1');

ウェブフックの受け取り

ユーザー(または Slack)が関数のエンドポイントに HTTP POST リクエストを送信した時点で次の kgSearch 関数がモジュールによりエクスポートされ、実行されます。

Node.js

/**
 * Receive a Slash Command request from Slack.
 *
 * Trigger this function by making a POST request with a payload to:
 * https://[YOUR_REGION].[YOUR_PROJECT_ID].cloudfunctions.net/kgsearch
 *
 * @example
 * curl -X POST "https://us-central1.your-project-id.cloudfunctions.net/kgSearch" --data '{"token":"[YOUR_SLACK_TOKEN]","text":"giraffe"}'
 *
 * @param {object} req Cloud Function request object.
 * @param {object} req.body The request payload.
 * @param {string} req.body.token Slack's verification token.
 * @param {string} req.body.text The user's search query.
 * @param {object} res Cloud Function response object.
 */
exports.kgSearch = (req, res) => {
  return Promise.resolve()
    .then(() => {
      if (req.method !== 'POST') {
        const error = new Error('Only POST requests are accepted');
        error.code = 405;
        throw error;
      }

      // Verify that this request came from Slack
      verifyWebhook(req.body);

      // Make the request to the Knowledge Graph Search API
      return makeSearchRequest(req.body.text);
    })
    .then((response) => {
      // Send the formatted message back to Slack
      res.json(response);
    })
    .catch((err) => {
      console.error(err);
      res.status(err.code || 500).send(err);
      return Promise.reject(err);
    });
};

次の関数は、Slack が作成したベリフィケーション トークンと照合することで、受信したリクエストを認証します。

Node.js

/**
 * Verify that the webhook request came from Slack.
 *
 * @param {object} body The body of the request.
 * @param {string} body.token The Slack token to be verified.
 */
function verifyWebhook (body) {
  if (!body || body.token !== config.SLACK_TOKEN) {
    const error = new Error('Invalid credentials');
    error.code = 401;
    throw error;
  }
}

Knowledge Graph API のクエリ作成

次の関数はユーザーの検索クエリとともにリクエストを Knowledge Graph API に送信します。

Node.js

/**
 * Send the user's search query to the Knowledge Graph API.
 *
 * @param {string} query The user's search query.
 */
function makeSearchRequest (query) {
  return new Promise((resolve, reject) => {
    kgsearch.entities.search({
      auth: config.KG_API_KEY,
      query: query,
      limit: 1
    }, (err, response) => {
      console.log(err);
      if (err) {
        reject(err);
        return;
      }

      // Return a formatted message
      resolve(formatSlackMessage(query, response));
    });
  });
}

Slack メッセージのフォーマット化

最後に、次の関数は Knowledge Graph の結果をフォーマット化し、ユーザーに表示される適切な形式の Slack メッセージにします。

Node.js

/**
 * Format the Knowledge Graph API response into a richly formatted Slack message.
 *
 * @param {string} query The user's search query.
 * @param {object} response The response from the Knowledge Graph API.
 * @returns {object} The formatted message.
 */
function formatSlackMessage (query, response) {
  let entity;

  // Extract the first entity from the result list, if any
  if (response && response.itemListElement && response.itemListElement.length > 0) {
    entity = response.itemListElement[0].result;
  }

  // Prepare a rich Slack message
  // See https://api.slack.com/docs/message-formatting
  const slackMessage = {
    response_type: 'in_channel',
    text: `Query: ${query}`,
    attachments: []
  };

  if (entity) {
    const attachment = {
      color: '#3367d6'
    };
    if (entity.name) {
      attachment.title = entity.name;
      if (entity.description) {
        attachment.title = `${attachment.title}: ${entity.description}`;
      }
    }
    if (entity.detailedDescription) {
      if (entity.detailedDescription.url) {
        attachment.title_link = entity.detailedDescription.url;
      }
      if (entity.detailedDescription.articleBody) {
        attachment.text = entity.detailedDescription.articleBody;
      }
    }
    if (entity.image && entity.image.contentUrl) {
      attachment.image_url = entity.image.contentUrl;
    }
    slackMessage.attachments.push(attachment);
  } else {
    slackMessage.attachments.push({
      text: 'No results match your query...'
    });
  }

  return slackMessage;
}

Slash コマンドを使う

  1. 手動でコマンドをテストします。

    curl -X POST "https://[YOUR_REGION].[YOUR_PROJECT_ID].cloudfunctions.net/kgSearch" -H "Content-Type: application/json" --data '{"token":"[YOUR_SLACK_TOKEN]","text":"giraffe"}'
    

    ここで:

    • [YOUR_REGION] は関数がデプロイされる領域です。関数のデプロイが完了すると、これがターミナルに表示されます。
    • [YOUR_PROJECT_ID] は Cloud プロジェクト ID です。関数のデプロイが完了すると、これがターミナルに表示されます。
    • [YOUR_SLACK_TOKEN] は Slash コマンド設定で Slack から提供されたトークンです。
  2. 実行した内容がすでに完了したことをログで確認します。

    gcloud beta functions logs read --limit 100
    

  3. Slack チャンネルにコマンドを入力します。

    /kg giraffe

クリーンアップ

このチュートリアルで使用するリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

プロジェクトの削除

課金を停止する最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除する手順は次のとおりです。

  1. GCP Console で [プロジェクト] ページに移動します。

    プロジェクト ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

Cloud Functions の削除

Cloud Functions を削除しても、Cloud Storage に保存されたリソースは削除されません。

Cloud Function を削除するには、次のコマンドを実行します。

gcloud beta functions delete [NAME_OF_FUNCTION]

ここで、[NAME_OF_FUNCTION] は削除する関数の名前です。

また、Google Cloud Platform Console から Cloud Functions を削除することもできます。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...