Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
とても
腹立たしいことが
あったのです。
プロローグ
Prologue
ある日。
とても腹立たしい
事件が起きた。
誰かに話して
共有したい。
SNS
でも誰かを巻き込んで
負の感情を連鎖
させるのはよくない。
LINE Bot 相手だったら
いいんじゃね?
ライトニングトーク - とある LINE Bot の開発記「とても腹立たしいことがあったのです」
ライトニングトーク - とある LINE Bot の開発記「とても腹立たしいことがあったのです」
ライトニングトーク - とある LINE Bot の開発記「とても腹立たしいことがあったのです」
よけいムカついた
まてまて。
前回のこの勉強会で、
LINE Bot 作るスキル
習得したじゃん!
ライトニングトーク - とある LINE Bot の開発記「とても腹立たしいことがあったのです」
ライトニングトーク - とある LINE Bot の開発記「とても腹立たしいことがあったのです」
いくらBotとはいえ、
こんな娘に乱暴な言葉
ぶつけるのは忍びない…
キャラ変えました。
○TAR ○ARS の DR○ID
ならいいだろw
ライトニングトーク - とある LINE Bot の開発記「とても腹立たしいことがあったのです」
メイキング
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, reje
aiRequest.on('response', response => resolve(respo
aiRequest.end();
});
// 意図は「お薦めの食事」だと特定。お薦めの食事を回答します。
if (aiResponse.result.action == 'recommendation') {
dietitian.dietitian.replyRecommendation(event.repl
return; // ここで処理は終了
}
// 意図が特定されなかった場合は
// 食事の報告だと仮定して形態素解析処理へ移る。
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

More Related Content

ライトニングトーク - とある LINE Bot の開発記「とても腹立たしいことがあったのです」

  • 5. SNS
  • 18. ○TAR ○ARS の DR○ID ならいいだろw
  • 23. function foo() { fizz() .then(res1 => { buzz(res1); }) .then(res2 => { fizzBuzz(res2); }) }
  • 24. function async foo() { fizz() .then(res1 => { buzz(res1); }) .then(res2 => { fizzBuzz(res2); }) }
  • 25. function async foo() { let res1 = await fizz(); .then(res1 => { buzz(res1); }) .then(res2 => { fizzBuzz(res2); }) }
  • 26. function async foo() { let res1 = await fizz(); buzz(res1) .then(res2 => { fizzBuzz(res2); }) }
  • 27. function async foo() { let res1 = await fizz(); let res2 = await buzz(res1); .then(res2 => { fizzBuzz(res2); }) }
  • 28. function async foo() { let res1 = await fizz(); let res2 = await buzz(res1); fizzBuzz(res2); }
  • 29. 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 => { // ...ここに巨大なアロー関数の本体... })
  • 30. 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, reje aiRequest.on('response', response => resolve(respo aiRequest.end(); }); // 意図は「お薦めの食事」だと特定。お薦めの食事を回答します。 if (aiResponse.result.action == 'recommendation') { dietitian.dietitian.replyRecommendation(event.repl return; // ここで処理は終了 } // 意図が特定されなかった場合は // 食事の報告だと仮定して形態素解析処理へ移る。 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); ...
  • 33. 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のコーディング支援を得られます。
  • 34. Happy Coding :) Learn, Practice, Share.
  • 35. 追補 • 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