hagino3000's blog

平成アーカイブス (更新停止)

Twitterのreplyを携帯にメール送信するスクリプトをRubyで書いた。

殴り書き。送信メールサーバーはGmailを使った。自分に ml_on/ml_off というreplyを飛ばす事でON/OFFを切りかえる様にした。

require 'rubygems'
require 'twitter'
require 'twitter/console'
require 'json'
require 'time'
require 'yaml'
require 'tmail'
require 'tlsmail'

gem('twitter4r','0.3.1')

def log(msg)
  puts Time.new.to_s + ' ' + msg
end

module Gmail
  def Gmail.get_content(from_address, to_address, subject=nil, body=nil)
    content = TMail::Mail.new
    content.from = from_address
    content.to = to_address
    content.subject = subject
    content.date = Time.now
    content.mime_version = '1.0'
    content.set_content_type 'text', 'plain', {'charset'=>'utf-8'}
    content.body = body
    return content
  end
  
  def Gmail.send(user, pass, from_address, to_address, subject=nil, body=nil)
    mail = get_content(from_address, to_address, subject, body)
    Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
    Net::SMTP.start('smtp.gmail.com', 587, 'gmail.com', user, pass, :login) { |smtp|
      smtp.send_message(mail.encoded, mail.from, mail.to)
    }
  end
end

def getClient(mode)
  begin
    config_file = File.join(File.dirname(__FILE__), 'config', 'twitter.yml')
    client = Twitter::Client.from_config(config_file, mode)
  rescue Exception => ex
    puts ex.message
    puts 'Cannot get twitter client.'
    raise
  end
  return client
end


######################################################
# main
######################################################

log "start()"

result = nil
mconf  = nil

## Open control file
File.open( 'log/result.yml' ) do |io|
  YAML.load_documents(io){|y|
    result = y
  }
end

File.open( 'config/gmail.yml' ) do |io|
  YAML.load_documents(io){|y|
    mconf = y
  }
end

begin
  client = getClient(result["mode"])

  # メール送信のON/OFF
  isActive = result["active"] || false
  # 前回処理した最後のreplyのid
  lastExecStatusId = result["last_exec_status_id"] || 0
  # 今回処理する最後のreplyのid
  maxStatusId = 0
  
  # APIで取得できる全てのreplyを取得
  allReplies = Array.new
  public_timeline = client.timeline_for(:replies) do |status|
    allReplies << status
  end
  allReplies.reverse!

  newReplies = Array.new
  
  allReplies.each { |s|  
    maxStatusId = s.id if maxStatusId < s.id

    # 前回処理したreply以降のみ処理対象とする
    if s.id > lastExecStatusId
      # 自分へのreplyでON/OFFを切りかえる
      if s.user.screen_name == "YOUR_TWITTER_ACCOUNT" 
        isActive = true  if s.text.include?("ml_on")
        isActive = false if s.text.include?("ml_off")
        next
      end
      newReplies << s
    end
  }

  if !isActive
    result["last_exec_result"] = "inactive"
  elsif newReplies.size > 0
    mailbody = ""
    newReplies.reverse!
    # 送信メール本文を作成
    newReplies.each { |r|
      mailbody << "-----------------------"
      mailbody << "\n"
      mailbody << r.user.screen_name
      mailbody << "\n"
      mailbody << r.text
      mailbody << "\n"
      mailbody << r.created_at.to_s
      mailbody << "\n"
    }
    # メール送信
    Gmail.send(mconf["user"], mconf["password"], mconf["from"], mconf["to"], "twitter replies", mailbody)
    log "Mail successfuly sended"
    result["last_exec_result"] = "success"
  else
    result["last_exec_result"] = "no data"
  end
  
  result["last_exec_status_id"] = maxStatusId

rescue Exception => exp
  log "Abnormaly ended"
  log exp.to_s
  result["last_exec_result"] = "error"
ensure
  result["last_exec_time"] = Time.new.to_s
  result["active"] = isActive
  YAML.dump(result, File.open('log/result.yml', 'w'))
end

log "end()"

設定ファイルも含めた全てのソースファイルはbitbucketにアップしてあります。