Alexaスキルの配信コンテンツをSlackから更新できるようにしてみた（前編）

# はじめに
先日、Alexaスキル「[1分間セキュリティ](https://www.amazon.co.jp/gp/product/B07D9FQ19D)」をストア公開しました。
その日のサイバーセキュリティ関連の注目トピックが1分間で分かるスキルです。

配信するコンテンツは、Slackに投稿するとAlexaスキルへ反映できる仕組みになっています。
このSlackとAlexaスキルの連携は簡単に実現できるので、本稿で紹介したいと思います。

なお、連携機能は大きく分けてコンテンツ投稿機能とコンテンツ配信機能に分かれます。
1つの記事だと長くなりすぎるので、前編と後編に分け、前編ではコンテンツ投稿機能、後編ではコンテンツ配信機能を説明します。

#1. 全体図
![全体図](https://qiita-image-store.s3.amazonaws.com/0/261015/9eea5e6e-ca05-c8f2-1889-c05d7793d0b0.png)

#2. 前提条件
- Amazon開発者アカウント
- AWSアカウント
- Slackアカウント

また、Amazon S3バケットを1つ作成しておいてください。

#3. コンテンツ投稿機能
Slackに投稿された内容をAmazon S3に保存する機能です。
SlackのSlash Commandでコンテンツを投稿し、Amazon API Gatewayを通じてAWS Lambdaに送信されたコンテンツをS3 bucketに書き込みます。

![コンテンツ投稿機能](https://qiita-image-store.s3.amazonaws.com/0/261015/aeaf15de-8b26-d0d4-04be-1f09c9270829.png)

##3.1. AWS Lambda
[AWS Lambdaマネジメントコンソール](https://console.aws.amazon.com/lambda/home)にアクセスして、AWSアカウントでサインインしてください。

![AWS Lambda](https://qiita-image-store.s3.amazonaws.com/0/261015/355079e9-cf56-0b4c-1eab-f73d69c209d2.png)

###関数の作成
- 「関数の作成」をクリック
- 「設計図」を選択して「slack-echo-command」を検索し、表示された結果をクリック
- 「名前」に任意の関数名を入力
- 「ロール」に「AmazonS3FullAccess」ポリシーをアタッチしたロールを設定
- 「API Gateway トリガー」の「削除」をクリック
- 「環境変数」の「kmsEncryptedToken」の値を空欄に変更
- 「関数の作成」をクリック

![関数の作成](https://qiita-image-store.s3.amazonaws.com/0/261015/297e2f90-5bbf-7a75-5e7b-cc2309aa8bac.png)

###関数の実装
- index.jsを以下のコードに変更して「保存」をクリック

```javascript:index.js
'use strict';
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const qs = require('querystring');

function processEvent(event, callback) {
  const params = qs.parse(event.body);

  const user = params.user_name;
  const command = params.command;
  const channel = params.channel_name;
  const commandText = params.text;

  s3.putObject(
    {
      Body: commandText,
      Bucket: '# bucket name #',
      Key: '# key name #'
    },
    function(err) {
      if (err) {
        console.error('S3 error:', err);
        callback(err);
      } else {
        callback(null, `${user} posting successful.`);
      }
    }
  );
}

exports.handler = (event, context, callback) => {
  const done = (err, res) => callback(null, {
    statusCode: err ? '400' : '200',
    body: err ? (err.message || err) : JSON.stringify(res),
    text: err ? (err.message || err) : res,
    headers: {
      'Content-Type': 'application/json',
    },
  });
  processEvent(event, done);
};
```

※本稿ではSlackから送信されるトークンを検証を省略しています
※「# ～ #」で囲んだ部分は以下の値に書き換えてください。

|項目|値|
|:--|:--|
|bucket name|事前に作成したバケット名|
|key name|任意のキー名|

##3.2. Amazon API Gateway
[API Gateway コンソール](https://console.aws.amazon.com/apigateway/home)にアクセスして、AWSアカウントでサインインしてください。

![Amazon API Gateway](https://qiita-image-store.s3.amazonaws.com/0/261015/37263b45-9ef0-1bd3-9c4e-84acb19b6b14.png)

###APIの作成
- 「APIの作成」をクリック
- 「API名」に任意の名前を入力して「APIの作成」をクリック

![APIの作成](https://qiita-image-store.s3.amazonaws.com/0/261015/48be25dd-4240-d0b9-9aec-8a3d9b4ecf4b.png)

###メソッドの作成
- 「アクション」プルダウンから「メソッドの作成」を選択
- 表示されたプルダウンから「POST」を選択して隣の「✓」をクリック
- 「Lambda 関数」に作成した関数名を入力して「保存」をクリック

![メソッドの作成](https://qiita-image-store.s3.amazonaws.com/0/261015/293e00ee-c22a-ce95-4a3f-b09c32615c20.png)

###デプロイ
- 「アクション」プルダウンから「APIのデプロイ」を選択
- 「デプロイされるステージ」で「[新しいステージ]」を選択
- 「ステージ名」に任意の名前を入力
- 「デプロイ」をクリック

![デプロイ](https://qiita-image-store.s3.amazonaws.com/0/261015/df77dacf-f43c-8b33-585b-4c8a592b1d1b.png)

###URLの取得
- デプロイしたステージ名を展開してメソッド名(POST)をクリック
- 「URL の呼び出し」のURLをコピー（Slackの設定で使用）

![URLの取得](https://qiita-image-store.s3.amazonaws.com/0/261015/0a79f5b9-f1bd-8014-f520-10aa90d29aab.png)

##3.3. Slack
Slackワークスペースにサインインしてしてください。

![Slack](https://qiita-image-store.s3.amazonaws.com/0/261015/ec5942f5-4205-ce5b-4df6-768cee8636cc.png)

###Slash Commandsの設定
- [Slash Commands](https://slack.com/apps/A0F82E8CA-slash-commands)にアクセス
- 「設定を追加」をクリック
- 「Choose a Command」に任意の文字列を入力
- 「Add Slash Command Integration」をクリック
- 「URL」に「Amazon API Gateway」で取得したURLを貼り付け
- 「インテグレーションの保存」をクリック

![Slash Commandsの設定](https://qiita-image-store.s3.amazonaws.com/0/261015/abe89bca-b784-f872-b0b6-bf2487048de7.png)

##3.4. テスト
Slackワークスペースの任意のチャンネルで以下の内容をポストします。

```
/[設定したコマンド文字列] [コンテンツ]
```

S3バケットにコンテンツが保存されていることを確認してください。

# なかじめ
本稿では、SlackとAlexaスキルの連携としてコンテンツ投稿機能について紹介しました。
引き続き「[Alexaスキルの配信コンテンツをSlackから更新できるようにしてみた（後編）](https://qiita.com/ops/items/fc2c244ed0b3679f8e63)」でコンテンツ配信機能の紹介しています。