[Alexa] スキルイベントを使ってスキルが有効/無効化されたらSlackに通知してみる

スキルイベントを使うとイベント発生をLambdaで受け取ることができます。スキルが有効/無効化されるとSlackに通知するサンプルを作ってみました
2019.04.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Alexaのスキルでは、イベントサブスクリプションの設定を行うことで、スキルの特定のイベント発生時に通知を受け取ることができます。

【公式ドキュメント】Alexaスキルのスキルイベント

今回は、ユーザーのスキル有効/無効化イベントの発生を、スキルのバックエンドではなく別のLambdaファンクションで受け取り、Slackに通知してみたいと思います。

スキルのマニフェストにイベントサブスクリプションを追加する

スキルにイベントを追加するには、スキルのマニフェストにイベントサブスクリプションを含めるように定義を変更する必要があります。

ask-cliを使ってイベント発生を通知させたいスキルのマニフェストファイルを取得します。 (amzn1.ask.skill.xxxxxx-xxxxxxには対象のスキルIDを入れてください)

$ ask api get-skill -s amzn1.ask.skill.xxxxxx-xxxxxx > skill.json

取得したskill.jsonを開いて、以下のようにeventsオブジェクトを追加します。 subscriptionsには以下の2つのイベントを指定します。

  • SKILL_ENABLED(スキルの有効化)
  • SKILL_DISABLED(スキルの無効化)

endpointのURIには、イベント発生を受け取るLambdaファンクション(後ほど説明)のARNを指定します。

{
  "manifest": {
    "apis": {
      "custom": {
        "endpoint": {
          "uri": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxx:function:alexa-skill-backend-function" //これはスキルのバックエンドLambda
        },
        "interfaces": []
      }
    },
    "events": {
      "subscriptions": [
        {
          "eventName": "SKILL_ENABLED"
        },
        {
          "eventName": "SKILL_DISABLED"
        }
      ],
      "endpoint": {
        "uri": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxx:function:alexa-skill-event-handler-function"
      }
    },
    "manifestVersion": "1.0",
    (以下省略)
}

以下を実行して、スキルのマニフェストを更新します。

$ ask api update-skill -s amzn1.ask.skill.xxxxxx-xxxxxx -f skill.json

イベント発生をSlackに通知するLambda

それでは、スキルイベントの発生をSlackに通知するLambdaを作成してみます。

Lambdaでは、トリガーとしてAlexa Skills Kitを設定しておく必要があります。

Lambdaのコード(Node.js 8.10)は以下です。

const request = require('request-promise');
const url = process.env.WEBHOOK_URL;

exports.handler = async (event) => {
  console.log(JSON.stringify(event));
  const userId = event.context.System.user.userId; //対象のユーザーID
  let message = '';
  switch (event.request.type) {
    case 'AlexaSkillEvent.SkillEnabled':
      message = '以下のユーザーがスキルを有効にしました :tada: ';
      break;
    case 'AlexaSkillEvent.SkillDisabled':
      message = '以下のユーザーがスキルを無効化しました :cry: ';
      break;
  }
  const option = {
    'url': url,
    'header': {
      'Content-Type': 'application/json'
    },
    'method': 'POST',
    'json': true,
    'body': {
      'text': message + '```' + userId + '```'
    }
  };
  const res = await request(option);
  console.log(res);
};

request-promiseを利用しているので、以下の2つをnode_modulesにインストールしてLambdaにアップロードするようにしてください。

  • request
  • request-promise

また、環境変数WEBHOOK_URLに、Slackで設定したIncoming WebhooksのURLを指定します。

SlackのIncoming Webhooks設定がよくわからない場合は、以下などを参照してください。

SNSでSlackにメッセージ送信する #slack

なお、今回はスキルのバックエンドではなく、別のLambdaファンクションでイベント発生を受け取ってSlackへ通知する処理を行っていますが、スキルのバックエンド上でまとめて行うこともできます。 その場合は、マニフェストのevents.endpointにスキルのバックエンドLambdaを指定して、以下のような感じでハンドラを定義するとよいでしょう。

【Github】alexa-cookbook/feature-demos/skill-demo-list-events

スキルを有効/無効化してみる

準備ができたので、対象のスキルをAlexaアプリから有効/無効にしてみましょう。 今回は開発中のサンプルスキルを対象としました。

実際に有効/無効にすると、無事Slackに通知が届きました。

おわりに

スキルイベントを利用して、ユーザーのスキル有効/無効化をSlackに通知するサンプルを作ってみました。 スキルイベントでは、アカウントリンクやスキル権限操作のイベントを取得することもできるので、本エントリのような通知やユーザーの集計、分析に役立つのではないでしょうか。

参考リンク