ConoHa VPS +Docker で Twitter bot 的なものを作成する

某毒舌な bot を作成してみようと思い、 ConoHa VPS で作業をしました。
Docker のコンテナに Ruby で書いたスクリプトから PostgreSQL に入れた文章をツイートさせます。
使ったのは gem くらいでフレームワーク的なものは使ってないです。
ツイートさせたい文章を1ツイート1行になるような import.csvUTF-8 で用意しておくのも必要です。

今回は CentOS 6.5 な仮想マシンを作成して、 ConoHa の薄い本 Vol.3 ConoHa + Docker でサーバーをドカドカ立てよう!を参考に Docker を導入します。

導入して PDF の内容を一通りこなしてみてから一般ユーザーでも docker コマンドを使えるように、ユーザーを docker グループに追加します。

# gpasswd docker -a k-zoar

使い慣れた debian を pull して作業を行います。

$ docker pull debian
$ docker run -i -t debian /bin/bash

とりあえず Exit して一度 Commit しました。

docker # Exit
$ docker commit `dl` zoar/bot

今度はbot 用のコンテナを指定して起動します。

$ docker run -i -t zoar/bot /bin/bash

以下はコンテナ内での作業です。
とりあえず一般ユーザーを作成しておきます。

# useradd zoar
# mkdir -p /home/zoar
# chown zoar:zoar /home/zoar
# passwd zoar
# su zoar
$ chsh -s /bin/bash
$ exit

一般ユーザーのホームディレクトリに適当な方法で Import.csv をコピーしておきます。
scp でどっかから取ってくるのが楽かもしれません。

RubyPostgreSQL をインストールします。
設定は PostgreSQL からしていきました。

# apt-get update
# apt-get install ruby ruby1.9.1-dev postgresql-9.1 postgresql-server-dev-9.1 vim
# service postgresql start

サービスを起動させてから postgres ユーザーになり、データベースアクセス用のユーザーを作成します。

# su postgres
$ createuser -s zoar
$ psql
psql > alter user zoar password '%Password%';
psql > \q
$ exit

一般ユーザーになってデータベース、テーブルを作成してツイートの内容をデータベースに取り込みます。
テーブルは id カラムを自動採番にして、 body カラムにツイートの内容を入れるようにしています。

# su zoar
$ createdb -h localhost -U zoar tweet
$ psql -h localhost -U zoar tweet
psql > CREATE TABLE tweet ( id SERIAL UNIQUE, body TEXT );
psql > COPY tweet (body) from '/home/zoar/import.csv' with CSV;
psql > exit
$ exit

Ruby gems から PostgreSQL アクセス用の gem と Twitter 操作用の gem をインストールします。

# gem install pg twitter

一般ユーザーのホームディレクトリに PostgreSQL アクセスアカウントの情報と Twitter 投稿に必要な情報を記録しておきます。

# su zoar
$ touch ./.pgaccount
$ chmod 600 ./.pgaccount
$ vi ./.pgaccount

ベタのテキストで1行目にデータベース接続用アカウントのアカウント名、2行目にパスワードを入力しておきます。

zoar
%Password%

Twitter の情報は Twitter Application Management のサイトで適当にアプリケーションを作成して、アプリケーションとアクセストークンの Access Level を Read and write に変更しておきます。

$ touch ./.twaccount
$ chmod 600 ./.twaccount
$ vi ./.twaccount

./.twaccount./.pgaccount と同じ様にベタのテキストでそれぞれ1行ずつ記録しておきます。

%Consumer Key%
%Consumer Secret%
%Access Token%
%Access Token Secret%

ツイート用のスクリプトを適当なディレクトリに書き込みます。

$ mkdir bot
$ cd bot
$ touch ./sendtweet.rb
$ chmod +x ./sendtweer.rb
$ vi ./sendtweet.rb

スクリプトは次のような感じ

#!/usr/bin/ruby -Ku

require 'pg'
require 'twitter'

pgacdata = []
open("/home/zoar/.pgaccount") do |pgaccount|
   pgaccount.each_line do |pgaccountline|
      pgacdata << pgaccountline.chomp
   end
end

def sendtweet(body)
   twacdata = []
   open("/home/zoar/.twaccount") do |twaccount|
      twaccount.each_line do |twaccountline|
         twacdata << twaccountline.chomp
      end
   end

   client = Twitter::REST::Client.new do |config|
      config.consumer_key = twacdata[0]
      config.consumer_secret = twacdata[1]
      config.access_token = twacdata[2]
      config.access_token_secret = twacdata[3]
   end

   client.update(body)

end

connection = PG::connect(
   :host => "localhost",
   :user => pgacdata[0],
   :password => pgacdata[1],
   :dbname => "tweet",
   :port => "5432")

begin
   result = connection.exec("Select * from tweet")
   $datacount =  result.ntuples

   $getnumber = rand(1..$datacount)
   
   result = connection.exec("Select body from tweet where id=#{$getnumber}")

   result.each do |value|
      sendtweet(value['body'])
   end
ensure
   connection.finish
end

PostgreSQL のレコード数を確認して、乱数から適当なツイートをとってきて Twitter に投稿しています。
なんでグローバル関数のところがあるんだろうか…。その辺は適当に変えてくだし。

Ruby スクリプトを書いたら Cron から Ruby スクリプトを呼び出せるようにします。
一度一般ユーザーから exit して root で作業

# apt-get install anacron sudo
# gpasswd crontab -a zoar
# gpasswd sudo -a zoar

グループに追加したら cron の設定をします。

# su zoar
$ crontab -e

好きなタイミングで sendtweet.rb を呼び出す内容を書き込めば OK です。

ところで、コンテナ起動時には PostgreSQL も cron も起動してくれないので次のようなスクリプトを書いておきました。

# touch /etc/start
# chmod +x /etc/start
# vi /etc/start
#!/bin/sh

service postgresql start
service cron start
/bin/bash

スクリプトを書き終えたら Exit してホスト OS に戻って Commit します。

docker # exit
$ docker commit `dl` zoar/bot

コンテナを動かす時には次のように起動させるとサービスも動かせます。

$ docker run -i -t zoar/bot /etc/start

docker から C-p C-q で抜けて設定した時間にツイートが流れれば OK です。

ホスト OS 側から操作するためにコンテナで SSH 動かしても良いかもしれません。
長々と書いたけど、もっと簡単な方法があるんだろうなぁと思ってるところです。