Twitter bot 鸚鵡ちゃんを Raspberry Pi 3 で動かす

鸚鵡ちゃんは2012年に Twitter 向けに書かれた bot で、タイムラインやリプライから言葉を覚え、覚えた言葉をたまにつぶやいたりリプライに反応したりする。最新の Twitter API に対応するため最近書き換えた。

今まで実験のため PC の電源を入れているときに気分で動かしていたが、たまに動かすと割と反応をもらえることもあり、継続的に動いてもらうべく常時電源の入っている環境で動かすことにした。

Heroku で動いてもらうことも考えたが、主に Web アプリケーションのためのサービスより手元の環境でゴリゴリやったほうが早いだろうと思ってたまたま持っている Raspberry Pi 3 で動かすことにする。Raspberry Pi 3 は無線LAN設定済み。

rbenv のインストール

とにもかくにも apt-get で入る Ruby が古いので rbenv で新しい Ruby を入れるところから始めよう。rbenv の README に従ってインストールするとすんなり入る。

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ ~/.rbenv/bin/rbenv init

# csh や zsh における rehash と同義
$ hash -r

ここで bash を再起動しないと rehash がうまくいかなかった。

ruby-build を入れる

これは rbenv install するために必要。

$ mkdir -p "$(rbenv root)"/plugins
$ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

Ruby 2.5.3 のインストール

最新の安定板は 2.6.1 だが、後述の Bundler に不具合があるそうなので一つ前の 2.5.3 を入れる。インストールには20分程度かかった。

# Ruby のビルドに必要
$ sudo apt-get install ruby-dev

# このライブラリも必要だった
$ sudo apt-get install libssl-dev libreadline-dev libsqlite3-dev

$ rbenv install 2.5.3

Bundler の使用

Bundler は npm のように gem パッケージをローカルにインストールするためのパッケージ。鸚鵡ちゃんを今どきの、プロジェクトごとにパッケージを入れる形にして他の人にも使いやすくする。

Gem を使ってインストールする。

$ rbenv exec gem install bundler
$ rbenv rehash

プロジェクトで使うには、そのディレクトリへ移動し次のコマンドを実行する。

$ cd ~/2236om
$ rbenv exec bundle init

するとそのディレクトリに Gemfile というファイルができるので、インストールしたいパッケージを記述していく。

gem 'pit', '0.0.7'
gem 'twitter', '6.2.0'
gem 'sqlite3', '1.4.0'

Gemfile が用意できたら Bundler を使って実際にインストールする。

$ rbenv exec bundle install --path=vendor/bundle

プログラムからは次のように通常の require の前に bundler を追加する。

require 'bundler/setup'

Cron の設定

鸚鵡ちゃんを cron で動かすため which コマンドで ruby の場所を調べて次のような crontab を書いたがうまくいかない。

MAILTO=""
* * * * * /home/pi/.rbenv/shims/ruby /home/pi/2236om/scheduled.rb

次のように cron のログを出力できるようにして調べて見る。

# cron の行のコメントを外す
$ sudo vi /etc/rsyslog.conf
$ sudo /etc/init.d/rsyslog restart

# すべてのログを出力するようにする: EXTRA_OPTS="-L 15"
$ sudo vi /etc/default/cron
$ sudo /etc/init.d/cron restart

# ログを監視
$ tail -f /var/log/cron.log

ログを見ると Ruby 自体は動くようだが、次のようなログが出力され鸚鵡ちゃんだけ動かない。

Mar 10 11:52:02 raspberrypi CRON[8105]: (CRON) error (grandchild #8109 failed with exit status 1)

どうやら実行ディレクトリが怪しいのでホームディレクトリに移動して鸚鵡ちゃんを起動してみる。

$ cd ~
$ ruby 2236om/scheduled.rb
Traceback (most recent call last):
	2: from 2236om/scheduled.rb:16:in `<main>'
	1: from /home/pi/.rbenv/versions/2.5.3/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
/home/pi/.rbenv/versions/2.5.3/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require': cannot load such file -- twitter (LoadError)

ということで実行ディレクトリに原因があるので次のように crontab を書き直す。

MAILTO=""
* * * * * cd /home/pi/2236om; /home/pi/.rbenv/shims/ruby scheduled.rb

これでめでたく鸚鵡ちゃんを動かすことができた。

おまけ:apt-get チートシート

やりたいこと コマンド
パッケージリストの更新 sudo apt update
インストール済みは? sudo dpkg -l
パッケージを検索(完全一致) sudo apt list
パッケージを検索(部分一致) sudo apt search
パッケージをインストール/更新 sudo apt install パッケージ名
パッケージを全て更新 sudo apt upgrade

おまけ:鸚鵡ちゃんが利用している Twitter API のレート制限

API Requests/Window Window
GET statuses/home_timeline 15 15 分
GET statuses/mentions_timeline 75 15 分
POST statuses/update 300 3 時間