SlideShare uma empresa Scribd logo
1 de 54
Baixar para ler offline
モテる! Node.js でつくる
Twitter ボット制作
X

Presented by @hecomi
introduction

はじめに
                 / ̄ ̄ ̄ ̄ ̄ ̄\ 

           /             \ 

                  _______ 

           /     /           \| 

           .′ 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 ̄ ̄〉 ̄〉	
                       ̄ ̄ ̄ ̄
本発表について
•  となってる人が多いと思うので…
•  実際に Node.js 環境を構築して、その上
で Twitter ボットを動かしてみます。
–  おうむ返しボット、特定のキーワードに反応
するボット、人工無能ボットから、一歩進ん
で形態素解析ボットを紹介します。
introduction

のぉどじぇーえす?

Node.js?
•  http://nodejs.jp/
•  サーバサイドで JavaScript を実行
–  エンジンは v8
何が出来るの?
•  ブラウザの JavaScript で出来なそうな
ことがサーバ上で出来ます
何が出来るの?
•  ブラウザの JavaScript で出来なそうな
ことがサーバ上で出来ます
–  ファイル操作とか
var fs = require('fs');
fs.writeFile('log.txt', ‘Hello, world!', function(err) {
   if (err) throw err;
   console.log('Success!');
});
何が出来るの?
•  ブラウザの 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);
何が出来るの?
•  ブラウザの 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);
install

いんすとーる
インストールしよう
•  Windows 環境下(http://nodejs.org/)

クリックしてインストールするだけ
インストールしよう
•  Mac / Linux 環境下
–  バージョン管理も含めて nave がオススメ
•  https://github.com/isaacs/nave
インストールしよう
•  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
インストールしよう
•  インストールされたか確認
–  Windows の人はコマンドプロンプト上で
$ node –v
v0.8.9
$ npm –v
V1.1.61

•  これで OK!
Hello, world!

はろーわーるど
対話コンソール
$ node
> console.log('Hello, world!'); // これを打つ
Hello, world!
undefined
> (Ctrl+D 押下)
$
ファイル
$ cat helloworld.js
console.log('Hello, world!');
$ node helloworld.js
Hello, world!
おまけ:ブラウザ
// helloworld.js
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);
$ node helloworld
Make twitter bot!

ついったーぼっとせいさく
Consumer Key / Access Token
1.  適当な 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
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

•  依存関係も含めて必要なモジュールをイ
ンストールしてくれます
npm
•  npm は node package manager の略
•  package 数は 15006 個!(2012/09/22
•  使い方

現在)

–  npm install hoge
•  実行したディレクトリ下に node_modules ディレ
クトリを作成してそこにモジュールを展開
•  実行したディレクトリ下のみで使用できる

–  npm install -g hoge
•  どのディレクトリからでも使える
Twitter で はろーわーるど
•  早速使ってみましょう!
var twitter = require('twitter');
var bot = new twitter({
consumer_key
consumer_secret
access_token_key
access_token_secret
});

:
:
:
:

'xxxxxxxxxx',
'xxxxxxxxxx',
'xxxxxxxxxx',
'xxxxxxxxxx'

モジュールのロード

さきほど取得した
各キーを入力
Twitter に Hello, world!
とつぶやく。

bot.updateStatus('Hello, world!', function (data) {
console.log(data);
});

つぶやいたら呼ばれる
コールバック関数。
data には Twitter から
返ってきた JSON が
入っている。
結果
$ 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
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
色んなボットを作ってみよう!
•  例として3つ紹介します
–  おうむ返しボット
–  特定のキーワードに反応するヤツ
–  人工無脳
おうむ返しボット
この ID をミスるとループしまくるので注意!
var BOT_ID = 'hecomiroid';
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);
});
他人から自分へのつぶやき以外は除外
});
});
特定のキーワードに反応するヤツ
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);
});
});
});
人工無脳
var printf = require('printf');
var BOT_ID = 'hecomiroid';
var replyMap = {
'こんにち(は|わ)'
'おやすみ(なさい)?'
'うー'
'(.*?)なう'
};

// npm install printf

:
:
:
:

'ちょりーっす!',
'いい夢見ろよ',
'(」・ω・)」うー!(/・ω・)/にゃー!',
'%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;
}
}
});
できた!
•  というわけで Twitter ボットが出来まし
た。
•  最後に、もう一歩進んだボット制作を紹
介して終わりにします。
Make more interesting bot!

もういっぽふみこんでみる
もっと色々やりたい
•  色んな(JavaScriptには無い)プログラ
ムやライブラリと連携してもっと面白い
ことをつぶやかせたい、と思いません
か?
もっと色々やりたい
•  色んな(JavaScriptには無い)プログラ
ムやライブラリと連携してもっと面白い
ことをつぶやかせたい、と思いません
か?
•  それ、簡単にできます!
もっと色々やりたい
•  色んな(JavaScriptには無い)プログラ
ムやライブラリと連携してもっと面白い
ことをつぶやかせたい、と思いません
か?
•  それ、簡単にできます!
•  例として MeCab を使った形態素解析ボッ
トを作ってみようと思います。
•  簡単な方法と大変な方法の2つを紹介し
ます。
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
① 簡単な方法
•  コンソール上で実行して結果をパース
var exec = require('child_process').exec;
exec('ls', function(err, stdout, stderr) {
console.log(stdout);
});

•  こんな風にコマンドの実行結果を文字列
で受け取ることができますので、後はパ
ースすれば OK です。
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) {
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);
});
});
});
}

(ちなみに
  echo ‘hogehoge’ | mecab
を利用しても OK です。ファイルに
 一時書きだしたのは windows 環境
 での文字化けを避けているからです)

解析する文章を
一時ファイルに書き出す

MeCab を実行して
結果をパースする

一時ファイルを削除

parse('すもももももももものうち', function(err, result) { console.log(result); });
結果
$ node mecab
[ [ 'すもも', '名詞', '一般', '*', '*', '*', '*', 'すもも', 'スモモ', 'スモモ' ],
[ 'も', '助詞', '係助詞', '*', '*', '*', '*', 'も', 'モ', 'モ' ],
[ 'もも', '名詞', '一般', '*', '*', '*', '*', 'もも', 'モモ', 'モモ' ],
[ 'も', '助詞', '係助詞', '*', '*', '*', '*', 'も', 'モ', 'モ' ],
[ 'もも', '名詞', '一般', '*', '*', '*', '*', 'もも', 'モモ', 'モモ' ],
[ 'の', '助詞', '連体化', '*', '*', '*', '*', 'の', 'ノ', 'ノ' ],
[ 'うち', '名詞', '非自立', '副詞可能', '*', '*', '*', 'うち', 'ウチ', 'ウチ'
] ]
別の 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);
});
});
});
}
別の JS から使う
var parse = require('./parse.js');
parse('すもももももももものうち', function(err, result) {
console.log(result);
});
形態素分析ボット

(おうむ返しボットを改造)
•  つぶやく部分を以下のように変更すると
形態素解析ボットが出来ます
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);
});
});
② 大変な方法
•  C/C++ でモジュールを書く
–  面倒ですが作れば速いです

•  v8 のお作法に従って書けばOK
•  詳しく解説しようとすると時間足りない
ので、詳細は以下をご参照下さい m(_ _)m
•  node.js の mecab addon 作った - 凹みTips※
–  http://d.hatena.ne.jp/hecomi/20120611/1339347112
※ ここでは node-waf をコンパイルツールとして使っていますが、最近は node-gyp に置き換わったみたいです。
Summary

おわりに
まとめ
•  Node.js の環境を整えました
•  Twitter に呟くボットを作ってみました
•  一歩踏み込んだ処理をするボットを作っ
てみました
Appendix

おまけ
おまけ - ネストを浅く
•  非同期処理を繰り返すとネストがどんど
ん深くなっていきます
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 あたりがおすすめです。
おまけ - ネストを浅く
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);
});
}
]);
おまけ - ネストを浅く
•  async.js には他にもパラで処理したり、
引数を次々と渡して行ったりと色んなパ
ターンで書けます。
•  参考:
–  async.jsでフロー制御 - すぎゃーんメモ
–  http://d.hatena.ne.jp/sugyan/
20110605/1307240191
おまけ - ネストを浅く
•  非同期処理を繰り返すとネストがどんど
ん深くなっていきます
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 あたりがおすすめです。
おまけ - 例外処理
•  例外が処理されないと Node.js は…
おまけ - 例外処理
•  例外が処理されないと Node.js は…

_人人人人人人_

> 突然の死 <

 ̄^Y^Y^Y^Y^Y^ ̄
します。
おまけ - 例外処理
•  なので以下のようなコードで例外を補足
して処理してあげます。
process.on('uncaughtException', function (err) {
console.log('uncaughtException => ' + err);
});

•  参考
–  node.jsの最低限の例外処理 - motsatのブログ
–  http://d.hatena.ne.jp/bellbind/20110530/1306764093
おわり
end

Mais conteúdo relacionado

Destaque

サークル対抗テニス大会!
サークル対抗テニス大会!サークル対抗テニス大会!
サークル対抗テニス大会!stucon
 
テストプラン
テストプランテストプラン
テストプランstucon
 
「ビアマジ21」 ~大学生目線で認知度UP~
「ビアマジ21」
~大学生目線で認知度UP~「ビアマジ21」
~大学生目線で認知度UP~
「ビアマジ21」 ~大学生目線で認知度UP~stucon
 
バズ・オブ・ビアマジ21
バズ・オブ・ビアマジ21バズ・オブ・ビアマジ21
バズ・オブ・ビアマジ21stucon
 
ビアマジ!美女
ビアマジ!美女ビアマジ!美女
ビアマジ!美女stucon
 
ロボットによるサッカー対決
ロボットによるサッカー対決ロボットによるサッカー対決
ロボットによるサッカー対決stucon
 
Twitter分析のためのリアルタイム分析基盤@第4回Twitter研究会
Twitter分析のためのリアルタイム分析基盤@第4回Twitter研究会Twitter分析のためのリアルタイム分析基盤@第4回Twitter研究会
Twitter分析のためのリアルタイム分析基盤@第4回Twitter研究会Yuya Unno
 
ロボットによるサッカー対決
ロボットによるサッカー対決ロボットによるサッカー対決
ロボットによるサッカー対決stucon
 

Destaque (9)

サークル対抗テニス大会!
サークル対抗テニス大会!サークル対抗テニス大会!
サークル対抗テニス大会!
 
test
testtest
test
 
テストプラン
テストプランテストプラン
テストプラン
 
「ビアマジ21」 ~大学生目線で認知度UP~
「ビアマジ21」
~大学生目線で認知度UP~「ビアマジ21」
~大学生目線で認知度UP~
「ビアマジ21」 ~大学生目線で認知度UP~
 
バズ・オブ・ビアマジ21
バズ・オブ・ビアマジ21バズ・オブ・ビアマジ21
バズ・オブ・ビアマジ21
 
ビアマジ!美女
ビアマジ!美女ビアマジ!美女
ビアマジ!美女
 
ロボットによるサッカー対決
ロボットによるサッカー対決ロボットによるサッカー対決
ロボットによるサッカー対決
 
Twitter分析のためのリアルタイム分析基盤@第4回Twitter研究会
Twitter分析のためのリアルタイム分析基盤@第4回Twitter研究会Twitter分析のためのリアルタイム分析基盤@第4回Twitter研究会
Twitter分析のためのリアルタイム分析基盤@第4回Twitter研究会
 
ロボットによるサッカー対決
ロボットによるサッカー対決ロボットによるサッカー対決
ロボットによるサッカー対決
 

Semelhante a Title

UnityとnodeとMMDと
UnityとnodeとMMDとUnityとnodeとMMDと
UnityとnodeとMMDとsters
 
蜘蛛の巣から抜け出すには?
蜘蛛の巣から抜け出すには?蜘蛛の巣から抜け出すには?
蜘蛛の巣から抜け出すには?Hayato Tominaga
 
Eucalyptus 3.1 and next in #occpv
Eucalyptus 3.1 and next in #occpvEucalyptus 3.1 and next in #occpv
Eucalyptus 3.1 and next in #occpvOsamu Habuka
 
ぼくのかんがえたふつうのあんどろいどかいはつ
ぼくのかんがえたふつうのあんどろいどかいはつぼくのかんがえたふつうのあんどろいどかいはつ
ぼくのかんがえたふつうのあんどろいどかいはつYukiya Nakagawa
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoShoot Morii
 
ヒカルのGo 資料 Webアプリケーションの作り方
ヒカルのGo 資料 Webアプリケーションの作り方ヒカルのGo 資料 Webアプリケーションの作り方
ヒカルのGo 資料 Webアプリケーションの作り方Yosuke Furukawa
 
Web5-iwate
Web5-iwateWeb5-iwate
Web5-iwatedynamis
 
hubotで快適BOT生活
hubotで快適BOT生活 hubotで快適BOT生活
hubotで快適BOT生活 Kazufumi Otani
 
Ruby on Rails Tutorial Chapter8-10
Ruby on Rails Tutorial Chapter8-10Ruby on Rails Tutorial Chapter8-10
Ruby on Rails Tutorial Chapter8-10Sea Mountain
 
OCamlでJavaScriptが幸せ
OCamlでJavaScriptが幸せOCamlでJavaScriptが幸せ
OCamlでJavaScriptが幸せSachirou Inoue
 
Llでゆるふわプログラミングのすすめ
LlでゆるふわプログラミングのすすめLlでゆるふわプログラミングのすすめ
Llでゆるふわプログラミングのすすめmizcki
 
モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話
モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話
モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話Tomoo Amano
 
やる夫で学ぶマーケティング
やる夫で学ぶマーケティングやる夫で学ぶマーケティング
やる夫で学ぶマーケティングlogch admin
 
gumiStudy#5 JavaScript でネイティブiPhone/Androidアプリを作る
gumiStudy#5 JavaScript でネイティブiPhone/Androidアプリを作るgumiStudy#5 JavaScript でネイティブiPhone/Androidアプリを作る
gumiStudy#5 JavaScript でネイティブiPhone/Androidアプリを作るgumilab
 
Rubyで和暦をよみとる
Rubyで和暦をよみとるRubyで和暦をよみとる
Rubyで和暦をよみとるTakashi Ota
 
FFRK cocos2d xレイヤーの最適化
FFRK cocos2d xレイヤーの最適化FFRK cocos2d xレイヤーの最適化
FFRK cocos2d xレイヤーの最適化dena_study
 
Dodai projectの紹介
Dodai projectの紹介Dodai projectの紹介
Dodai projectの紹介Osamu Habuka
 
BigDataの集め方
BigDataの集め方BigDataの集め方
BigDataの集め方Mahito Ogura
 

Semelhante a Title (20)

UnityとnodeとMMDと
UnityとnodeとMMDとUnityとnodeとMMDと
UnityとnodeとMMDと
 
蜘蛛の巣から抜け出すには?
蜘蛛の巣から抜け出すには?蜘蛛の巣から抜け出すには?
蜘蛛の巣から抜け出すには?
 
Eucalyptus 3.1 and next in #occpv
Eucalyptus 3.1 and next in #occpvEucalyptus 3.1 and next in #occpv
Eucalyptus 3.1 and next in #occpv
 
ぼくのかんがえたふつうのあんどろいどかいはつ
ぼくのかんがえたふつうのあんどろいどかいはつぼくのかんがえたふつうのあんどろいどかいはつ
ぼくのかんがえたふつうのあんどろいどかいはつ
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
 
ヒカルのGo 資料 Webアプリケーションの作り方
ヒカルのGo 資料 Webアプリケーションの作り方ヒカルのGo 資料 Webアプリケーションの作り方
ヒカルのGo 資料 Webアプリケーションの作り方
 
Web5-iwate
Web5-iwateWeb5-iwate
Web5-iwate
 
hubotで快適BOT生活
hubotで快適BOT生活 hubotで快適BOT生活
hubotで快適BOT生活
 
Ruby on Rails Tutorial Chapter8-10
Ruby on Rails Tutorial Chapter8-10Ruby on Rails Tutorial Chapter8-10
Ruby on Rails Tutorial Chapter8-10
 
OCamlでJavaScriptが幸せ
OCamlでJavaScriptが幸せOCamlでJavaScriptが幸せ
OCamlでJavaScriptが幸せ
 
Llでゆるふわプログラミングのすすめ
LlでゆるふわプログラミングのすすめLlでゆるふわプログラミングのすすめ
Llでゆるふわプログラミングのすすめ
 
モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話
モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話
モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話
 
php.js
php.jsphp.js
php.js
 
やる夫で学ぶマーケティング
やる夫で学ぶマーケティングやる夫で学ぶマーケティング
やる夫で学ぶマーケティング
 
Puppetのススメ
PuppetのススメPuppetのススメ
Puppetのススメ
 
gumiStudy#5 JavaScript でネイティブiPhone/Androidアプリを作る
gumiStudy#5 JavaScript でネイティブiPhone/Androidアプリを作るgumiStudy#5 JavaScript でネイティブiPhone/Androidアプリを作る
gumiStudy#5 JavaScript でネイティブiPhone/Androidアプリを作る
 
Rubyで和暦をよみとる
Rubyで和暦をよみとるRubyで和暦をよみとる
Rubyで和暦をよみとる
 
FFRK cocos2d xレイヤーの最適化
FFRK cocos2d xレイヤーの最適化FFRK cocos2d xレイヤーの最適化
FFRK cocos2d xレイヤーの最適化
 
Dodai projectの紹介
Dodai projectの紹介Dodai projectの紹介
Dodai projectの紹介
 
BigDataの集め方
BigDataの集め方BigDataの集め方
BigDataの集め方
 

Mais de stucon

流行のSNSを活用したPR方法
流行のSNSを活用したPR方法流行のSNSを活用したPR方法
流行のSNSを活用したPR方法stucon
 
ビアマジ!21認知企画
ビアマジ!21認知企画ビアマジ!21認知企画
ビアマジ!21認知企画stucon
 
ビアマジ!21認知企画
ビアマジ!21認知企画ビアマジ!21認知企画
ビアマジ!21認知企画stucon
 
ビアマジが学校にやってくる!プロジェクト
ビアマジが学校にやってくる!プロジェクトビアマジが学校にやってくる!プロジェクト
ビアマジが学校にやってくる!プロジェクトstucon
 
エンジニアレンタルサービス
エンジニアレンタルサービスエンジニアレンタルサービス
エンジニアレンタルサービスstucon
 
エンジニアレンタルサービス
エンジニアレンタルサービスエンジニアレンタルサービス
エンジニアレンタルサービスstucon
 
子供の心を掴め!親にねだらせるPR方法
子供の心を掴め!親にねだらせるPR方法子供の心を掴め!親にねだらせるPR方法
子供の心を掴め!親にねだらせるPR方法stucon
 
ビアメシプロジェクト
ビアメシプロジェクトビアメシプロジェクト
ビアメシプロジェクトstucon
 
課題発見とビール一杯無料以外からの誘引施策
課題発見とビール一杯無料以外からの誘引施策課題発見とビール一杯無料以外からの誘引施策
課題発見とビール一杯無料以外からの誘引施策stucon
 
ビアマジ!21 暇人マッチングサービス
ビアマジ!21 暇人マッチングサービスビアマジ!21 暇人マッチングサービス
ビアマジ!21 暇人マッチングサービスstucon
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービスstucon
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービスstucon
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービスstucon
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービスstucon
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービスstucon
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービスstucon
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービスstucon
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービスstucon
 
学内PR企画
学内PR企画学内PR企画
学内PR企画stucon
 
ビアマジ!21オリジナルアプリ「呑み歩かNight!21」
ビアマジ!21オリジナルアプリ「呑み歩かNight!21」ビアマジ!21オリジナルアプリ「呑み歩かNight!21」
ビアマジ!21オリジナルアプリ「呑み歩かNight!21」stucon
 

Mais de stucon (20)

流行のSNSを活用したPR方法
流行のSNSを活用したPR方法流行のSNSを活用したPR方法
流行のSNSを活用したPR方法
 
ビアマジ!21認知企画
ビアマジ!21認知企画ビアマジ!21認知企画
ビアマジ!21認知企画
 
ビアマジ!21認知企画
ビアマジ!21認知企画ビアマジ!21認知企画
ビアマジ!21認知企画
 
ビアマジが学校にやってくる!プロジェクト
ビアマジが学校にやってくる!プロジェクトビアマジが学校にやってくる!プロジェクト
ビアマジが学校にやってくる!プロジェクト
 
エンジニアレンタルサービス
エンジニアレンタルサービスエンジニアレンタルサービス
エンジニアレンタルサービス
 
エンジニアレンタルサービス
エンジニアレンタルサービスエンジニアレンタルサービス
エンジニアレンタルサービス
 
子供の心を掴め!親にねだらせるPR方法
子供の心を掴め!親にねだらせるPR方法子供の心を掴め!親にねだらせるPR方法
子供の心を掴め!親にねだらせるPR方法
 
ビアメシプロジェクト
ビアメシプロジェクトビアメシプロジェクト
ビアメシプロジェクト
 
課題発見とビール一杯無料以外からの誘引施策
課題発見とビール一杯無料以外からの誘引施策課題発見とビール一杯無料以外からの誘引施策
課題発見とビール一杯無料以外からの誘引施策
 
ビアマジ!21 暇人マッチングサービス
ビアマジ!21 暇人マッチングサービスビアマジ!21 暇人マッチングサービス
ビアマジ!21 暇人マッチングサービス
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービス
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービス
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービス
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービス
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービス
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービス
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービス
 
暇人マッチングサービス
暇人マッチングサービス暇人マッチングサービス
暇人マッチングサービス
 
学内PR企画
学内PR企画学内PR企画
学内PR企画
 
ビアマジ!21オリジナルアプリ「呑み歩かNight!21」
ビアマジ!21オリジナルアプリ「呑み歩かNight!21」ビアマジ!21オリジナルアプリ「呑み歩かNight!21」
ビアマジ!21オリジナルアプリ「呑み歩かNight!21」
 

Title

  • 1. モテる! Node.js でつくる Twitter ボット制作 X Presented by @hecomi
  • 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 ボットを動かしてみます。 –  おうむ返しボット、特定のキーワードに反応 するボット、人工無能ボットから、一歩進ん で形態素解析ボットを紹介します。
  • 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);
  • 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!
  • 17. 対話コンソール $ node > console.log('Hello, world!'); // これを打つ Hello, world! undefined > (Ctrl+D 押下) $
  • 18. ファイル $ cat helloworld.js console.log('Hello, world!'); $ node helloworld.js Hello, world!
  • 19. おまけ:ブラウザ // helloworld.js 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); $ node helloworld
  • 21. Consumer Key / Access Token 1.  適当な 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 consumer_secret access_token_key access_token_secret }); : : : : 'xxxxxxxxxx', 'xxxxxxxxxx', 'xxxxxxxxxx', '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
  • 28. おうむ返しボット この ID をミスるとループしまくるので注意! var BOT_ID = 'hecomiroid'; 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'); var BOT_ID = 'hecomiroid'; var replyMap = { 'こんにち(は|わ)' 'おやすみ(なさい)?' 'うー' '(.*?)なう' }; // npm install printf : : : : 'ちょりーっす!', 'いい夢見ろよ', '(」・ω・)」うー!(/・ω・)/にゃー!', '%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! もういっぽふみこんでみる
  • 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) { 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); }); }); }); } (ちなみに   echo ‘hogehoge’ | mecab を利用しても OK です。ファイルに  一時書きだしたのは windows 環境  での文字化けを避けているからです) 解析する文章を 一時ファイルに書き出す MeCab を実行して 結果をパースする 一時ファイルを削除 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 に置き換わったみたいです。
  • 45. まとめ •  Node.js の環境を整えました •  Twitter に呟くボットを作ってみました •  一歩踏み込んだ処理をするボットを作っ てみました
  • 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