public
Last active

Brett Terpstra's voicesms.rb command: send sms messages from the command line via google voice. Original here: http://brettterpstra.com/sms-from-the-command-line-with-google-voice/

  • Download Gist
voicesms.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
#!/usr/bin/env ruby -Ku
 
require 'net/http'
require 'net/https'
require 'open-uri'
require 'cgi'
require 'optparse'
require 'jcode' if RUBY_VERSION < '1.9'
 
ACCOUNT = '' # Set to Google Voice account email for default account
PASSWORD = '' # Set to Google Voice account password for default account
NUMBERS = ['+1555444333','+1555444222'] # Set one or more numbers for default destination(s)
 
options = {}
optparse = OptionParser.new do|opts|
opts.banner = "Usage: voicesms.rb -n +15554443333[,+15554442222] -m \"Message to send\" [-u Username:Password]"
 
options[:numbers] = NUMBERS
opts.on( '-n', '--numbers NUM[,NUM]', 'Phone numbers to SMS (separate multiples with comma)' ) do|numbers|
options[:numbers] = numbers.split(',')
end
 
options[:message] = false
opts.on( '-m', '--message MESSAGE', 'Message to send' ) do|msg|
options[:message] = msg
end
options[:username] = ACCOUNT
options[:password] = PASSWORD
opts.on( '-u', '--user USERNAME:PASSWORD', 'Google Voice username and password' ) do|creds|
parts = creds.split(':')
options[:username] = parts[0]
options[:password] = parts[1]
end
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit
end
end
 
optparse.parse!
 
unless options[:message]
puts "Message required. Use -m \"MESSAGE\"."
puts "Enter `voicesms.rb -h` for help."
exit
end
 
def postit(uri_str, data, header = nil, limit = 3)
raise ArgumentError, 'HTTP redirect too deep' if limit == 0
url = URI.parse(uri_str)
http = Net::HTTP.new(url.host,443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response,content = http.post(url.path,data,header)
case response
when Net::HTTPSuccess then content
when Net::HTTPRedirection then postit(response['location'],data,header, limit - 1)
else
puts response.inspect
response.error!
end
end
 
def getit(uri_str, header, limit = 3)
raise ArgumentError, 'HTTP redirect too deep' if limit == 0
url = URI.parse(uri_str)
http = Net::HTTP.new(url.host,url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response,content = http.get(url.path,header)
case response
when Net::HTTPSuccess then content
when Net::HTTPRedirection then getit(response['location'],header, limit - 1)
else
response.error!
end
end
 
data = "accountType=GOOGLE&Email=#{options[:username]}&Passwd=#{options[:password]}&service=grandcentral&source=brettterpstra-CLISMS-2.0"
res = postit('https://www.google.com/accounts/ClientLogin',data)
if res
authcode = res.match(/Auth=(.+)/)[1]
header = {'Authorization' => "GoogleLogin auth=#{authcode.strip}",'Content-Length' => '0'}
newres = getit('https://www.google.com/voice',header)
if newres
#rnrse = newres.match(/'_rnr_se': '([^']+)'/)[1]
rnrse = CGI.escape(newres.match(/'_rnr_se': '([^']+)'/)[1])
options[:numbers].each {|num|
data = "_rnr_se=#{rnrse}&phoneNumber=#{num.strip}&text=#{CGI.escape(options[:message])}&id="
finalres = postit('https://www.google.com/voice/sms/send/',data,header)
if finalres["ok"]
puts "Message sent to #{num}"
else
puts "Error sending to #{num}"
end
}
else
newres.error!
end
else
res.error!
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.