ユーザーローカルの人工知能APIをLINE BOTに組み込んでみた

f:id:yamamotomanabu:20160616004522p:plain

先日、ユーザーローカル社が人工知能APIの公開を発表しました。
発表当日に無料版の申し込みをしておいたところ、先程メールでAPIキーが届いたので早速試してみました。

先日試したLINE BOT APIにこの人口知能APIを組み込んでみようと思います。

構成は前回同様なので、LINE BOT APIやWebsocket.ioについてはこちらの記事を参照してください。 http://yamamotomanabu.hatenablog.com/entry/2016/04/08/webscript.io%E3%81%A7LINE_BOT_API%E3%81%AE%E4%BA%8B%E5%A7%8B%E3%82%81

という訳で、いきなりスクリプトです。

-- LINEの認証情報
ChannelID = あなたのChannel ID
ChannelSecret = あなたのChannel Secret
MID = あなたのMID

-- 人工知能ボットAPIの認証情報
key = あなたのAPIキー

-- 受信メッセージを取得
body = json.parse(request.body)
message = body.result[1].content.text

-- 人工知能ボットAPIを呼び出す
local response = http.request {
    -- まだAPIの内容が一般公開されていないようなのでコメント化します
    -- API公開後に修正します
}
res = json.parse(response.content)
text = res.result

reply = body.result[1].content.from
data = {
    ['to'] = {reply},
    ['toChannel'] = '1383378250', -- 固定値
    ['eventType'] = '138311608800106203', -- 固定値
    ['content'] = {
        ['contentType'] = 1,
        ['toType'] = 1,
        ['text'] = text
    }
}

-- メッセージ送信
local response = http.request {
    url = 'https://trialbot-api.line.me/v1/events',
    method = 'POST',
    data = json.stringify(data),
    headers = {
        ['Content-Type'] = 'application/json; charser=UTF-8',
        ['X-Line-ChannelID'] = ChannelID,
        ['X-Line-ChannelSecret'] = ChannelSecret,
        ['X-Line-Trusted-User-With-ACL'] = MID
    }
}

return true

「LINEの認証情報」と「人工知能ボットAPIの認証情報」の計4行はご自身の情報に置き換えてください。

これだけでLINE BOTをAI化することができます。
f:id:yamamotomanabu:20160616011634p:plain

と言ったものの、精度はMicrosoftさんのりんなと比較するとまだまだといった印象です。
ただ組み込みの簡単さは素晴らしく、こういう人工知能チャットBOTがサーバレスで一時間もかからず構築できてしまうことには非常に驚きを感じました。

さて、こちらの人口知能APIですが、まだ完全公開ではなく、開発者の第二期募集中とのことなので(6/15時点)、API仕様もまだ公開されていないので、スクリプトも肝心の部分はマスクしておきました。
APIキー発行のメールにはAPIドキュメントのリンクが記載されていて、「APIを試したらブログやQiitaに記事を書いてね!」とあるので、マスクしなくても良い気もするのですが念のため。 公式サイトにもAPIドキュメントのリンクを貼ってくれればいいのに。。。

webscript.ioでLINE BOT APIの事始め

f:id:yamamotomanabu:20160408005017p:plain

2016/12/26追記 ---
この記事で取り扱っているBOT APIは、Messaging APIの公開に伴い、開発者アカウントの削除、API仕様の変更が行われています。

webscript.ioを使ったMessaging API連携というところでは、id:JUNKI_fuglyさんが記事を書かれていますのでこちらが参考になると思います!
qiita.com --- ここまで

BOT API Trial Accountの受付が開始されたので、早速試してみました。
APIの仕様はこちらをご覧ください。

今回はいくつかあるAPIの中から、ユーザーからのメッセージを受け取るReceiving messagesと、ユーザーにメッセージを送るSending messagesを使って、メッセージを受け取ったら、そのメッセージの末尾に"やで"を付けてオウム返しするBOTを作ってみようと思います。

Sending messagesはBOT製作者にしか分からないアプリケーション情報や、送信先のユーザー情報、メッセージをHTTPヘッダやボディに乗せてPOSTで送る分かりやすいAPIなのですが、Receiving messagesはWebhook方式になっていて、LINE developersと呼ばれるBOT製作者向けの管理画面上でメッセージ受信時のコールバックURLを設定する仕組みになっています。
このコールバックURLには制約事項があって、HTTPSでなければならず、更にオレオレ証明証はNGのようなので注意が必要です。
制約事項についてはこちらに記載があるのでチェックしてください。

Once registered, requests will be sent to your callback URL. The callback URL must use HTTPS.

Note: The SSL certificate must be issued by an authorized CA. If a self-issued SSL certificate is applied to your server, requests sent from the LINE platform will fail.

最初、手持ちのIDCF Cloudの仮想マシンを使おうと思ったのですが、証明書を準備するのが億劫だったので、webscript.ioを使ってみようと思います。
webscript.io自体の使い方はChatWorkさんのブログで詳しく解説されているので、そちらをご覧ください。
サーバー不要で Lua 言語な webscript.io で ChatWork API を叩いてみる

早速スクリプトを作成しましょう。
f:id:yamamotomanabu:20160408013951p:plain

スクリプトの内容はこれだけです。

-- 認証情報
ChannelID = あなたのChannel ID
ChannelSecret = あなたのChannel Secret
MID = あなたのMID

-- 受信メッセージから送信メッセージを構築
body = json.parse(request.body)
res = body.result[1].content.text .. 'やで'
reply = body.result[1].content.from
data = {
    ['to'] = {reply},
    ['toChannel'] = '1383378250', -- 固定値
    ['eventType'] = '138311608800106203', -- 固定値
    ['content'] = {
        ['contentType'] = 1,
        ['toType'] = 1,
        ['text'] = res
    }
}

-- メッセージ送信
local response = http.request {
    url = 'https://trialbot-api.line.me/v1/events',
    method = 'POST',
    data = json.stringify(data),
    headers = {
        ['Content-Type'] = 'application/json; charser=UTF-8',
        ['X-Line-ChannelID'] = ChannelID,
        ['X-Line-ChannelSecret'] = ChannelSecret,
        ['X-Line-Trusted-User-With-ACL'] = MID
    }
}

return true

先頭の認証情報の3行はご自身のアプリケーション情報に置き換えてください。必要な情報はLINE developersのBasic informationで確認することができます。 f:id:yamamotomanabu:20160408021504p:plain

続いて同じLINE developersのBasic informationでコールバックURLを設定します。 f:id:yamamotomanabu:20160408022609p:plain

ポート番号を明示的に指定する必要があるので、
https//指定したサブドメイン名.webscript.io:443/指定したディレクトリ名
のような形式で設定してください。

最後にLINE developersのServer IP Whitelistを設定します。 Sending messagesを実行するホストのIPアドレスホワイトリスト方式で列挙する必要があります。 f:id:yamamotomanabu:20160408023102p:plain

webscript.ioの接続元IPである54.159.34.187を設定してください。(私の環境では54.159.34.187だけで問題なく動作しているのですが、もしかしたレンジ指定する必要があるかもしれません。。)

コールバックURLやホワイトリストの設定が反映されるのに丸一日近く掛かったという報告が挙がっています。自分が作業行った際は特に待ち時間なかったのですが、人が増えて負荷が上がったんですかね・・・。設定後は気長に待ちましょう。(2016/4/11追記)

LINE developersのBasic informationにあるQRコードなどを使って、BOTを友だち追加してメッセージを送ってみてください。
f:id:yamamotomanabu:20160408024124p:plain

これでオウム返しBOTが完成です。
f:id:yamamotomanabu:20160408024154j:plain

IFTTTのMakerチャンネルから発行されるHTTPリクエストのヘッダーを確認してみた

f:id:yamamotomanabu:20151031165736p:plain

IFTTTのMakerチャンネルには、さまざまなWebサービスの「状態」を契機にして、任意のHTTPリクエストを実行することができる「Make a web request」というアクションがあります。これを利用すると、Webhookに対応していないWebサービスでもIFTTTのトリガーとして「状態」をフックすることができれば、擬似的にWebhook化することができます。
Maker Channel

前述のとおりとても便利な機能なのですが、ただ一つだけ気になる点があって、ボディの内容は自由にカスタマイズできるのですが、ヘッダーは「Content-Type」以外カスタマイズできないことでした。認証系の情報をヘッダーに付与するシーンはよくあると思うので、それができないのは人によっては少し不便ですね。
f:id:yamamotomanabu:20151031165049p:plain

じゃあカスタマイズできないとして、そもそもどんなヘッダーが付与されるのかを調べたのですが、ドキュメントが見当たらなかったので、実際に調べてみました。
これだけのためにWebサーバを立ち上げるのは手間だったので、今回はwebscript.ioというサービスを利用してみます。webscript.ioはURLを指定して、そのURLにアクセスされたらどう動作するかをブラウザ上でプログラミングできるサービスです。詳しくは公式サイトかChatWorkさんのブログが詳しかったので、そちらをご覧くださいな。
webscript.io
サーバー不要で Lua 言語な webscript.io で ChatWork API を叩いてみる

webscript.ioで設定するスクリプトはたった一行だけです。

return;

「Make a web request」の設定は以下のようにしました。 トリガーはDate & Timeチャンネルの「Every hour at」を使いました。
f:id:yamamotomanabu:20151031165103p:plain

IFTTTのレシピが実行されると、webscript.ioにアクセスログが残るので、そちらでヘッダーを確認することができます。
f:id:yamamotomanabu:20151031170523p:plain

という訳で、IFTTTが付与するヘッダーは以下のとおりでした。

Content-Length
X-Newrelic-Id
X-Forwarded-Port
X-Forwarded-For
Host
X-Newrelic-Transaction
Connection
X-Forwarded-Proto
Content-Type

ちなみに、、、IFTTT単体でヘッダーのカスタマイズはできないものの、今回使ったwebscript.ioをクッションとして活用すれば任意のヘッダーを追加することが可能なので、もしヘッダー周りをカスタマイズしたケースがあればwebscript.ioは選択肢として検討してみては如何でしょうか!

Mac版VisualStadioCodeのIntelliSenseのショートカットキーを変更する

Visual Stadio Codeの提供が開始されたのでインストールしてみました。
Visual Stadio Code

f:id:yamamotomanabu:20150501001351p:plain

公式サイトを確認したところIntelliSenseのショートカットキーはCtrl+Space。。。お決まりのショートカットキーではあるのですが、お決まりのようにSpotlightと競合してしまうので、これを変更したいと思います。

メニューから「Code→Preference→Keyboard Shortcuts」を選択。すると、以下のようにDefault Keyboard Shortcutsとkeybindings.jsonが表示されます。

f:id:yamamotomanabu:20150501002824p:plain

keybindings.jsonの内容を以下のように編集することで、IntelliSenseのショートカットキーを変更することができます。(今回はCmd+Spaceに変更しました)

// Place your key bindings in this file to overwrite the defaults
[
  {
    "key": "cmd+space",
    "command": "editor.action.triggerSuggest",
    "when": "editorTextFocus"
  }
]

db tech showcase OSAKA:2014に参加しました

db tech showcase OSAKA:2014に参加しました。
db tech showcase OSAKA:2014

f:id:yamamotomanabu:20140618153030j:plain

夕方から参加して、玉川竜司氏の「RDB技術者におくるMongoDBの勘所」と、まつもとゆきひろ氏の「1人のエンジニアが世界を変えられる」を拝聴しました。

RDB技術者におくるMongoDBの勘所 - 玉川竜司氏

実は未だに触っておらず危機感感じてたところだったので、これは!?と思い聴講させて頂きました。

MongoDBのいいところは「お手軽さ」
例えるなら多目的の高性能「オートマ車
インストールが簡単ですぐにそこそこ使える。

という紹介がありました。
普段LLな言語ばかり使用しているので、相性良さそうだなーという第一印象。

また、スキーマ構造をグイグイ変更していけるというのは、プロトタイピング時には非常にありがたいなと思いました。

そもそも今までRDBの経験しかないので、スキーマ設計の勘所を掴むまでがポイントなのかなーと感じています。

1人のエンジニアが世界を変えられる - まつもとゆきひろ

要約すると、

「成功した」という結果と「失敗しなかった」という結果はイコールではない。

失敗できない状況は成功の芽を潰す。

現実問題としてプロでも失敗するし、未来が予知できない以上、成功するには失敗は許容していくしか無い。

そのためにはまず「失敗できないこと」をしない。後に引けなくなるような高コストなことをしない。

「下手な鉄砲も数撃ちゃあたる」「繰り返すことで確率を上げる」を実践するには低コストであることが絶対条件になる。

IT(特にWeb)はすさまじい速度で低コスト化している、ITはそういう意味で低コストで大成功を目指せる領域だ。

ここまで話せば分かりましたよね?プログラマの皆さんはチャンスです。後は行動するだけです。

というとても熱いメッセージを頂きました。 特に失敗を許容するというフレーズがスライド内に出てきたのですが、これは今所属しているチームでも標榜しているコアフレーズです。

まとめ

量は質に転化する
とにかく打席数を増やして、見送り三振せず、空振り三振上等の精神でバットを振りきっていこうと思います。

Windows Azure Webサイト 今度はLaravelをデプロイしてみる

先日セミナーでWindows Azure Webサイトについて知り、無料枠もあるということで、FuelPHPのデプロイを題材にどんなものかと試してみました。

初めてのWindows Azure Webサイト FuelPHPをデプロイしてみる

結果としてあっさりデプロイできてしまったので、次はHello World!も兼ねて話題のLaravelをデプロイしてみようと思います。

Azure

サインアップは先日のブログの通り完了しているので、コンパネから新しいWebサイトを作成します。

Laravel事始め

今回はLaravelが初めましてなので、Laravelの導入から始めます。

こちらのサイトを参考にさせて頂きました。
Laravelクイックスタート

まずはクイックスタート通り、LaravelインストーラーPHARアーカイブをダウンロード。
LaravelインストーラーPHARアーカイブ

# helloプロジェクトを作成
$ chmod 744 ./laravel.phar
$ ./laravel.phar new hello

あっさり空プロジェクトが出来上がり。さて、ディレクトリ構造すらよく分かっていないのですが、クイックスタートを読み進めるとルーティングはapp/routes.phpで行っているらしい。

$ view 744 ./hello/app/routes.php

Route::get('/', function()
{
        return View::make('hello');
});

View::make('hello')…。app/views/hello.phpにルーティングされる雰囲気をひしひしと感じつつも、何はともあれ真っ白じゃないページが表示されそうなので、FuelPHPのときと同じようにアップロードしてみる。

  1. site\wwwrootにhelloディレクトリをアップロード。
  2. ドキュメントルートをsite\wwwroot\laravel\publicに変更。

Azure Webサイトにアクセスしてみる。

f:id:yamamotomanabu:20140217225709p:plain

なんか表示された!

まとめ

FuelPHPに引き続き、Laravelもあっさりとデプロイできました。ただこちらもデータベースとの連携を試していないので、いずれまた。

Laravelに対する印象は、上で書いたView::make('hello')が想像通りapp/views/hello.phpにルーティングされていたこともあって、想像通りの挙動をしてくれそうなフレームワークといった感じ。まだ空プロジェクトをそのまま動かしただけですが…。という訳で、じゃあ本当に想像通り動いてくれるのかこれから色々試してみたいと思います。

初めてのWindows Azure Webサイト FuelPHPをデプロイしてみる

Innovation EGGに参加しました。
Innovation EGG 第二回 XEgg 1st『クラウド未経験者向けITコミュニティ&クラウドベンダー合同勉強会』2月15日(土)

午前中のみの予定だったので、Ride on Azure!というAzure三本立てセッションを拝聴しました。
Ride on Azure! ~概要編~
Ride on Azure! ~詳細編~
Ride on Azure! ~アイデアソン編~

セッションの中で一番興味を持ったのがWindows Azure Webサイト
AzureはAWS的な汎用タイプのPaaSだと勝手に思い込んでいたのですが、Heroku的なホスティングもできるということで、俄然興味が湧いてきました。

色々グッズも頂戴したので、実際に試してみたいと思います。

f:id:yamamotomanabu:20140215174637p:plain

Azure事始め

まずはAzureのサインアップから。特につまずくところはなし。住所入力欄が欧米的な下から上なのに後から気づいて舌打ちをしたぐらい。
サインアップ

コンパネはこんな感じ

f:id:yamamotomanabu:20140215164106p:plain

環境も整ったので、お目当てのWindows Azure Webサイトを作成します。
左メニューのWEBサイトを選択して、WEBサイトの作成、ギャラリーから、と覗いていくとCakePHP発見。

f:id:yamamotomanabu:20140215164755p:plain

PHPフレームワークCakePHPぐらいの模様で、PHP関連だとPHP Empty StyleだとかPHP Starter Kitというプリセットもありましたが、それらは利用せず簡易作成から始めます。

f:id:yamamotomanabu:20140215165356p:plain

できた!

f:id:yamamotomanabu:20140215165611p:plain

発行されたURLにアクセスしてみる

f:id:yamamotomanabu:20140215170046p:plain

FuelPHPをデプロイする

環境ができたので、今回はさっくりFTPFuelPHP(v1.7.1)をデプロイしたいと思います。
FTP周りの設定はどこかなと探してみると、作成したWebサイトのダッシュボードの右カラム。デプロイ/FTPユーザーが未設定となっているので、デプロイ資格情報を設定するからユーザー名とパスワードを設定します。

手持ちのFTPクライアントからあっさり接続できました。

f:id:yamamotomanabu:20140215171110p:plain

作成したWebサイトの構成からドキュメントルートを確認すると、デフォルトはsite\wwwrootとなっています。
という訳で、

  1. site\wwwrootに公式サイトからダウンロードしzip解凍しただけのfuelphp-1.7.1をアップロード。
  2. ドキュメントルートをsite\wwwroot\fuelphp-1.7.1\publicに変更。

再度、発行されたURLにアクセスしてみる。

f:id:yamamotomanabu:20140215172506p:plain

まとめ

実にあっさりとデプロイできました。とはいえVCSやデータベースとの連携を試していないので、それらはこれから試してみたいと思います。

このブログを書いている最中に気付いたのですが、とっくに先駆者の方々がVCS、データベース連携の上でFuelPHPを動かしてくれていたので、このブログを読んだ方は続けてこちらも読むとハッピーになれる気がします。

Azure_Web_siteFuelPHPを動かしてmigration_までやってみた

Azure Web サイトで FuelPHP を動かす(改定)