SIOS Tech. Lab
  • Azure
  • OSS
  • コンテナ
  • 認証
  • シリーズ
  • ホーム
  • クラウド
  • Azure

LINEのBOTをRaspberry Piで作成し、BOTとのやりとりをOpen JTalkで読み上げ、Azure DocumentDBに保存し、Azure App Service上のWebアプリで一覧表示する

2016-05-252021-01-27

SHARE

  • ポスト
  • シェア
  • はてブ
  • LINE

こんにちは、サイオステクノロジー技術部の武井です。

今回は、LINEのBOTをRaspberry Piで作成し、BOTとのやりとりをOpen JTalkで読み上げ、Azure DocumentDBに保存し、Azure App Service上のWebアプリで一覧表示する仕組みを作ってみました。

写真を撮ってみました。こんなかんじです。

IMG_1812

目次
  • 1 Open JTalk、Azure DocumentDB、Azure App Serviceとは?
  • 2 何ができるの?
  • 3 どんな仕組み?
  • 4 どうやって作るの?

Open JTalk、Azure DocumentDB、Azure App Serviceとは?

Open JTalkはオープンソースの音声合成システムで、テキストを渡すとその内容を読み上げてくれます。

Azure DocumentDBはJSON形式の文書をそのまま保存できるスキーマレスのデータベースです。リレーショナル・データベースとは違い、スキーマの設計はいりません。やりとりされるJSONのデータをそのままデータベースに登録が可能であり、クエリ言語も慣れ親しんだSQLを使うので、データ操作も簡単です。

Azure App ServiceはAzure上でアプリケーションを動作することができるPaaS環境になります。OSやアプリケーションサーバーを構築する必要もなく、パッチ当てもする必要がありません。開発者はソースコードさえ登録すれば、後の面倒なことは全部Azureがやってくれます。

何ができるの?

つまり何をするものかというと、私が作成したLINEのBOTとお友達になって、そのBOTに対して発言すると、ちょっとした会話ができて、さらにその会話をOpen JTalk(音声合成システム)によって音声で読み上げ、その会話の内容をAzure DocumentDBにJSON形式で保存して、さらにAzure App Service上で作成したPHPのWebアプリケーションからDocumentDBにアクセスして、会話を一覧表示します。

文章だけではわかりにくいと思いますので、構成図を書いてみました。

system

どんな仕組み?

仕組みとしては以下です。

1.LINEのBOTを作成できるサービス「BOT API Trial Account」にアカウント登録する。

2.「BOT API Trial Account」の管理画面からコールバックURLを設定する。BOTアカウントに対して発言をすると、このコールバックURLに対して、JSON形式でPostリクエストが来る。コールバックURLのアクセス先はRaspberry Pi上にWebアプリケーションとして構築する。

3.BOTアカウントに対して発言したことによって、Raspberry Pi上のコールバックURL宛にリクエストがあったJSONを解析する。

4.3の内容をOpen JTalkに渡して、喋らせる。

5.Azure DocumentDBのRest APIを用いて、会話の内容をJSON形式のまま保存する。

6.Azure App Service上に作成したWebアプリケーションにアクセスすると、会話の内容が一覧表示される。

どうやって作るの?

構築手順を記載します。

まず、Raspberry Piを用意します。OSは何でもよいのですが、今回はRaspberry Piの本家サイトで提供されているRaspbianのイメージを使いました。このあたりの方法はWebにたくさんありますので、そちらを参照して下さい。

Open JTalkをインストールします。インストール対象のソフトウェアを以下のサイトからダウンロードして下さい。

■Open JTalk
https://downloads.sourceforge.net/open-jtalk/open_jtalk-1.09.tar.gz

■hts_engine API
https://osdn.jp/projects/sfnet_hts-engine/downloads/hts_engine%20API/hts_engine_API-1.10/hts_engine_API-1.10.tar.gz

■辞書ファイル
https://osdn.jp/frs/g_redir.php?m=onet&f=%2Fopen-jtalk%2FDictionary%2Fopen_jtalk_dic-1.09%2Fopen_jtalk_dic_utf_8-1.09.tar.gz

■音声ファイル
https://osdn.jp/frs/g_redir.php?m=liquidtelecom&f=%2Fmmdagent%2FMMDAgent_Example%2FMMDAgent_Example-1.4%2FMMDAgent_Example-1.4.zip

# mkdir /usr/local/hts_engine_API
# tar xzvf hts_engine_API-1.10.tar.gz
# ./configure --prefix=/usr/local/hts_engine_API
# make
# make install

# mkdir /usr/local/open_jtalk
# tar xvzf open_jtalk-1.09.tar.gz
# cd open_jtalk-1.09
# ./configure --prefix=/usr/local/open_jtalk --with-hts-engine-header-path=/usr/local/hts_engine_API/include --with-hts-engine-library-path=/usr/local/hts_engine_API/lib --with-charset=UTF-8
# make
# make install

# tar xzvf open_jtalk_dic_utf_8-1.09.tar.gz
# cp -r open_jtalk_dic_utf_8-1.09 /usr/local/open_jtalk/

# unzip MMDAgent_Example-1.4.zip
# mkdir /usr/local/hts_engine_API/hts_voice
# cp -r MMDAgent_Example-1.4/Voice/mei/*htsvoice /usr/local/hts_engine_API/hts_voice/

試しに「こんにちは」と喋らせてみます。

# echo "こんにちは" | /usr/local/open_jtalk/bin/open_jtalk -m /usr/local/hts_engine_API/hts_voice/mei_normal.htsvoice -ow output.wav -x /usr/local/open_jtalk/open_jtalk_dic_utf_8-1.09

上記のコマンドを発行すると、「output.wav」というファイルができます。これをaplayで再生するのですが、Raspberry PiはデフォルトでLINE Out端子から音声が出力されません。以下のコマンドを実行して下さい。

# amixer cset numid=3 1

以下のコマンドで音量を調節して下さい。

# alsamixer

LINE Out端子にスピーカをつないで、以下のコマンドを実行して下さい。

# aplay output.wav

女性の声で「こんにちは」と聞こえてきたはずです。これでOpen JTalkのインストールは完了です。

※Open JTalkについては以下の記事を参考にしました。この記事を作成したH氏に感謝致します。

iBeacon & Raspberry Pi & iPhone & Azure で天気予報

次は、LINE BOT API Trial Accountに登録します。これは、期間限定、人数限定でLINEのBOTを作成するためのAPIを無料で利用できるサービスです。以下のURLから登録して下さい。登録はお早めに。

https://business.line.me/services/products/4/introduction

申請する途中で「Callback URL」」を指定するところが出てきます。これはRaspberyy Pi上に構築したWebアプリケーションのURLである必要があり、BOTに対して発言した時に、このURLに発言内容がHTTPSプロトコルでJSON形式で送られてきます。こちらご注意頂きたいのが、このURLは公的な認証機関でサインした証明書を利用したサイトでないとダメなのです。オレオレ不可です。また、もちろん仕組み上このURLには外部からアクセスできる必要があります。セキュリティには十分お気をつけ下さい。

次は、DocumentDBを作成する準備をします。Azureポータルにログインし、「参照」→「データ + ストレージ」 → 「Azure DocumentDB」の順番にクリックして、一番右のブレードに出てくる画面で必要な事項を入力して「作成」をクリックして下さい。「ID」は任意の名称で結構です。サブスクリプションやリソースグループは環境に応じたものを入力して下さい。場所は自分の住んでいるところに一番近いほうが、お財布にやさしいかと思います。

1

これで、Azure DocumentDBを作成する準備が整いました。本来なら、、これからデータベースとコレクションの作成を行わなければいけないのですが、以降に紹介するPHPスクリプトで自動的に作成されるようになっていますので、割愛します。

次は、BOTに対して発言があった際にLINEからコールされるコールバックURLの呼び出し先をRaspberry Pi上に作成します。Raspberry PiにApache、PHPをインストールして、Document Rootに以下のソースを置いて下さい。

<?php
require_once '/var/www/html/phpdocumentdb.php';

// DocmentDBのホスト名を指定する
$host = 'https://hostname.documents.azure.com';

// DocumentDBのマスターキーを指定する
$master_key = 'maserkey';

// DocumentDBに接続する
$documentdb = new DocumentDB($host, $master_key,$debug = true);

// LINEのBOTアカウント管理画面に表示されている「Channel ID」、「Channel Secret」、「MID」を指定する
$channel_id = "1234567890";
$channel_secret = "abcdefghijklmnopqrstuvwxyz";
$mid = "aaaabbbbccccdddd";

// コールバックURL宛のリクエストを取得する
$json_string = file_get_contents('php://input');
$json_object = json_decode($json_string);
$content = $json_object->result{0}->content;
$text = $content->text;
$from = $content->from;
$message_id = $content->id;
$content_type = $content->contentType;

// Azure DocumentDBに入れるためIDを生成する
$json_object->id = $json_object->result{0}->content->id;

// 送信者を入れる
$json_object->sender = 'user';

$user_document = json_encode($json_object);

// ユーザーの発言をDocumentDBに保存する
$documentdb->createDocument("linebot","messages",$user_document);

// ユーザーの発言をOpen JTalkで読み上げる
exec("sudo /usr/local/bin/line_talk ".$text);

// ユーザーに対して返信をする
$url = "https://trialbot-api.line.me/v1/events";

$headers = array(
    "Content-Type: application/json",
    "X-LINE-ChannelID: {$channel_id}",
    "X-LINE-ChannelSecret: {$channel_secret}",
    "X-LINE-Trusted-User-With-ACL: {$mid}"
);
// 下記の中からランダムで発言する
$contents = array(
"今日はいい天気ですね",
"おなか空いたよ",
"ごきげんはいかがですか?",
"眠いよ",
"おはようございます",
"こんばんは"
);

$content_key = array_rand($contents);

$content = $contents[$content_key];

// BOTの発言内容のJSONを作成する
$post = <<< EOM
{
    "to":["{$from}"],
    "toChannel":1383378250,
    "eventType":138311608800106203,
    "content":{
    "toType":1,
    "contentType":1,
    "text":"{$content}"
    }
}
EOM;

// LINEのRestAPIを実行して実際に発言する
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($curl);

$posted_json_object = json_decode($post);
$returned_json_object = json_decode($output);

$posted_json_object->id = $returned_json_object->messageId;
$posted_json_object->timestamp = $returned_json_object->timestamp;
$posted_json_object->sender = 'bot';

$bot_document = json_encode($posted_json_object);

// BOTの発言をDocumentDBに保存する
$documentdb->createDocument("linebot","messages",$bot_document);

// BOTの発言をOpen JTalkによって読み上げる
exec("sudo /usr/local/bin/line_talk ".$content);
?>

上記のコード中に「phpdocumentdb.php」を読み込んでいる部分があります。これは、Azure DocumentDBを操作するRest APIのラッパークラスです。以下で公開しております。作成していただいた方に感謝です!!

https://github.com/cocteau666/AzureDocumentDB-PHP

ただしこれはこのままでは使用できません。ドキュメントの作成に失敗してしまいます。おそらく当時とAPIの仕様が変わったのだと思います。以下の変更を加えて下さい。

576c576,577
< $headers = $this->getAuthHeaders('POST', 'docs', $rid_col);
---
> // $headers = $this->getAuthHeaders('POST', 'docs', $rid_col);
> $headers = $this->getAuthHeaders('POST', 'docs', 'dbs/'.$rid_id.'/colls/'.$rid_col);

また、上記のソースコード中に

exec("sudo /usr/local/bin/line_talk ".$content);

の記述があります。こちらは、内部的には以下のようになっており、LINEのタイムラインで発言された内容をOpen JTalkに渡しているShellを呼び出しています。

#!/bin/bash

echo $1 | /usr/local/open_jtalk/bin/open_jtalk -m /usr/local/hts_engine_API/hts_voice/mei_normal.htsvoice -ow /tmp/output.wav -x /usr/local/open_jtalk/open_jtalk_dic_utf_8-1.09

aplay /tmp/output.wav

次は、LINEからコールされるコールバックURLの呼び出し先を置くWebアプリケーション基盤を作成します。これはAzure App Serviceで実現します。

Azureポータルから「参照」→「App Service」の順にクリックします。

1

「追加」をクリックします。

2

「アプリ名」に任意の名前を入力し、「サブスクリプション名」や「リソースグループ」は環境に応じて必要なものを入力して、最後に「作成」をクリックします。

3

先ほど作成したアプリが一覧に表示されていることを確認します。

4

先ほど一覧に表示されていたアプリ名の右端に黒い点が3つ並んだアイコンがあります。それをクリックして「ツール」をクリックします。

5

「Visual Studio Online (プレビュー)」をクリックします。

6

「オン」をクリックします。

7

「移動」をクリックします。Visual Studio Onlineが起動します。

8

 

起動したVisual Studio Online上で以下のソースコードを作成して下さい。ファイル名はindex.phpとして下さい。

<?php
// DocumentDB操作用Classをincludeする
require_once 'D:homesitewwwrootphpdocumentdb.php';

// DocumentDBのホスト名
$host = 'https://hostname.documents.azure.com:443/';

// DocumentDBのマスターキー
$master_key = 'masterey';

// DocumentDBに接続する
$documentdb = new DocumentDB($host, $master_key,$debug = false);

// データベースを選択する
$db = $documentdb->selectDB("linebot");

// コレクションを選択する
$col = $db->selectCollection("messages");

// クエリを実行する
$user_json = $col->query("SELECT 'you' as sender,user.result[0].content.text as message, user.result[0].content.createdTime as time FROM c user where user.sender = 'user'");
$bot_json = $col->query("SELECT 'bot' as sender,bot.content.text as message, bot.timestamp as time FROM bot where bot.sender = 'bot'");

$user_json_object = json_decode($user_json); // ユーザーが発言した発言のJSONObject
$bot_json_object = json_decode($bot_json); // BOTが発言した発言のJSONObject

// ユーザーとBOTの発言をマージする
$messages = array_merge($user_json_object->Documents,$bot_json_object->Documents);

// 発言日付でソートする
foreach ($messages as $key => $value) {
$key_id[$key] = $value->time;
}

array_multisort( $key_id , SORT_ASC , $messages);

// 発言を表示する
echo "<table border=1>";
echo "<tr>";
echo "<td>送信者</td><td>発言内容</td><td>発言日付</td>";
echo "</tr>";
for ($i=0;$i < count($messages);$i++) {
echo "<tr>";
echo "<td>".$messages[$i]->sender."</td><td>".$messages[$i]->message."</td><td>".date("Y年m月d日 H時i分s秒", $messages[$i]->time/1000)."</td>";
echo "</tr>";
}
echo "</table>";
?>

ここでも同様にphpdocumentdb.phpを呼び出しています。このphpファイルも同様に、Visual Studio Online上に配置して下さい。実は、このままではこのソースは動作しません。Azure Remote App上からcurlでhttps通信を行う場合、通信先の証明書発行元の認証局のルート証明書が必要になります。しかし、今回はそのようなことはせずに、SSL通信の証明書のチェックを無効にすることで回避します。ただ、こちら、本番環境ではこのようなことはやらないでください。

phpdocumentdb.phpを以下のように修正して下さい。

159a160
> curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

これで準備は整いました。では、早速動作確認してみましょう。

先ほど登録申請したBOTアカウントに話しかけてみます。すると、応答が返ってきます。こちら、先ほどRaspberryPi上に作成したスクリプトが応答をして、メッセージを返しています。

IMG_1815

そして、写真だけではわかりにくいのですが、Rapbberry Piにつながったスピーカーから、BOTとのやりとりが音声で流れてます。

IMG_1810

そして先ほどAzure App Service上に作成したWebアプリケーションを起動してみましょう。

スクリーンショット_2016-05-25_06-56-11

BOTとのやりとりが一覧で表示されいます。こちらは、Raspberry Piから登録されたDocumentDB内のJSONデータを表示しています。

いかがでしたでしょうか?なんとなく面白そうなサービスをくっつけただけで実用性は皆無ですが、Azureで色々なことができるんだなと実感頂けましたら幸いです。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。
SHARE
  • ポスト
  • シェア
  • はてブ
  • LINE

CATEGORY :

  • Azure
  • クラウド
  • takei

TAGS :

  • Raspberry Pi
  • Azure App Service
  • Visual Studio Online
  • Open JTalk
  • LINE
  • BOT
  • Azure DocumentDB
  • BOT API Trial Account
  • Rest API
  • Azure Remote App
  • Azure AD Connectの同期処理時にExchange関連の属性が同期されない

    Azure AD Connectの同期処理時にExchange関連の属性が同期されない

  • Web App for ContainersでコンテナにSSHする

    Web App for ContainersでコンテナにSSHする

  • Microsoft Ignite 2019レポート 〜 【その他】Developer Feedback 〜

    Microsoft Ignite 2019レポート 〜 【その他】Developer Feedback 〜

  • OSS on Azure非公式コミュニティ ロゴ

    OSS on Azure非公式コミュニティ ロゴ

  • Pluggableな非同期処理

    Pluggableな非同期処理

  • KubernetesでApp Serviceを動かす!!

    KubernetesでApp Serviceを動かす!!

この記事を書いた人
アバター画像
武井 宜行

Microsoft MVP for Azure🌟「最新の技術を楽しくわかりやすく」をモットーにブログtech-lab.sios.jp)で情報を発信🎤得意分野はAzureによるクラウドネイティブな開発(Javaなど)💻「世界一わかりみの深いクラウドネイティブ on Azure」の動画を配信中📹 https://t.co/OMaJYb3pRN

X YouTube

コメントを残す コメントをキャンセル

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

前の記事

Azureに仮想マシン(CentOS)を構築する

次の記事

【第3回】 Linux/OSS エヴァンジェリスト古賀政純の …
  • OSS
  • 認証
  • クラウド
  • コンテナ
  • 生成AI
  • トレンド
    • Web3
    • IoT
    • SBOM
  • その他
    • フロントエンド
    • バックエンド
    • データーベース
    • ミドルウェア
    • os
    • 監視
    • API
  • シリーズ
    • 世界一わかりみ深いシリーズ
    • 便利なコマンドシリーズ

Contact

  • About
  • ブラウザで購読する
  • 執筆依頼
  • カジュアル面談
  • お問い合わせ
  • エントリー
  • X
  • Facebook
  • YouTube
HOME
  • サイオステクノロジー株式会社

© 2025 SIOS Tech. Lab All rights reserved.