TwitterのDM送信プログラムを書いてみた
グリーンバンドが届きました!
ほいで、賛同者の方々に住所を聞くDMをがんがん投げたくなったので、自動送信プログラムを書いてみました。もちろんTDDです。
テスト
#! /opt/local/bin/ruby -w # -*- mode:ruby; coding:utf-8 -*- require 'dmsender' $sleep = 0 def sleep(sec) $sleep += sec end describe DMSender do before do $sleep = 0 @twitter = mock 'twitter4r' @log = mock 'log' @sender = DMSender.new @twitter, @log end it "はログイン/DM送信をする" do @twitter.should_receive(:message).with(:post,"hi","mzp").once @log.should_receive(:info).with("sending to mzp") @sender.send_message ["mzp"],"hi" end it "は複数の宛先にメッセージを送る" do @twitter.should_receive(:message). with(:post,"hi",match(/mzp|nzp/)). exactly(2) @log.should_receive(:info). with(match(/sending to (mzp|nzp)/)). exactly(2) @sender.send_message ["mzp", "nzp"],"hi" end it "は送信ごとにsleepする" do @twitter.stub!(:message) @log.stub!(:info) @sender.send_message ["a","b","c"],"hi" $sleep.should == DMSender::WaitTime * 3 end it "は本文にerbが使える" do @twitter.should_receive(:message).with(:post,"hi, @mzp","mzp").once @log.should_receive(:info).with("sending to mzp") @sender.send_message ["mzp"],"hi, <%= screen_name %>" end it "はサーバがエラーを返したら停止する" do e= StandardError.new @twitter.should_receive(:message).and_raise(e) @log.should_receive(:info).with("sending to a") @log.should_receive(:error).with("Error: #{e.inspect}") @sender.send_message ["a", "b", "c" ],"hi" end end
送信毎にwaitをいれたり、エラーがおきたら中止したりするのはとても重要です。逮捕されちゃうからね。
本体
#! /opt/local/bin/ruby -w # -*- mode:ruby; coding:utf-8 -*- require 'erb' class DMSender WaitTime = 2 def initialize(twitter, logger) @twitter = twitter @logger = logger end def send_message(users, message) erb = ERB.new message begin users.each do|user| @logger.info "sending to #{user}" screen_name = "@#{user}" @twitter.message :post, erb.result(binding), user sleep WaitTime end rescue => e @logger.error "Error: #{e.inspect}" end end end if __FILE__ == $0 require "rubygems" gem "twitter4r" require "twitter" require 'logger' client = Twitter::Client.new(:login => 'username', :password => 'pass') logger = Logger.new STDOUT sender = DMSender.new client, logger sender.send_message ["mzp"],<<END hi! <%= screen_name %> END end