Skip to content

Instantly share code, notes, and snippets.

@dsanson
Created September 8, 2011 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsanson/1204446 to your computer and use it in GitHub Desktop.
Save dsanson/1204446 to your computer and use it in GitHub Desktop.
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/
#!/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
@dsanson
Copy link
Author

dsanson commented Sep 8, 2011

@MtnBiker
Copy link

2014
Getting an error:
versions/2.1.0/lib/ruby/2.1.0/net/http/response.rb:119:in error!': 403 "Forbidden" (Net::HTTPServerException) from voicesms.y.rb:65:inpostit'
from voicesms.y.rb:85:in `

'

I added three lines above this, so 85 is

res = postit('https://www.google.com/accounts/ClientLogin',data)

Presumably Google has made it more difficult/impossible to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment