I am using twillio api to send sms from my application . Its working fine . But I need to send the verification code as sms to verify his phone number and then need to submit registration from in my rails project.
Can any one please provide the sample example using twilio to verify the code.
Thanks
Here is an example of Twilio
require 'rubygems'
require 'twilio-ruby'
account_sid = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
auth_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
client = Twilio::REST::Client.new account_sid, auth_token
from = '+441702806101' # Your Twilio number
friends = {
'+447908232434' => 'David'
}
friends.each do |key, value|
client.account.sms.messages.create(
:from => from,
:to => key,
:body => "#{value} you are working 30/04/2013 - CX1"
)
puts "Sent message to #{value}"
end
See a code complete tutorial in Ruby:
https://www.twilio.com/docs/tutorials/walkthrough/account-verification/ruby/rails
Hope this helps
Related
So MS disabled IMAP for basic auth as we all know.
I am trying to figure out how to get the OAUTH 2.0 working using ruby (not ruby on rails).
I have Azure APP and everything needed (I think), but I can not find any code related to ruby and getting the access token.
First step is completed, but next step is to get the access token.
https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth
I need to read different Outlook mailboxes.
Could someone please explain how to do this?
SOLUTION for me!
Steps I took.
Made an Azure app ('Device Flow' was the easiest way to go for me) Check the Steps in the link. You also need to change some settings in your APP if you want to use IMAP. See the youtube link here between 2:50 - 4:30
Get the postman requests from this link (scroll down a little) (click here)
From postman you can use "Device Flow" requests.
Start with Device Authorization Request (you need a scope and client_id for this) I used https://outlook.office.com/IMAP.AccessAsUser.All scope.
go to the link that you got back from the request and enter the required code.
now go to Device Access Token Request and use the "device_code" from the last request and put that under code, under body.
You should get an access_token
Connect using ruby
require 'gmail_xoauth' # MUST HAVE! otherwise XOAUTH2 auth wont work
require 'net/imap'
imap = Net::IMAP.new(HOST, PORT, true)
access_token = "XXXXX"
user_name = "email#outlook.com"
p imap.authenticate('XOAUTH2',"#{user_name}", "#{access_token}")
# example
imap.list('','*').each do |folders|
p folders
end
XOAUTH2 Returns
#<struct Net::IMAP::TaggedResponse tag="RUBY0001", name="OK", data=#<struct Net::IMAP::ResponseText code=nil, text="AUTHENTICATE completed.">, raw_data="RUBY0001 OK AUTHENTICATE completed.\r\n
Just to specify
HOST = 'outlook.office365.com'
PORT = 993
UPDATE 25.01.2023
class Oauth2
require 'selenium-webdriver'
require 'webdrivers'
require 'net/http'
# Use: Oauth2.new.get_access_code
# Grants access to Office 365 emails.
def get_access_code
p "### Access Request Started #{Time.now} ###"
begin
codes = device_auth_request
authorize_device_code(codes[:user_code])
access_code = device_access_token(codes[:device_code])
access_code
rescue => e
p e
p "Something went wrong with authorizing"
end
end
def device_auth_request # Returns user_code and device_code
url = URI('https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode')
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request.body = "client_id=YOUR_CLIENT_ID&scope=%09https%3A%2F%2Foutlook.office.com%2FIMAP.AccessAsUser.All"
response = https.request(request)
{
user_code: JSON.parse(response.read_body)["user_code"],
device_code: JSON.parse(response.read_body)["device_code"]
}
end
def device_access_token(device_code)
url = URI('https://login.microsoftonline.com/organizations/oauth2/v2.0/token')
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request.body = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&code=#{device_code}&client_id=YOUR_CLIENT_ID"
response = https.request(request)
JSON.parse(response.read_body)["access_token"]
end
def authorize_device_code(device_code)
# SELENIUM SETUP
driver = setup_selenium
driver.get "https://microsoft.com/devicelogin"
sleep(4)
# ------------------------------------------
# Give Access
element = driver.find_element(:class, "form-control")
element.send_keys(device_code)
sleep(2)
element = driver.find_element(:id, "idSIButton9")
element.submit
sleep(2)
element = driver.find_element(:id, "i0116")
element.send_keys("YOUR OUTLOOK ACCOUNT EMAIL")
sleep(2)
element = driver.find_element(:class, "button_primary")
element.click
sleep(2)
element = driver.find_element(:id, "i0118")
element.send_keys("YOUR OUTLOOK PASSWORD")
element = driver.find_element(:class, "button_primary")
element.click
sleep(2)
element = driver.find_element(:class, "button_primary")
element.click
sleep(2)
# ------------------------------------------
driver.quit
end
def setup_selenium
require 'selenium-webdriver'
# set up Selenium
options = Selenium::WebDriver::Chrome::Options.new(
prefs: {
download: {
prompt_for_download: false
},
plugins: {
'always_open_pdf_externally' => true
}
}
)
options.add_argument('--headless')
options.add_argument('--no-sandbox')
# options.add_argument('-incognito')
options.add_argument('disable-popup-blocking')
Selenium::WebDriver.for :chrome, options: options
end
end
I am working on a project that returns SMS messages to a user who has just sent a SMS message to the server.
The process is:
The user sends a SMS message to the server.
The server will send two SMS messages back to this user. Note that these are two separate short messages and will be sent pretty much at the same time.
I've got the sending part working, but just for sending one SMS message, not two. When I add more code to send another message only the second message part works, which means only the second message has been sent out, the first message has been ignored.
The code looks pretty much like:
else
sms = SMS.create(:body => params['Body'], :from => params['From'], :to => params['To'], :created_at => Time.now)
#return a random saved sms
return_secret = SMS.first(:offset => rand(SMS.count))
twiml = Twilio::TwiML::Response.new do |r|
r.Sms return_secret.body
#send another message to remind user for rating
ask_rating = remind_rating
if ask_rating
twiml = Twilio::TwiML::Response.new do |r|
r.Sms ask_rating
end
twiml.text
end
Does anyone know how to send two messages in Twilio?
You've got some variable shadowing going on with twiml. As you wrote it, the second message's code is inside of the first message's block. Yet, you refer to a variable with the same name as one outside of the block. I would try flattening your code so you aren't nesting like that.
I think the issue here is you're instantiating a second TwiML::Response object when you already have one, so you can just references the previous one which you assigned to r in the first block. You also called it r in the second block so you just remove the block that encloses it:
sms = SMS.create(:body => params['Body'], :from => params['From'], :to => params['To'], :created_at => Time.now)
#return a random saved sms
return_secret = SMS.first(:offset => rand(SMS.count))
twiml = Twilio::TwiML::Response.new do |r|
r.Sms return_secret.body
#send another message to remind user for rating
ask_rating = remind_rating
if ask_rating
r.Sms ask_rating
end
end
Also the blocks weren't balanced in the initial code snippet so I stripped out the else to make it syntactically accurate.
Thank you all, really appreciate your replies.
After consulting with twilio team, they gave me an example like this:
require 'rubygems'
require 'twilio-ruby'
require 'sinatra'
get '/sms-quickstart' do
twiml = Twilio::TwiML::Response.new do |r|
r.Message "Hey Monkey. Thanks for the message!"
r.Message "this is the 2nd message"
end
twiml.text
end
I just deleted
if ask_rating
twiml = Twilio::TwiML::Response.new do |r|
everything works...
I'm having an issue using the mandrill API for ruby and i'm not sure if it's a lack of ruby/api understanding on my part of if there's an issue with the mandrill api.
I have this method which sends an email with mandrill, and then I make another api call using the id returned from mandrill.messages.send to make another call to mandrill to get the email header message-id so i can store that in a db table.
Why am I getting the error Mandrill::UnknownMessageError (No message exists with the id '64fba1cce24942dea1ada4f905fd7871'): when the id clearly exists as seen in the comments for the logging events?
# Sends an email to all users for the account_id on the issue
def send_email
require 'mandrill'
...
mandrill = Mandrill::API.new Mandrill::API_KEY
# Email contents
message = {
:subject => self.name,
:from_name => self.account.subdomain,
:text => self.description,
:to => [{
:email => user.email,
:name => user.name
}],
:text => self.description,
:from_email => "noreply#myapp.com",
:headers => {
'reply-to' => 'update#myapp.com'
}
}
results = mandrill.messages.send message # Send email through mandrill
# Loop through results of sent email
results.each do |result|
logger.debug "result id = #{result['_id']}" # LOGS result id = 64fba1cce24942dea1ada4f905fd7871
logger.debug "result = #{result}" # LOGS result = {"email"=>"tomcaflisch#gmail.com", "status"=>"sent", "_id"=>"64fba1cce24942dea1ada4f905fd7871", "reject_reason"=>nil}
id = result['_id'] # Mandrill's internal id from api call results that sent the email
# CAUSES Mandrill::UnknownMessageError (No message exists with the id '64fba1cce24942dea1ada4f905fd7871'):
info = mandrill.messages.content id # Get info for sent email with a specific mandrill id
end
end
I think you just have to give it a little bit of time.
I am facing the same error on messages.info(id).
However, search('*') is finding all messages sent but not providing correct status information.
I think the following snippet of gem code is getting 500 status (instead of 200) when messages.info(id) is called:
def call(url, params={})
params[:key] = #apikey
params = JSON.generate(params)
r = #session.post(:path => "#{#path}#{url}.json", :headers => {'Content-Type' => 'application/json'}, :body => params)
cast_error(r.body) if r.status != 200
return JSON.parse(r.body)
end
Also, gem code is hosted on bitbucket instead of more common github. Not sure how to raise an issue there for support.
Sorry can't be of much help but thought I should share my experience also to get more visibility for the problem.
I would like to do the following:
Call my twilio number from my cell phone
My twilio number identifies the incoming number then immediately hangs up
My twilio number calls back the identified number (my cell phone number)
When I pick up, twilio asks me to enter the number I wish to call
Twilio gathers the input of the number I want to call and connects me.
So I can make cheap international calls (or roaming calls) from my cell phone.
So far, taken from the twilio website api docs, I have:
require 'rubygems'
require 'sinatra'
require 'twilio-ruby'
get '/' do
account_sid = 'xxxxxxx'
auth_token = 'zzzzzzz'
to = params['From']
#to = '+447928344246'
#to = '441903773807'
from = '442033222327'
Twilio::TwiML::Response.new do |r|
r.Hangup
end.text
# set up a client to talk to the Twilio REST API
#client = Twilio::REST::Client.new account_sid, auth_token
#call = #client.account.calls.create(
:from => from, # From your Twilio number
:to => to, # To any number
:timeout => "20",
# Fetch instructions from this URL when the call connects
:url => 'https://dl.dropboxusercontent.com/u/85088004/twilio/twilio.xml'
)
end
post '/makecall' do
warn params.inspect
account_sid = ' ACaf2b951ae6f7424da036ea9dcd5b0d91'
auth_token = 'my token'
#client = Twilio::REST::Client.new account_sid, auth_token
call = #client.account.calls.create(:url => "https://dl.dropboxusercontent.com/u/85088004/twilio/callback.xml",
:to => params[:Digits],
:from => "+442033222327")
puts call.to
end
The twilio.xml, in the '/' section url file is:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather action="/makecall" method="POST">
<Say timeout="10">Enter the number you wish to call</Say>
</Gather>
</Response>
I get "Sorry an application error has occurred." Then it just hangs up.
warn params.inspect
does not produce anything when I inspect the heroku logs. So I think (one of) the problem(s) is that the params of the number I am dialling is not passed.
Is there any other problem with logic or scripting that seems obvious?
Does the problem lie with the url in the '/makecall' snippet? It si:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
</Hangup>
</Response>
Many, many thanks!
SOLVED!! Thank you for help from the T evangelist. Here is the solution:
require 'rubygems'
require 'sinatra'
require 'twilio-ruby'
account_sid = 'my sid'
auth_token = 'my token'
get '/' do
from = 'my T number'
to = params[:From]
Twilio::TwiML::Response.new do |r|
r.Hangup
end.text
sleep 10
# set up a client to talk to the Twilio REST API
#client = Twilio::REST::Client.new account_sid, auth_token
#call = #client.account.calls.create(
:from => from, # From your Twilio number
:to => to, # To any number
# Fetch instructions from this URL when the call connects
:url => 'https://dl.dropboxusercontent.com/u/85088004/twilio/twilio.xml'
)
end
# the xml file. It is VERY IMPORTANT that you have the absolute url in the action=""
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather timeout="20" action="http://dry-journey-9071.herokuapp.com/makecall" method="GET">
<Say voice="alice">Enter the destination number, please.</Say>
</Gather>
<Say voice="alice">Input not received. Thank you</Say>
</Response>
#Back to the app:
get '/makecall' do
number = params[:Digits]
Twilio::TwiML::Response.new do |r|
r.Dial number ### Connect the caller to Koko, or your cell
r.Say 'The call failed or the remote party hung up. Goodbye.'
end.text
end
Yay!
Twilio Developer Evangelist here.
When you detect that it is your own number, you want to return some TwiML (XML) to Twilio, this should suffice: <Response> <Hangup/> </Response>
You would then need to make a REST API call to Twilio to make a new outbound call to yourself:
#client.account.calls.create(to: my_number, from: "+sometiwilionumber", url: "http://example.com/make-other-call-twiml")
Then use the URL of some TwiML to <Gather> the number you want to dial, and simply <Dial> to that number...
The thing you want to avoid is having Twilio call you back before the first call ends. As you will need to make the API call first, we need to use threading to get around it. I'm not bad with Ruby/Sinatra, but I'm no expert with threading here, but this should work:
twilio_call_thread = Thread.new{
sleep 3 #3 Seconds should be plenty, but you may want to experiment.
#client.account.calls.create(to: mynumber, from: some_twilio_number, url: "http://example.com/gather-and-dial")
}
#Then return the TwiML to hangup...
"<Response><Hangup/></Response>"
You call your number, it creates a thread, then goes to sleep. It responds with a <Hangup> to disconnect the call. A few seconds later, the thread wakes up and you'll get the return call. You will need some TwiML on that call to do a <Gather> to get the phone number to dial, and then <Dial> to make the actual call.
I wasn't sure about the threading, so before checking on that, I had two other ideas you could use:
Use SMS. Send you Twilio number the other number you want to dial, and just have Twilio make the call directly between your number, and the other number.
Secondly, just use a URL, presuming you have data on your phone you can just open a URL which does the same without the initial call or SMS.
Oh - and a third option, if you don't want to muck about with threads, or that's not working for you: set the Status Callback URL on your Twilio number (click 'Optional Voice Settings'). This is fired after the call completes, and from there you can make the new call to yourself.
Hope you get it sorted, it's going to be awesome.
Hi all I am trying to get my rails app to talk to Windows LIVE (through OAuth Wrap) so I can retrieve a list of contacts. I am using the rest_client gem to do this. Here is the action code for it:
def hotmail
app_id = 'some_id'
app_sec = 'some_secret'
app_callback = 'http://my.callback.com/same/as/getting/verification_code'
app_var = params[:wrap_verification_code]
encoded = "wrap_client_id=#{app_id}&wrap_client_secret=#{app_sec}&wrap_verification_code=#{app_var}&wrap_callback=#{app_callback}".encode!('UTF-8')
begin
r = RestClient.post("https://consent.live.com/AccessToken.aspx", encoded.bytes.to_a, {:content_type => 'application/x-www-form-urlencoded', :content_length => encoded.bytesize})
rescue => e
puts e.message
end
render :text => 'hello'
end
I base this on a c# example http://msdn.microsoft.com/en-us/library/ff750952.aspx (note: http://www.goatly.net/2010/12/23/401-unauthorized-when-acquiring-an-access-token-windows-live-sdk.aspx shows the correct payload)
However I keep getting 401 Unauthorized, so I am thinking is the way I am using rest_client incorrectly? During a form post is there somthing else I need to do?
ANy hints will be really helpful :) thanks in advance.
Found the problem. The C# code says it post the byte array but thats not true just post the encoded st direct is enough.