OpenQRMを運用してみる(断念)

インストールと初期設定は何とか終わったものの、肝心の運用方法がよく分からない。
公式サイトから色々たどってみたところ、下記のドキュメントを発見。
http://www.openqrm-enterprise.com/fileadmin/DATA/Whitepapers/Setup_your_own_openQRM_Cloud_on_Ubuntu_Lucid_Lynx.10052010.pdf
やりたいことはプライベートクラウド上でKVMを運用することなので、UbuntuCentOSの違いはあるものの、これを参照して環境を作ってみる事にする。
まず、インストールの部分でいくつかやっていない事項があったので、それらをやる。

ネットワークインターフェースを変更

初期設定でネットワークインターフェースをeth0にしたが、これだとVMIPアドレスがNATで振られてしまうみたいなので、ブリッジインターフェースを作成する。
まず、
http://hnakamur.blogspot.com/2010/12/centos.html
を参考に作業し、ブリッジインターフェースbr0を作成。
/usr/local/openqrm-4.8/openqrm/etc/openqrm-server.conf
を編集し、

OPENQRM_SERVER_INTERFACE=eth0

OPENQRM_SERVER_INTERFACE=br0

のように変更し、OpenQRMを再起動。

# /etc/init.d/openqrm restart

qemu-kvmをインストール

# rpm -qa | grep kvm

したところ、KVMコンポーネントが何も入ってなかった…orz

# yum install qemu-kvm

して入れた。
これでインストールに関しては同等になったはず…?

その後の作業

その後、上記ドキュメント通りに作業し、なんとかインスタンスの作成まで終えたのだが、インスタンスの状態が「Active」になったにも関わらず、Error EventsにVMの作成に失敗した旨のエラーが出ていて、VNCでの接続もうまくいかなかった。
(ホストOS自体を再インストールしてしまったので、詳細なエラーメッセージが残っていない…。)
libvirt等必要なのだろうか?
今回はこれ以上の時間をかけられないので、ここで断念する。
しかし、自分のローカルネットワークでEC2みたいなインスタンス作成画面が出たときはテンション上がったし、またトライしようと思う。
ただ、課金に関する項目を設定する必要があったりとか、個人で使うには大きすぎる印象も持った。
この辺はプラグインの有効/無効や設定で、もうちょっとシンプルな運用もできるのかもしれない。

OpenQRMの初期設定

インストールした後、Webの管理画面(http://localhost/openqrm/)にアクセスして行うOpenQRMの初期設定。

step1

NICは一枚しか刺さっていないので、eth0を選択してnext。


ちなみに後から分かったことではあるが、このstep1の設定は、$OPENQRM_SERVER_BASE_DIR/web/base/configure.phpsedコマンドにより$OPENQRM_SERVER_BASE_DIR/etc/openqrm-server.confを書き換えるようになっているが、バグにより機能していないようだ。(sedコマンドが不正で、/var/log/messagesにsedコマンドのエラーが吐かれていた。)
よって、ネットワークインターフェースをopenqrm-server.confの設定から変更する場合、ファイルを直接編集しなければならない。

step2

mysqlしかインストールされていないので、mysqlを選択してnext。
次に、データベース設定画面になる。
そのままInitializeでいいのか?と思いとりあえずポチる。
しかし反応なし。
ログを色々見ていると、/var/log/httpd/error_logに

sh: /usr/local/openqrm-4.8/openqrm/sbin/openqrm-exec: Permission denied

の記述を発見。
当該ファイルにはちゃんと実行パーミッションが付いているみたいだが?
ググってみると、
http://sourceforge.net/projects/openqrm/forums/forum/519722/topic/3742386
に情報があった。
SELinuxを無効にしろとのこと。
無効にした後再度ポチるが、やはり反応なし。
再度/var/log/httpd/error_logを見ると、

mysql_pconnect(): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) in /usr/local/openqrm-4.8/openqrm/web/base/include/adodb/drivers/adodb-mysql.inc.php on line 383

ってある。
もしかしてmysqlの設定は自分でやらないといけない?
確かに、netstatでみたときにmysqlがlistenしていないのは気になってはいたんだよな。
とりあえず、

# /etc/init.d/mysqld start

したところ、コマンドラインからrootパスワードが空で繋がる状態みたいなので、管理コンソール上のrootパスワードも空にしてもう一回ポチる。
しばらく待った後、初期画面が表示された。
mysqldは忘れずchkconfigで自動起動するようにしておく。
rootパスワードが空とか、SELinuxを無効にしたりとか、ちょっとやっつけだが、とりあえず動いた。
ビルド時から色々エラーが出たのでかなり苦戦した。
しかし、これだけのミドルウェア群がこれだけの手間で連携して動くとか、ちょっと感動するな。

CentOS 6.0へのOpenQRMのインストール

公式ページのドキュメントにはパッケージインストールの手順が書かれていたが、最新バージョンのパッケージが無かったので、ソースからビルドしてみた。
すべてrootでの作業。

ソースをダウンロード、展開

# wget http://sourceforge.net/projects/openqrm/files/openQRM-4.8/openqrm-4.8.tgz/download
# tar xzvf openqrm-4.8.tgz
# cd openqrm-4.8/src

INSTALLを読む、ビルド設定

doc/INSTALLを読むと、etc/openqrm-server.confをいじると色々変えられるよーと書いてある。

OPENQRM_SERVER_BASE_DIR=/usr/local/openqrm-4.8
OPENQRM_RESOURCE_BASE_DIR=/usr/local/openqrm-4.8

の二カ所を変更。

手順

INSTALLを読んだところ、rpmを作る方法もあるようだが、とりあえず難しいことは考えず、/usr/local以下に専用ディレクトリを掘ってインストールすることにする。
この場合、INSTALLによると、make → make install → make start になる。(と思う。)
make checkの役割がイマイチ不明だったのだが、Makefileを斜め読みしたところ、LAMP等の依存パッケージを入れてくれるターゲットで、make startしたときにも呼ばれるみたいなので、make → make install → make check → make start の順に実行してみることにする。

make

# make

すると途中で止まる。

ERROR: Could not download DMC-applet from 
make[2]: *** [compile] エラー 1
/bin/sh: line 0: cd: ./aoe-storage: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./wakeuponlan: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./vmware-server: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./puppet: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./collectd: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./cloud: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./novnc: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./kvm: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./nfs-storage: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./local-storage: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./dns: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./xen-storage: そのようなファイルやディレクトリはありません
/bin/sh: line 0: cd: ./zabbix: そのようなファイルやディレクトリはありません
make[1]: *** [all] エラー 1
/bin/sh: line 0: cd: ./tftpboot: そのようなファイルやディレクトリはありません
make: *** [compile] エラー 1

DMC-appletが404らしい。
ググってみると
http://sourceforge.net/tracker/?func=detail&aid=3295326&group_id=153504&atid=788031
というチケットを発見。
これに書いてある通り、
plugins/drbdmc/etc/build.conf/drbdmc.conf
を開き、

OPENQRM_SOURCE_DOWNLOAD="http://oss.linbit.com/drbd-mc/DMC-applet-$OPENQRM_SOURCE_VERSION.jar"

OPENQRM_SOURCE_DOWNLOAD="http://oss.linbit.com/drbd-mc-old/DMC-applet-$OPENQRM_SOURCE_VERSION.jar"

と編集する。
もう一回make。
するとまた404になる箇所が。

ERROR: Could not download dropbear from 
make: *** [initrd] エラー 1

恐らく上と同じ原因だろう。
404になったURL
http://matt.ucc.asn.au/dropbear/dropbear-0.52.tar.gz
のサイトを色々見てみると、どうやら最新の0.53がリリースされており、0.52は
http://matt.ucc.asn.au/dropbear/releases/dropbear-0.52.tar.gz
に移動されている。
最新版を使うか0.52を使うか迷うところだが、ここは0.52を使う事にする。

# grep -r "http://matt.ucc.asn.au/dropbear/dropbear" .

してURLが出てくる場所を調べると

./etc/build.conf/dropbear.conf:OPENQRM_SOURCE_DOWNLOAD="http://matt.ucc.asn.au/dropbear/dropbear-$OPENQRM_SOURCE_VERSION.tar.gz"

と出たので、
etc/build.conf/dropbear.confを編集し、

OPENQRM_SOURCE_DOWNLOAD="http://matt.ucc.asn.au/dropbear/dropbear-$OPENQRM_SOURCE_VERSION.tar.gz"

OPENQRM_SOURCE_DOWNLOAD="http://matt.ucc.asn.au/dropbear/releases/dropbear-$OPENQRM_SOURCE_VERSION.tar.gz"

に編集してmake。
なんか終わったっぽい。

make install

# make install

インストールディレクトリを見ると、
/usr/local/openqrm-4.8/openqrm
みたいな感じでディレクトリが入れ子になってしまったが、まあよしとする。

make check

# make check
Checking the requirements for RedHat based systems ...
openqrm-server requires: httpd, php, php-mysql, php-soap, mod_ssl, mysql, mysql-server, syslinux, screen, procmail, openssl

みたいに表示された後、必要なソフトウェアをyumでごりごりインストールし始める。
しかし途中でエラー。

No package collectd available.
Error: Nothing to do
ERROR: collectd could not be installed. Please install manually to continue
make: *** [check] エラー 1

ググってみると、EPELで提供されているパッケージのようなので、EPELを使用可能にする。

rpm -ivh http://download.fedora.redhat.com/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm

その後再度make checkで問題なく終了。
念のためEPELリポジトリはenable=0にしておく。
(collectd以後のインストールにEPELが使われてしまったかもしれない。)

make start

# make start

make checkが走ってから、初期化が始まる。

Starting httpd: httpd: apr_sockaddr_info_get() failed for hypervisor
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]
First startup detected. Running initialization.
 Looking for syslinux/pxelinux.0...found: /usr/share/syslinux/pxelinux.0
 Creating custom apache config.../etc/httpd/conf.d/openqrm-httpd.conf
 Checking /usr/local/openqrm-4.8/openqrm/etc/openqrm-server[FAILED]r OPENQRM_WEB_PROTOCOL=https..Reloading httpd: 
Adding password for user openqrm
 Initializing dropbear...
Will output 1024 bit rsa secret key to '/usr/local/openqrm-4.8/openqrm/etc/dropbear/dropbear_rsa_host_key'
Generating key, this may take a while...
Public key portion is:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgwCLYzJDFIxiek7XDatfFCrZTht+hoUjJZlJ7ygb+U5qy3+tlx5RMr2U7BaMPr223/jga9vGWQMv560EU+MW/1mN0o5saSPupiFzBnNnHEj1OcNyddCdztzfClk/dn9bTyjJ3aOL8HESyr+a+t0H5hOAxksx4TEZcfNCzBso1vpDO28t root@hypervisor
Fingerprint: md5 a0:b3:a0:ff:11:40:6c:a8:44:ea:4b:ca:4b:0c:16:71
  Adding public key to /root/.ssh/authorized_keys...

Starting the openQRM-server ver. 4.8.

Initialization complete. Please configure your openQRM Server at: http://192.168.1.100/openqrm/
-> User: openqrm  -> Password: openqrm

なんか[FAILED]の文字が見えるが、一応立ち上がった模様。
URLにアクセスするとブラウザに設定ウィザードが表示される。

技術書の写経ができない

どういう勉強の仕方が良いか、悩んでいる。
この辺
http://d.hatena.ne.jp/meganii/20110221/1298292184
を見て、技術書のサンプルコードを打ち込んで動かすこと、いわゆる「写経」が大事かと思い、しばらく実践してみた。
しかし、

技術書の「写経」の方法。

1.ローカルで使える SCM を用意

2.「ほんたった」などで対象の本を固定

3.ひたすらサンプルコードを写して実行

4.実行するたびにコミット(コミットログにページ番号を含める)

5.疑問点があったらコミットログや本に書き込む

6.章ごとにタグを打つ

がどうしても継続できない。
技術書のサンプルコードにあるような、fooとかbarとか、自分の問題と直結しないプログラムを書くことが、どうしても続けられないのだ。(ましてSCMを使うなんて…という感じだ。)
元々好きで読んでいるわけだし、本文やサンプルコードを「読む」のは非常に興味をそそれらて面白いのだけれども、サンプルコードを打ち込むとなるとそうはいかない。
どうも義務感というか、「書かなきゃ」みたいに思ってしまって、嫌々やるから時間がかかるし、時間がかかるうちにモチベーションが下がってしまって、途中で投げ出してしまう。
でもその捨てた部分に良いTIPSが書いてあったりして、ひょんなことで本を開いたとき気付いて、「ああすればよかった」なんて後悔したりする。
途中で「写経」することによって読みが中断され、「なんだったっけ?」みたいになるのもイマイチだ。
こうなると、「写経」ありきで勉強するのは、自分には合ってないんじゃないかと思えてきた。
(多分読むスピードや、プログラムを書いて理解するスピードが遅いのもあると思う。)
次みたいな感じじゃないと、自分は続かないかも。

1.読みたい本は原則として手を動かさずに最後まで読む

どうしても「書きたい」という衝動にかられたときだけコードを打ち込む。
読者がコードを打ち込みながら読む前提で書かれた本であっても、気が向かなかったら書かない。
要は、読むスピード感と、そこから生まれる「知りたい」というモチベーションを大事にする。
そういう意味では、前に書いたことと矛盾するようではあるが、興味が湧かない部分は思い切って読み飛ばしたり、読みたいところから読む、とかもありかもしれない。

2.その本のノウハウを使って自分が欲しいプログラムを書く

やはり本を読むだけだと生きた知識にはならないと思うので、自分で使う前提で、どんな小さいツールでもいいから、一本書き上げる。
当然ながら、必要だと感じたり、疑問を感じたときは本を読み返す。
(実際にアウトプットを出すには、Webで調べたり、同じような課題がありそうなOSSのソースを読んだり、人に聞いたりとかも必要だろうが。)
ただし、人に見てもらうという意識は大事だと思うので、できればソースを公開して、GitHubなんかに上げた上でTwitterなんかに流すのが良いのかも。


本来、2.の前提として1.があるのが望ましいのだろう。
事実、仕事ではそうやって勉強とアウトプットを繰り返してきた。
しかし、自分が面白いと思ったのであれば、1.の上に2.があってもいいと思う。
2.は自分が作りたいと思うものなら何でもいいんじゃないだろうか。
例えばブログエンジンとかでも、自分にとってすれば得るものは沢山あると思う。
いずれにせよ、何も考えずに「写経」するのはもう止めようと思う。


古い記事だけど、この辺の方法論に近いのかな。こんなふうにちょっと加減な(失礼)方が、自分にはしっくり来るかも。
http://jibun.atmarkit.co.jp/lskill01/rensai/study/study001.html
中でも、翻訳プロジェクトに手を挙げるのはかなりありだ。

Ruby で Windows7 のイベントログを解析

Windows 7 でのログオン/ログオフの時間が知りたかったので、120MBくらいあるセキュリティイベントのログ(XMLでエクスポートしたもの)を解析していた。
まず、標準のREXMLを素直に使ったのだが、MacBook AirではCPUが100%に張り付いてしまい、一晩たってもパースが完了しない。
(なお、Windows のイベントログはXMLで落としたそのままの状態だとの連続になっており、root タグが無くてパースできないので、まずファイルの先頭と末尾にを付加する必要がそもそもある。)
検索してみるとREXMLの遅さには定評がある?ようで(かなり頑張ってはいるがピュアRubyなのでしょうがないらしい。)、他にはLibXML、Nokogiriといったところが選択肢としてあるようだ。(他は未調査)

LibXML

公式のドキュメント
http://libxml.rubyforge.org/rdoc/
を見ると、巨大なファイルにはParserじゃなくてReaderを使ってね、とある。
ただ、Readerはノードを一つ一つ読み込んで行くカーソルライクなAPIみたいなので、xpathとか使えずに実装に難儀しそうに思い、多少メモリ食ってもいいか、ってことで、Parserを使ってみる。(この辺はコードサンプルが少なくて誤解している可能性があるので、怪しいかも。)

# gem install libxml-ruby

でインストールした後、公式ドキュメントにあるように

require "rubygems"
require "xml/libxml"

XML::Document.io(file_io)

してみたところ、(自分のコードがIOを渡す設計になっていたので)

Fatal error: Input is not proper UTF-8, indicate encoding !
Bytes: 0x83 0x70 0x83 0x58 at :1430.
Entity: line 89136: error: xmlSAX2Characters: huge text node: out of memory

と怒られてしまう。どうやら文字コードの問題と、ドキュメントがでかすぎるよってことのようだ。
わりかし予想通りであった。
文字コードはきっとShift JISを渡さなきゃいけないっぽくて、巨大なファイルはやっぱり無理なのだろうか、と思ってドキュメントを色々見ていると、

XML::Document.io(io) → XML::Document
XML::Document.io(io, :encoding => XML::Encoding::UTF_8,
:options => XML::Parser::Options::NOENT
:base_uri="http://libxml.org") → XML::Document

とあって、オプションを指定できるみたい。
どんなオプションが渡せるのか、XML::Parser::Optionsのドキュメントを見てみると、

HUGE	=	INT2NUM(XML_PARSE_HUGE)	 	 relax any hardcoded limit from the parser

てのがあった。
これを渡せばいいんじゃね?ってことで、

XML::Document.io(file_io, 
:encoding => XML::Encoding::SHIFT_JIS, 
:options => XML::Parser::Options::HUGE)

としたら無事パースできた。(数分で終わった。)
しかし、その後パースされたDocumentオブジェクトを色々弄っていると、segmentation faultが多発。
うーんと思ってまたドキュメントを眺めていると、XML::Document#findのところに

As a result, the associated document may be freed before the node list, which will cause a segmentation fault. To avoid this, use the following (non-ruby like) coding style:

nodes = doc.find('/header')
nodes.each do |node|
  ... do stuff ...
end

# nodes = nil # GC.start

と書いてあったので、findした後にGC.startしてみると、出なくなった。
しかし、全然関係ない部分を直したりしていると突然再発したりする。
やはり、こんなでかいファイルをParserで処理しようとすることに無理があるようだ。

Nokogiri

ここで、諦めてNokogiriを使うことにした。

# gem install nokogiri

としてインストール。
NokogiriにもReaderというLibXMLと似たようなAPIがありそうだったが、やはり同一の理由から普通にパースする方針を取った。
しかし、5分待ってもCPUが100%のまま終わる気配がない。
そもそも、実行するたびに5分も10分も待つのはつらいので、結局100行くらいのファイルに分割してNokogiriでパース、という手段に落ち着いた。
(最初からこうすればREXMLでも良かった可能性は大きいw)
Nokogiriに関してはWebに資料も多いし、APIも分かりやすいのでほとんどはまらなかったのだけど、イベントログは

<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'

というnamespaceを持っているため、パースする際に

require "rubygems"
require "nokogiri"

doc = Nokogiri::XML(file_io)
doc.xpath("/Events/ms:Event", { "ms" => "http://schemas.microsoft.com/win/2004/08/events/event" }) do |event|
...
end

のようにする必要があった。

※下記を参考にさせていただいた。
http://d.hatena.ne.jp/Gimite/20090926/1253964626

ログの解析について

次に実際にログを解析する際のポイントとなった事項をメモ。

ログオン/ログオフ時間の解析

当初EventIDを使い、
http://support.microsoft.com/kb/947226/ja
あたりを見て、下のようにログオン/ログオフの時間だけ拾おうとした。
(このマシンを使用するユーザーは自分のみの前提。)

def auth_event?
    if event_id_node
      return ["4624", "4634", "4647"].include?(event_id_node.text)
    end
    return false
  end

しかし、この方法だと、ありえない深夜や早朝の時間帯にログオンしていたことになってしまう。
(裏で動いているサービス等が出力したログなのだろうか?謎である。)
違うアプローチとして、xpathで言うところの

  • /Events/ms:Event/ms:EventData/ms:Data[@Name='TargetUserName']
  • /Events/ms:Event/ms:EventData/ms:Data[@Name='SubjectUserName']

に該当するノードのtextに自分のログオンIDが含まれるイベントの最小、最大を取ったところ、どうもそれらしいログオンの時間帯になった。
(正しいかどうかは謎だが、実情から考えると正しげ。この辺は結構情報が錯綜しているような気がする。)

イベントの起こった時間

こちらは当然といえば当然なのだが、

  • /Events/ms:Event/ms:System/ms:TimeCreated

の時間はGMTなので、日本時間にするには+9時間する必要がある。

ServersMan@VPSの Ubuntu に Redmine をインストールした。

ServersMan@VPSUbuntuRedmineをインストールした。
詳細な手順は
http://blog.redmine.jp/articles/redmine-1_1-installation_centos/
に詳しいが、Ubuntu ということで多少違う部分があったため、メモとして残しておく。
ちなみに、上記手順書自体は非常に丁寧に書かれており、CentOS 向けとはなっているが、Ubuntu であってもほとんど問題は起こらなかった。

CentOSの設定」

ServersMan@VPS の場合は管理用の Apache が動いていたので、特に作業は必要無かった。

「必要なパッケージのインストール」の部分

MySQL 関連だけ追加で入れた。(他は後でエラーが起こったら足りないものを入れようと思ったが、そのスタンスで問題無かったようだ。)

# apt-get install mysql-server libmysqlclient-dev

Rubyのインストール」

一回目のインストーラ実行時はライブラリが不足している旨のメッセージが出るが、インストーラの指示に従ってapt-getで足りないパッケージをインストールしてから再実行すればOK。(すばらしいインストーラだ。)

Redmineのインストール」

rakeが無いと言われたので、gemでインストールした。

# gem install rake

※こちらを参考にした。
http://d.hatena.ne.jp/mihoko_az/20110503/1304415095

「PassengerのApache用モジュールのインストール」

passenger-install-apache2-module コマンド実行時に、Ruby インストール時と同じように不足しているパッケージを教えてくれるので、apt-get でインストールすれば問題ない。

Apacheの設定」

「1. worker MPMに切り替える」

Ubuntuの場合の切り替え方が分からなかった。
とりあえずは速度を求めていないのでTODOとしてスルー。

「2. Passengerの設定を追加」

passenger.conf を /etc/apache2/conf.d 以下に作成する。
gems ディレクトリ以下のPassengerのバージョンが執筆時点だと3.0.5→3.0.7だったのと、Ruby Enterprise Editionをデフォルトの /opt 以下にインストールしていたので、そこも変更。
その状態でApacheを起動すると、「Headers」で始まる行が、mod_headers モジュールがロードされていないためシンタックスエラーとなる。
そのため、 mod_headersをロードする。

# cd /etc/apache2/mods-enabled
# ln -s ../mods-available/headers.load headers.load

その後 Apache を起動したところ、起動に成功。

Apache上のPassengerでRedmineを実行するための設定」

/var/lib/redmine の所有者を変更するよう指示されている。
しかし、 ps コマンドで見たところ、Apacheのプロセスが root のものと daemon のものの2つある。
Passenger のプロセスは root になっているようなので、とりあえずそのままに。

これで初期画面は出た。
Redmine のインストーディレクトリのパーミッションを変更していないので、何か問題が出るかもしれない。
しばらく使ってみる。

追記 - /var/lib/redmineの所有者について

インストールしたそのままだと、添付ファイルをアップロードする際にPermission Deniedとなる。
ファイルはnobody/nogroupの所有者で作られるようなので、/var/lib/redmineごと、

# chown -R nobody:nogroup /var/lib/redmine

しておいた。

twitterのbotをrubyで書いてみる(DSL風)

というわけで、仕様だけ考えてみた。
とりあえず、

  • 時間が来たら
  • 自分宛のmentionが来たら

なんらかのアクションを起こすよう定義できるようにする。
下のような感じで書けるようにしたい。

require 'twitter_app'

# 毎日4時に時間をつぶやく。
on_schedule("0 4 * * *") do |t|
  update("It is #{t} now.")
end
# @fromさんからHelloまたはHiが含まれるmentionが来たら返信する。
on_mention.from("@from").is_like(/Hello|Hi/) do |from, msg|
  reply(msg, "Nice to meet you. RT #{from}: #{msg.to_s}")
end

start

twitterAPIの仕様等あまり把握していないので、間違っているかもだが、まあこんなノリで作ることにする。