ライトニングトーク - とある line bot...
TRANSCRIPT
とても腹立たしいことがあったのです。
プロローグPrologue
ある日。
とても腹立たしい事件が起きた。
誰かに話して共有したい。
SNS
でも誰かを巻き込んで負の感情を連鎖
させるのはよくない。
LINE Bot相手だったらいいんじゃね?
よけいムカついた
まてまて。
前回のこの勉強会で、LINE Bot作るスキル習得したじゃん!
いくらBotとはいえ、こんな娘に乱暴な言葉ぶつけるのは忍びない…
キャラ変えました。
○TAR ○ARS の DR○IDならいいだろw
メイキングMaking
TypeScript v.2.1+
async / await
function foo() {fizz().then(res1 => {
buzz(res1);})
.then(res2 => {fizzBuzz(res2);
}) }
function async foo() {fizz().then(res1 => {
buzz(res1);})
.then(res2 => {fizzBuzz(res2);
}) }
function async foo() {let res1 = await fizz();.then(res1 => {
buzz(res1);})
.then(res2 => {fizzBuzz(res2);
}) }
function async foo() {let res1 = await fizz();
buzz(res1).then(res2 => {
fizzBuzz(res2);})
}
function async foo() {let res1 = await fizz();
let res2 = await buzz(res1);.then(res2 => {
fizzBuzz(res2);})
}
function async foo() {let res1 = await fizz();
let res2 = await buzz(res1);
fizzBuzz(res2);}
app.post('/webhook', (req, res) => {...let gotIntent = new Promise((resolve, reject) => {
aiRequest.on('response', response => resolve(response));aiRequest.end();
}) as any;
let main = gotIntent.then(aiResponse => {
// 意図は「お薦めの食事」だと特定。お薦めの食事を回答します。if (aiResponse.result.action == 'recommendation') {
dietitian.dietitian.replyRecommendation(event.replyToken);main.Cancel();// ここで処理は終了
}else {
// 意図が特定されなかった場合は// 食事の報告だと仮定して形態素解析処理へ移る。return mecab.parse(event.message.text);
}}).then(res => {
let gotAllNutrition = res.filter(r => r[1] == '名詞').map(r => foodsDb.getNutrition(r[0]));
return Promise.all(gotAllNutrition);}).then(responseList => {
// ...ここに巨大なアロー関数の本体...})
app.post('/webhook', (req, res) => {...let gotIntent = new Promise((resolve, reject) => {
aiRequest.on('response', response => resolve(response));aiRequest.end();
}) as any;
let main = gotIntent.then(aiResponse => {
// 意図は「お薦めの食事」だと特定。お薦めの食事を回答します。if (aiResponse.result.action == 'recommendation') {
dietitian.dietitian.replyRecommendation(event.replyToken);main.Cancel();// ここで処理は終了
}else {
// 意図が特定されなかった場合は// 食事の報告だと仮定して形態素解析処理へ移る。return mecab.parse(event.message.text);
}}).then(res => {
let gotAllNutrition = res.filter(r => r[1] == '名詞').map(r => foodsDb.getNutrition(r[0]));
return Promise.all(gotAllNutrition);}).then(responseList => {
// ...ここに巨大なアロー関数の本体...})
app.post('/webhook', async (req, res) => {...let aiResponse: any = await new Promise((resolve, reject)
aiRequest.on('response', response => resolve(response));aiRequest.end();
});
// 意図は「お薦めの食事」だと特定。お薦めの食事を回答します。if (aiResponse.result.action == 'recommendation') {
dietitian.dietitian.replyRecommendation(event.replyTokenreturn; // ここで処理は終了
}
// 意図が特定されなかった場合は// 食事の報告だと仮定して形態素解析処理へ移る。let res = await mecab.parse(event.message.text);
let gotAllNutrition = res.filter(r => r[1] == '名詞').map(r => foodsDb.getNutrition(r[0]));
let responseList = await Promise.all(gotAllNutrition);...
非同期呼び出しの連鎖中でもreturnで処理打ち切れる
Bluebird 要らんかったんやw
まとめConclusion
TypeScript マジお薦め
•async/await ※1神機能。
• さらに Visual Studio Codeなら、Out-of-Boxでコーディ
ング支援からデバッグ実行までできて超快適。
※1 ... 実際には async/await は TypeScript の専売特許などではなく、次期 JavaScript(ECMAScript) で
採用予定の機能・構文となっており、Babel などの他のトランスパイラでも利用できます。
※2 ... もちろん Visual Studio Code に限らず、Atom や Sublime Text 等々、主だったテキストエディ
タや IDE上でTypeScriptのコーディング支援を得られます。
Happy Coding :)Learn, Practice, Share.
追補• AIが入ったBotの作り方を学ぼう
• Part1 概要と開発環境のセットアップhttp://qiita.com/nkjm/items/0e9d24b2f3429bd33c8d
• Part2 LINEでビジネスアカウントを作成するhttp://qiita.com/nkjm/items/daa4e34b26ef937446c6
• Part3 Bot本体のプログラムを開発するhttp://qiita.com/nkjm/items/27d0131003a4b7ef02b9
• Part4 形態素解析と食品データベースで食品とその栄養価を特定するhttp://qiita.com/nkjm/items/d46bd91e1784adf1434b
• Part5 自然言語解析でメッセージの意図を解釈しBotのスキルを高めるhttp://qiita.com/nkjm/items/fe2db6b8c4ee2980e2b4
• 「Oracle Cloud Developers Meetup@北海道 - AIが入ったBotの作り方を学ぼう」に VSCodeと TypeScript で取り組んだ話http://qiita.com/jsakamoto/items/3f19cac806dc44c3dd50