Help us understand the problem. What is going on with this article?

AlexaとLINEをアカウントリンクしてAlexaスキルにLINEメッセージ送信機能を実装する

More than 1 year has passed since last update.

AlexaスキルからLINEメッセージを送れたら面白いなと思って調べながら試行錯誤してたら、できました。

仕組み

仕組みを図で表現すると、ざっくり以下のような感じです。
image.png

やること

大まかには、以下の感じで実現できました。

開発側で準備すること
 1.LINEのプロバイダ&チャネル作成
 2.Alexa開発者コンソールでアカウントリンクを設定
 3.lambdaでのコーディング

ユーザーがやること
 1.アカウントリンクの実施・Messaging APIチャネル(LINE Bot)を友だちに追加
 2.Alexaスキル呼び出し

以下、各ステップを簡単に説明していきます。

1.開発側で準備すること

1.1.LINEのプロバイダ&チャネル作成

LINE Developers のページでプロバイダとチャネルを作成してください。

チャネルは2個作成します。
 ・通知送信用のMessaging APIチャネル(LINE Bot)
 ・アカウントリンク用のLINEログインチャネル

プロバイダ、チャネル作成は以下の公式リファレンスをみて進めてください。
Messaging APIを利用するには
LINEログインを利用するには

通知送信用のMessaging APIチャネル(LINE Bot)

Messaging APIチャネルを作成する際に気を付けるべき点は以下です。
・プランは"Developer Trial"にする(PUSH_MESSAGEを利用可能にしたいため)
・アクセストークンを発行し控えておく(→lambdaソースで利用するため。失効までの時間を0時間にしておけばずっと有効にできる)

アカウントリンク用のLINEログインチャネル

LINEログインチャネルを作成する際、気を付けるべき点は以下です。
・アプリタイプは"WEB"にする
・"このチャネルにリンクされたボット"で、Messaging APIチャネルを指定する
・作成したチャネルで、チャネルIDとシークレットを控えておく(→Alexa開発者コンソールで利用する)
・アプリ設定タブのCallback URLに、後述するAlexa開発者コンソールのアカウントリンク画面下部にある"リダイレクト先のURL"を貼り付ける

image.png
上のキャプチャは、アプリタイプをWEBで作成し、Messaging APIチャネルをリンクした様子です。

image.png
こちらは、アプリ設定のCallback URLにAlexa開発者コンソールのリダイレクトURLを貼り付けたところです。

そんな感じで2個チャネルを作成しました。
image.png
(※LINEログインチャネルを非公開にしていますが、状況に応じて公開にする必要あり)

1.2.Alexa開発者コンソールでアカウントリンクを設定

つぎにAlexaスキル側を準備します。
Alexa開発者コンソールで、LINE連携したいカスタムスキルの編集画面でアカウントリンクの設定をします。

スキルビルド画面左側の"アカウントリンク"をクリックしてアカウントリンク設定画面に遷移し、アカウントリンクを有効にして以下の通り設定します。
認証画面のURIにbot_promptパラメータを付与しているのがミソです。
これを入れることで、アカウントリンク時にMessaging APIチャネルの友だち追加画面を挟むことができます。

項目
認証画面のURI https://access.line.me/oauth2/v2.1/authorize?bot_prompt=aggressive
アクセストークンのURI https://api.line.me/oauth2/v2.1/token
クライアント ID (LINEログインチャネルのチャネルID)
クライアントシークレット (LINEログインチャネルのシークレット)
クライアントの認可方法 HTTP Basic認証(推奨)
スコープ profile
ドメインリスト (空)
デフォルトのアクセストークンの有効期限 (空)

1.3.lambdaでのコーディング

カスタムスキルのlambdaソースは、以下のようにコーディングします。
※一部抜粋
※package.jsonも適当に修正してください

node.js
'use strict';
const Alexa = require('ask-sdk');
const request = require('request');
const LINE_API_BASE_URL = 'https://api.line.me/v2';

// LINE Messaging APIのチャネル設定で発行したアクセストークン
const MESSAGING_API_ACCESSTOKEN = '【ここにMessaging APIチャネルで生成したアクセストークンを記載する】';

// スキル起動
const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    },
    async handle(handlerInput) {
        const lineMessage = "Alexaからのメッセージです!";
        const speechText = 'LINEアカウントにメッセージを送信しました!';
        // チャネルへのアクセストークン取得
        const profileAccessToken = handlerInput.requestEnvelope.session.user.accessToken;

        // ソーシャルAPIでユーザープロフィール情報を取得
        var resBody = await getProfile(profileAccessToken);

        // プロフィール情報からuserIdを取得
        const userId = resBody.userId; 

        // プッシュ通知を送信
        resBody = await push(userId,lineMessage);

        return handlerInput.responseBuilder
            .speak(speechText)
            .reprompt(speechText)
            .getResponse();
    }
};

// LINEユーザー情報を取得する
function getProfile(profileAccessToken){
    var options = {
        url: LINE_API_BASE_URL + '/profile',
        headers: {
            'Authorization': 'Bearer ' + profileAccessToken
        },
        json: true,
    };

    // GETでリクエスト送信
    return new Promise(function(resolve, reject){
        request.get(options, function(err, res, body) {
            if (err) {
                reject(body);
                return;
            }
            resolve(body);
        });
    });
}

// Messaging APIチャネルからpushメッセージを送信する
async function push(to,message){
    // メッセージオブジェクトを生成
    var objMessage = {
        type:"text",
        text:message
    };
    // body生成(messagesは配列で最大5件まで同時に送信できるが、今回は1件だけ送信する)
    var body = {
        to: to,
        messages: [objMessage]
    };
    var options = {
        url: LINE_API_BASE_URL + '/bot/message/push',
        headers: {
            'Content-type': 'application/json; charset=UTF-8',
            'Authorization': 'Bearer ' + MESSAGING_API_ACCESSTOKEN
        },
        json: true,
        body: body
    };

    // POSTでリクエスト送信
    return new Promise(function(resolve, reject){
        request.post(options, function(err, res, body) {
            if (err) {
                reject(body);
                return;
            }
            resolve(body);
        });
    });
}

// 以下、省略。。。

ここまでできたら開発側の準備は完了です。

2.ユーザーがやること

2.1.アカウントリンクの実施・Messaging APIチャネル(LINE Bot)を友だちに追加

Alexaのユーザーページから、作成したスキルのアカウントリンクを実施してください。
image.png
"有効にする"ボタン押下でLINEログイン画面(作成したLINEログインチャネル)に遷移します。
image.png
ログインすると、権限利用の許可を求められる画面に遷移しますので、"許可する"を押下します。
image.png
許可すると、作成したMessaging APIチャネルを友だちに追加する画面に遷移します。
私はこのチャネルを以前友だち追加していて今はブロック状態のため"ブロック解除"になってますが、初めての場合"友だち追加"とかになっているはずです。
image.png

チャネルを友だち追加してアカウントリンクは完了です。アカウントリンク完了画面に遷移します。
("LINE連携"はスキル名です)
image.png

2.2.Alexaスキル呼び出し

アカウントリンク後、スキルを実行してみます。

Echoの方の挙動は以下の感じ。
image.png

LINEをみてみると…
image.png
通知が届いています!
(上の絵文字交じりのメッセージは友だち追加時に自動送信されるものです)

注意点

LINEのMessaging APIチャネルは、無料枠(Developer Trial)だと友達上限が50人のため、必然的にAlexaスキルの利用者上限も50人となってしまいます。
回避するには、以下のような工夫が必要そうです(思いついたもの列挙しただけです)。
 ・有料版を利用する
 ・チャネルを複数作る
 ・先着50名とそれ以降の人で機能に差をつける

参考:LINE@ プラン・料金

また、上記のlambdaソースは正常系しかカバーしていません。
ざっと思いつくだけでも以下の考慮が必要になるかと思います。
 ・アカウントリンクしないままスキルを実行した場合
 ・アカウントリンクはしたがMessaging APIチャネルを友だち追加せずにスキル実行した場合
 ・API連携に失敗した場合

最後に

以上でAlexaスキルからLINEメッセージ送信を実装することができました。
AlexaとLINE Botをうまく連携すればスキル開発の可能性が広がりそうです。

最後の最後に…
結構がんばって書いたんですが、先人がいました…
AlexaからLINE Botに通知してみる(ASK+Messaging API+LINEログイン+Social API)

私の記事との差はアカウントリンク時の認証画面のURIにパラメータ付与があるかどうか(→アカウントリンク後に友だち追加画面を挟むかどうか)くらいです。

参考URL

[Alexa] LINEログインでAccount Linkingしてみた
LINE Messaging API を使ってLINEにメッセージ送信/メッセージ返信する
LINE Login 超入門
ユーザープロフィールを取得する (LINE Developers)
Messaging APIリファレンス (LINE Developers)

igarashisan_t
元教員。今はエンジニア。 ソフトウェア開発やっています。 Alexaスキル「ダーツの対戦」がAlexaスキルアワード2019 ゲーム部門賞を受賞しました! https://www.amazon.co.jp/dp/B07W6SCCS1/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした