• Like
モテる! Node.js でつくる twitter ボット制作
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

モテる! Node.js でつくる twitter ボット制作

  • 6,191 views
Published

Node.js の環境構築から、一本進んだ Twitter のボット制作までを紹介します。

Node.js の環境構築から、一本進んだ Twitter のボット制作までを紹介します。

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
6,191
On SlideShare
0
From Embeds
0
Number of Embeds
5

Actions

Shares
Downloads
27
Comments
0
Likes
18

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. モテる! Node.js でつくる Twitter ボット制作 X Presented by @hecomi
  • 2. introductionはじめに
  • 3.                  / ̄ ̄ ̄ ̄ ̄ ̄\ 
           /             \ 
                  _______ 
           /     /           \| 
           .′ j/  ,. -―――‐- .,   〉 
        /   j|:..//-∠、. . . . . /--. \{ 
         〈_/上|. / o  \/∨ o V/庁=、 
          \ |/ ┌──── ┐ ∨ソ/ 
    ___________
            )、_;,. !         | ;_/    
  /                 \
              ⌒ 介:. 、 ____,,ノイ{     <  のぉどじぇーえすって     | 
               ⌒7⌒\/\/\⌒ 
  |  なにするです?        |
               / .:::::::::::::::::::::::::::::::::::::::::::::.\                  ,′ V/, ○∨  ∧ 
  \___________/             /.::::::::::::::   ´ ̄ ̄ ̄ ̄` 、:::::.\               j__,V/○ j  ′〉 
              {___,ノ  人__ク 
            / .::::::::::::/   ____  \:::::::|                _,ノ\冖┘ へ. └冖 \_ 
         ___/ .:::::::::::::∨   / \. . . . /^\ \,′            {丈____\/-―-\/___丈}           \:::::::::::::::::::::::|  // ⌒ |/∨ ⌒ |\__〉           `  ――r┴‐| /  o      o│./┴┐  ___________
                     \⌒′ r――――┐ レ  /  /                 \
                         __                    >ヘ  |      │ ,< <  よくわからないので      |                 ,... -―――‐/ \ー- 、  __                    ^⌒T>乂__   ...ノ イ⌒^  |  おことわりするです      |
               ./: : : : : : : : : :/    \__/ .‘,             /: : ,---- ̄ ̄  ____    .‘,                     ∠ニ=干‐ 厂}‐r‐厂}  \___________/            /: : : : |    ., - ´   ,. -,l .\ ‘,__                        { . . . │ |=イ.│|=イ           /: : : : : : :.|   / ⌒     l____丿.⌒ヽ  /                 _,,..ノ\ . .│ | 八 |│/          /: : : : : : :/  ./               | ./                  /. . . . . . \_|_j,′.〉 ̄         /: : : : : :/   ./l    o     .__   o ∨                \ . . . . . . . . . . . (__)ヘ        ./: : : : : :‘,   ./.ヽ   ____|___|___ .|       .,: : : : : : : :‘, _ -ー´   |           | .|    ___________
         {\. . . . . . . . . . ∧. . 〉                             、::\___/::::}/       l: : : : : : : : /       .|           | |  /                 \
                  \::::::::::::::::::::,′:/       |: : : : : : : :\       ヽ          / ./ <  さーばさいどでじゃば     |       |: : : ._------|ー‐―-、 _  .\______//                   \::::::::::::/.::::,′       |: :/       ̄ ̄ヽ _>ー――――‐ ´  |  すくりぷとじっこうしたり?  |
                    {三三}ニニ}       |/            ̄/: :|__\ <> |ヽ  \___________/                   /: : : : : : └-\/.人                     {___┐┐                  .|: : : :/: : : : : : : : : : : :‘,                   \:/: : : : : : : : : :○: : :‘,                    /: : : : : : : : : : : : : : : :‘,                   〈: : : : : : : : : : : : : : : : : : |                    `ー-...._: : : : : : : /l: :_/                    .‘,: : :`ー---/ : ̄/                     ‘,: : : : : :./: : : /                      .‘,: : : : / : /                       l ̄ ̄〉 ̄〉                        ̄ ̄ ̄ ̄
  • 4. 本発表について•  となってる人が多いと思うので…•  実際に Node.js 環境を構築して、その上 で Twitter ボットを動かしてみます。 –  おうむ返しボット、特定のキーワードに反応 するボット、人工無能ボットから、一歩進ん で形態素解析ボットを紹介します。
  • 5. introductionのぉどじぇーえす?

  • 6. Node.js?•  http://nodejs.jp/•  サーバサイドで JavaScript を実行 –  エンジンは v8
  • 7. 何が出来るの?•  ブラウザの JavaScript で出来なそうな ことがサーバ上で出来ます
  • 8. 何が出来るの?•  ブラウザの JavaScript で出来なそうな ことがサーバ上で出来ます –  ファイル操作とか var fs = require(fs); fs.writeFile(log.txt, ‘Hello, world!, function(err) {    if (err) throw err;    console.log(Success!); });
  • 9. 何が出来るの?•  ブラウザの JavaScript で出来なそうな ことがサーバ上で出来ます –  http サーバ立てたりとか var http = require(http); http.createServer(function(req, res) {     res.writeHead( 200, {Content-Type: text/plain} );     res.write(Hello, world!n);     res.end(); }).listen(3000);
  • 10. 何が出来るの?•  ブラウザの JavaScript で出来なそうな ことがサーバ上で出来ます –  http サーバ立てたりとか var http = require(http); http.createServer(function(req, res) {     res.writeHead( 200, {Content-Type: text/plain} );     res.write(Hello, world!);     res.end(); }).listen(3000);
  • 11. installいんすとーる
  • 12. インストールしよう•  Windows 環境下(http://nodejs.org/) クリックしてインストールするだけ
  • 13. インストールしよう•  Mac / Linux 環境下 –  バージョン管理も含めて nave がオススメ •  https://github.com/isaacs/nave
  • 14. インストールしよう•  node.js と npm のインストール $ mkdir ~/.nave $ cd ~/.nave $ git clone git://github.com/isaacs/nave.git $ ~/.nave/nave/nave.sh use latest $ $ curl https://npmjs.org/install.sh | sh•  ちなみに結構コンパイル時間かかります•  参考 –  naveを使ったnode.jsインストールと、最近のnpmの使い方 - ラシウラ –  http://d.hatena.ne.jp/bellbind/20110530/1306764093
  • 15. インストールしよう•  インストールされたか確認 –  Windows の人はコマンドプロンプト上で $ node –v v0.8.9 $ npm –v V1.1.61•  これで OK!
  • 16. Hello, world!はろーわーるど
  • 17. 対話コンソール$ node> console.log(Hello, world!); // これを打つHello, world!undefined> (Ctrl+D 押下)$
  • 18. ファイル$ cat helloworld.jsconsole.log(Hello, world!);$ node helloworld.jsHello, world!
  • 19. おまけ:ブラウザ// helloworld.jsvar http = require(http);http.createServer(function(req, res) {     res.writeHead(200, {Content-Type: text/plain});     res.write(Hello, world!n);     res.end();}).listen(3000);$ node helloworld
  • 20. Make twitter bot!ついったーぼっとせいさく
  • 21. Consumer Key / Access Token1.  適当な Twitter アカウントを作成2.  Twitter の開発者サイトより 1.  Consumer Key / Consumer Secret 2.  Access Token / Access Token Secret を取得する※ 開発者サイト: https://dev.twitter.com/•  ※参考: –  twitterアクセストークンなどの取得方法(WordPress更新通知用) –  http://musilog.net/webdesign/my-works/twitter-oauth-wp-to-twitter.php
  • 22. Twitter モジュール導入•  npm でインストール $ mkdir twitter_bot $ cd twitter_bot $ npm install twitter npm http GET https://registry.npmjs.org/twitter npm http 200 https://registry.npmjs.org/twitter npm http GET https://registry.npmjs.org/twitter/-/ twitter-0.1.18.tgz npm http 200 https://registry.npmjs.org/twitter/-/ twitter-0.1.18.tgz …(ry•  依存関係も含めて必要なモジュールをイ ンストールしてくれます
  • 23. npm•  npm は node package manager の略•  package 数は 15006 個!(2012/09/22 現在)•  使い方 –  npm install hoge •  実行したディレクトリ下に node_modules ディレ クトリを作成してそこにモジュールを展開 •  実行したディレクトリ下のみで使用できる –  npm install -g hoge •  どのディレクトリからでも使える
  • 24. Twitter で はろーわーるど•  早速使ってみましょう! var twitter = require(twitter); モジュールのロード var bot = new twitter({ consumer_key : xxxxxxxxxx, consumer_secret : xxxxxxxxxx, さきほど取得した access_token_key : xxxxxxxxxx, 各キーを入力 access_token_secret : xxxxxxxxxx }); Twitter に Hello, world! とつぶやく。 bot.updateStatus(Hello, world!, function (data) { つぶやいたら呼ばれる console.log(data); コールバック関数。 }); data には Twitter から 返ってきた JSON が 入っている。
  • 25. 結果$ node twitter{ entities: { hashtags: [], user_mentions: [], urls: [] }, retweet_count: 0, id_str: 249420311064358913, place: null, in_reply_to_user_id: null, favorited: false, in_reply_to_status_id_str: null, coordinates: null, created_at: Sat Sep 22 08:10:10 +0000 2012, in_reply_to_user_id_str: null, contributors: null, user:…(ry
  • 26. Streaming API を利用•  twitter モジュールの説明: –  https://github.com/jdub/node-twitter•  stream 接続 bot.stream(user, function(stream) { stream.on(data, function(data) { console.log(data); // ズラーッと TL の情報が表示される }); });※ ローカル環境の Linux 機で試してみると $ node bot とコマンドを実行してもすぐ終了してしまう場合があります。原因は分かる方いらっしゃいましたら @hecomi まで教えて下さい m(_ _)m
  • 27. 色んなボットを作ってみよう!•  例として3つ紹介します –  おうむ返しボット –  特定のキーワードに反応するヤツ –  人工無脳
  • 28. おうむ返しボットvar BOT_ID = hecomiroid; この ID をミスるとループしまくるので注意!bot.stream(user, function(stream) { stream.on(data, function(data) { if ( !(text in data) ) { Streamin API 接続直後は console.error([ERROR] invalid data); following ID 一覧が降ってき return; たりするので、そういったゴミ } を除外。 var twUserId = data.user.screen_name , replyStr = data.text.replace(new RegExp(^@ + BOT_ID + ), ) , isMention = (data.in_reply_to_user_id !== null) ; @の部分を除去 if (!isMention || twUserId === BOT_ID) return; bot.updateStatus(@ + id + + text, function (data) { console.log(data); }); 他人から自分へのつぶやき以外は除外 });});
  • 29. 特定のキーワードに反応するヤツvar BOT_ID = hecomiroid;bot.stream(user, { track: Vim }, function(stream) { stream.on(data, function(data) { 自分の TL に加えて、検索ワー if ( !(text in data) ) { ドを追加できる console.error([ERROR] invalid data); return; } if (data.user.screen_name === BOT_ID) return; var twStr = data.user.name + さんが、" + data.text + "って呟いた; bot.updateStatus(twStr, function (data) { console.log(data); }); });});
  • 30. 人工無脳var printf = require(printf); // npm install printfvar BOT_ID = hecomiroid;var replyMap = { こんにち(は|わ) : ちょりーっす!, おやすみ(なさい)? : いい夢見ろよ, うー : (」・ω・)」うー!(/・ω・)/にゃー!, (.*?)なう : %sするのが許されるのは小学生までだよねー!};bot.stream(user, function(stream) { stream.on(data, function(data) { キーワードと返信する文章を if ( !(text in data) ) { 正規表現で書いて console.error([ERROR] invalid data); return; 引っ掛かったら返事をつぶやく } if (data.user.screen_name === BOT_ID) return; for (var regex in replyMap) { if ( new RegExp(regex).test(data.text) ) { var replyStr = printf(replyMap[regex], RegExp.$1); var tweetStr = printf(@%s %s, data.user.screen_name, replyStr); bot.updateStatus(tweetStr, function (data) { console.log(data); }); return; } }});
  • 31. できた!•  というわけで Twitter ボットが出来まし た。•  最後に、もう一歩進んだボット制作を紹 介して終わりにします。
  • 32. Make more interesting bot!もういっぽふみこんでみる
  • 33. もっと色々やりたい•  色んな(JavaScriptには無い)プログラ ムやライブラリと連携してもっと面白い ことをつぶやかせたい、と思いません か?
  • 34. もっと色々やりたい•  色んな(JavaScriptには無い)プログラ ムやライブラリと連携してもっと面白い ことをつぶやかせたい、と思いません か?•  それ、簡単にできます!
  • 35. もっと色々やりたい•  色んな(JavaScriptには無い)プログラ ムやライブラリと連携してもっと面白い ことをつぶやかせたい、と思いません か?•  それ、簡単にできます!•  例として MeCab を使った形態素解析ボッ トを作ってみようと思います。•  簡単な方法と大変な方法の2つを紹介し ます。
  • 36. MeCab のインストール•  MeCab: Yet Another Part-of-Speech and Morphological Analyzer –  http://mecab.googlecode.com/svn/trunk/mecab/ doc/index.html#download•  Windows ならインストーラ –  インストール後は環境変数へ登録•  mac なら –  brew install mecab mecab-ipadic•  Linux なら –  sudo aptitude install mecab mecab-ipadic-utf8
  • 37. ① 簡単な方法•  コンソール上で実行して結果をパースvar exec = require(child_process).exec;exec(ls, function(err, stdout, stderr) { console.log(stdout);});•  こんな風にコマンドの実行結果を文字列 で受け取ることができますので、後はパ ースすれば OK です。
  • 38. MeCab の結果をパースvar exec = require(child_process).exec , fs = require(fs) , TMP_TXT_FILE_NAME = __tmp__.txt;function parse(str, callback) { (ちなみに fs.writeFile(TMP_TXT_FILE_NAME, str, function(err) {   echo ‘hogehoge’ | mecab if (err) callback(err, null); を利用しても OK です。ファイルに exec(mecab + TMP_TXT_FILE_NAME, function(err, stdout, stderr) {  一時書きだしたのは windows 環境  での文字化けを避けているからです) if (err) callback(err, null); var mecabResultArr = [] , mecabResultStr = stdout.split(n) ; 解析する文章を for (var i in mecabResultStr) { 一時ファイルに書き出す var wordInfoArr = []; if (mecabResultStr[i].indexOf(EOS) === 0) break; /([^s]+)s+([^s]+)/.test(mecabResultStr[i]); wordInfoArr.push(RegExp.$1); MeCab を実行して wordInfoArr = wordInfoArr.concat(RegExp.$2.split(,)); mecabResultArr.push(wordInfoArr); 結果をパースする } exec(rm + TMP_TXT_FILE_NAME, function(err, stdout, stderr) { if (err) callback(err, null); callback(null, mecabResultArr); }); 一時ファイルを削除 }); });}parse(すもももももももものうち, function(err, result) { console.log(result); });
  • 39. 結果$ node mecab[ [ すもも, 名詞, 一般, *, *, *, *, すもも, スモモ, スモモ ], [ も, 助詞, 係助詞, *, *, *, *, も, モ, モ ], [ もも, 名詞, 一般, *, *, *, *, もも, モモ, モモ ], [ も, 助詞, 係助詞, *, *, *, *, も, モ, モ ], [ もも, 名詞, 一般, *, *, *, *, もも, モモ, モモ ], [ の, 助詞, 連体化, *, *, *, *, の, ノ, ノ ], [ うち, 名詞, 非自立, 副詞可能, *, *, *, うち, ウチ, ウチ] ]
  • 40. 別の JS から使えるようにするvar exec = require(child_process).exec , fs = require(fs) , TMP_TXT_FILE_NAME = __tmp__.txt; module.exports すると別のファイルからこの 関数を使えるようになるmodule.exports = function(str, callback) { fs.writeFile(TMP_TXT_FILE_NAME, str, function(err) { if (err) callback(err, null); exec(mecab + TMP_TXT_FILE_NAME, function(err, stdout, stderr) { if (err) callback(err, null); var mecabResultArr = [] , mecabResultStr = stdout.split(n) ; for (var i in mecabResultStr) { var wordInfoArr = []; if (mecabResultStr[i].indexOf(EOS) === 0) break; /([^s]+)s+([^s]+)/.test(mecabResultStr[i]); wordInfoArr.push(RegExp.$1); wordInfoArr = wordInfoArr.concat(RegExp.$2.split(,)); mecabResultArr.push(wordInfoArr); } exec(rm + TMP_TXT_FILE_NAME, function(err, stdout, stderr) { if (err) callback(err, null); callback(null, mecabResultArr); }); }); });}
  • 41. 別の JS から使うvar parse = require(./parse.js);parse(すもももももももものうち, function(err, result) { console.log(result);});
  • 42. 形態素分析ボット
 (おうむ返しボットを改造)•  つぶやく部分を以下のように変更すると 形態素解析ボットが出来ますparse(mentionStr, function(err, mecabResult) { var replyStr = ; mecabResult.forEach(function(wordInfoArr) { replyStr += printf(%s[%s] , wordInfoArr[0], wordInfoArr[1]); }); var tweetStr = printf(@%s %s, data.user.screen_name, replyStr); bot.updateStatus(tweetStr, function (data) { console.log(data); });});
  • 43. ② 大変な方法•  C/C++ でモジュールを書く –  面倒ですが作れば速いです•  v8 のお作法に従って書けばOK•  詳しく解説しようとすると時間足りない ので、詳細は以下をご参照下さい m(_ _)m•  node.js の mecab addon 作った - 凹みTips※ –  http://d.hatena.ne.jp/hecomi/20120611/1339347112※ ここでは node-waf をコンパイルツールとして使っていますが、最近は node-gyp に置き換わったみたいです。
  • 44. Summaryおわりに
  • 45. まとめ•  Node.js の環境を整えました•  Twitter に呟くボットを作ってみました•  一歩踏み込んだ処理をするボットを作っ てみました
  • 46. Appendixおまけ
  • 47. おまけ - ネストを浅く•  非同期処理を繰り返すとネストがどんど ん深くなっていきますvar exec = require(child_process).exec;exec(echo hoge, function(err, stdout, stderr) { console.log(stdout); exec(echo fuga, function(err, stdout, stderr) { console.log(stdout); exec(echo piyo, function(err, stdout, stderr) { console.log(stdout); }); });});•  これを解決する方法は色々ありますが、 async.js あたりがおすすめです。
  • 48. おまけ - ネストを浅くvar exec = require(child_process).exec , async = require(async);async.series([ function(next) { exec(echo hoge, function(err, stdout, stderr) { console.log(stdout); next(null); }); }, function(next) { exec(echo fuga, function(err, stdout, stderr) { console.log(stdout); next(null); }); }, function(next) { exec(echo piyo, function(err, stdout, stderr) { console.log(stdout); next(null); }); }]);
  • 49. おまけ - ネストを浅く•  async.js には他にもパラで処理したり、 引数を次々と渡して行ったりと色んなパ ターンで書けます。•  参考: –  async.jsでフロー制御 - すぎゃーんメモ –  http://d.hatena.ne.jp/sugyan/ 20110605/1307240191
  • 50. おまけ - ネストを浅く•  非同期処理を繰り返すとネストがどんど ん深くなっていきますvar exec = require(child_process).exec;exec(echo hoge, function(err, stdout, stderr) { console.log(stdout); exec(echo fuga, function(err, stdout, stderr) { console.log(stdout); exec(echo piyo, function(err, stdout, stderr) { console.log(stdout); }); });});•  これを解決する方法は色々ありますが、 async.js あたりがおすすめです。
  • 51. おまけ - 例外処理•  例外が処理されないと Node.js は…
  • 52. おまけ - 例外処理•  例外が処理されないと Node.js は… _人人人人人人_
 > 突然の死 <
  ̄^Y^Y^Y^Y^Y^ ̄ します。
  • 53. おまけ - 例外処理•  なので以下のようなコードで例外を補足 して処理してあげます。process.on(uncaughtException, function (err) { console.log(uncaughtException => + err);});•  参考 –  node.jsの最低限の例外処理 - motsatのブログ –  http://d.hatena.ne.jp/bellbind/20110530/1306764093
  • 54. おわりend