How to geocode a Twitter status update using the Ruby OAuth Gem - ruby

Using the following Ruby code, I can send a status update over the Twitter API to my account. According to the Twitter API Docs I would expect it to be geocoded, but it isn't. What am I doing wrong?
require 'oauth'
consumer = OAuth::Consumer.new('<MY_CONSUMER_KEY>', '<MY_CONSUMER_SECRET>', :site => "http://api.twitter.com", :scheme => :header)
access_token = OAuth::AccessToken.from_hash(consumer, :oauth_token => '<MY_OAUTH_TOKEN>', :oauth_token_secret => '<MY_OAUTH_SECRET>')
access_token.request(:post, "http://api.twitter.com/1/statuses/update.xml", {"Content-Type" => "application/xml", "status" => "This Tweet is from Zuerich in Switzerland", "lat" => "47.3807", "long" => "8.537", "display_coordinates" => "true", "geo_enabled" => "true"})

It works ok. You should enable "Add a location to your tweets" in your twitter profile settings.

Related

Connect to a SOAP API with savon and specify Domain

With SoapUI, I am successfully connecting to a SOAP API with details such as:
Initial WSDL: http://11.11.1.11:7303/FOO/BAR/BAZ
Username: foo
Password: bar
Domain: example
But I am not sure how to do this with Savon. I am trying this (not quite understanding if ntlm is the correct setting here):
savon_defaults = {
:wsdl => "http://11.11.1.11:7303/FOO/BAR/BAZ",
:ntlm => ["foo", "bar", "example"],
:log_level => :debug,
:pretty_print_xml => true,
:log => true
}
#client = Savon.client(savon_defaults)
#client.call(:foo, :message => {:bar => "baz"})
The above outputs:
D, [2020-05-18T21:21:14.853929 #7156] DEBUG -- : HTTPI /peer GET request to 11.11.1.11 (httpclient)
Savon::HTTPError: HTTP error (401)
Any ideas?

Sending email from simple Sinatra app using Pony

I am building my first portfolio page with Sinatra.
I have a 'textbook' contact page with a straight-forward form containing 'name', 'email' and 'content' fields. When someone submits the form, I want to recieve an email notification.
Pony claims that it can send email via simple 'one-line' of code. I have read the Pony documentation but it is not very detailed in how to set it up.
I don't know if I am not setting it up properly, the code is not right, Pony is not the best tool, or if my development environment is not allowing the mail to be sent.
The code below is supposed to be sending an email from the post method, it is then saving the data to a PostgreSQL database via the save_message method. The data is being persisted correctly.
#server.rb
require 'sinatra'
require 'pony'
require_relative 'model/methods'
get '/contact' do
erb :contact
end
post '/thankyou' do
unless params[:name] == '' || params[:email] == '' || params[:content] == ''
Pony.options = {
:subject => "Portfolio page: Message delivery from #{params[:name]}",
:body => "#{params[:content]}",
:via => :smtp,
:via_options => {
:address => 'smtp.1and1.com',
:port => '587',
:enable_starttls_auto => true,
:user_name => ENV["USER_EMAIL_ADDRESS"],
:password => ENV["SMTP_PASSWORD"],
:authentication => :login,
:domain => 'nterrafranca.com'
}
}
Pony.mail(:to => ENV["DESTINATION_EMAIL_ADDRESS"])
save_message(params[:name], params[:email], params[:content])
end
redirect '/'
end
Pony needs to know how to send the email, not just who it's to, from, what the subject and body are, etc.
From the pony documentation, it will default to use sendmail, otherwise configures SMTP to use localhost. Depending on where this application is running, it's highly likely that sendmail is not available, and that there is no SMTP configured on localhost.
I've used Pony for several applications. Each one, I configure a "noreply#" email address for Pony to use to authenticate for SMTP, therefore using my own domain email (usually Google Apps, or even Gmail) for my SMTP connection. For example:
Pony.options = {
:subject => "Some Subject",
:body => "This is the body.",
:via => :smtp,
:via_options => {
:address => 'smtp.gmail.com',
:port => '587',
:enable_starttls_auto => true,
:user_name => 'noreply#cdubs-awesome-domain.com',
:password => ENV["SMTP_PASSWORD"],
:authentication => :plain, # :plain, :login, :cram_md5, no auth by default
:domain => "localhost.localdomain"
}
}
In the case of a Sinatra app, I perform the exact above code (with the obvious substitutions) right before I call:
Pony.mail(:to => <some_email>)
I've configured Pony multiple times - comment if you still have issues and I'll be glad to help.
If you are using a gmail account with 2-step verification, you must generate an application specific password for the Pony mailer, and NOT use your usual SMTP password.
See https://support.google.com/accounts/answer/185833?hl=en
Insert the application specific password in the place of your usual password.
This is from the Pony project page on Github.

Google Apps Groups Settings API :: 500 Backend Error

Whenever I attempt to access the groups from our Google Apps instance, I get the following response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "backendError",
"message": "Backend Error"
}
],
"code": 500,
"message": "Backend Error"
}
}
The code I am using is below:
begin
require 'google/api_client'
rescue LoadError
puts "You need the google-api-ruby-client gem..."
puts "$ gem install google-api-client"
exit 1
end
client = Google::APIClient.new(application_name: "Group Modifier")
## Use key to authenticate and generate token
key = Google::APIClient::PKCS12.load_key("#{File.dirname(__FILE__)}/mykey.p12", 'notasecret')
service_account = Google::APIClient::JWTAsserter.new(
'mydeveloperid#developer.gserviceaccount.com',
'https://www.googleapis.com/auth/apps.groups.settings',
key)
client.authorization = service_account.authorize
groupssettings = client.discovered_api('groupssettings', 'v1')
result = client.execute(
:api_method => groupssettings.groups.get,
:parameters => { 'groupUniqueId' => 'mygroup#mydomain.com', 'alt' => 'json' }
)
puts result.body
I've added the correct permissions and all of that in both the "Manage API client access" within the Google Apps Admin Console and within the https://cloud.google.com/console.
I even noticed that when I use the "https://developers.google.com/admin-sdk/groups-settings/v1/reference/groups/get#try-it" it doesn't return anything.
Please help me out
I finally resolved my problem with using some example code from the git repo homepage. This is what I came up with:
begin
require 'google/api_client'
rescue LoadError
puts "You need the google-api-ruby-client gem..."
puts "$ gem install google-api-client"
exit 1
end
client = Google::APIClient.new
key = Google::APIClient::KeyUtils.load_from_pkcs12("#{File.dirname(__FILE__)}/mykey.p12", 'notasecret')
client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => 'https://www.googleapis.com/auth/apps.groups.settings',
:issuer => 'mydeveloperid#developer.gserviceaccount.com',
:person => 'myemail#mydomain.com',
:signing_key => key)
client.authorization.fetch_access_token!
groupssettings = client.discovered_api('groupssettings', 'v1')
result = client.execute(
:api_method => groupssettings.groups.get,
:parameters => { :groupUniqueId => 'mygroup#mydomain.com', :alt => 'json' }
)
puts result.body

How to use google-api-ruby-client with the Google Calendar API?

I've been reading the docs for the Google Calendar API and the google-api-ruby-client library, but I'm having a lot of trouble understanding them.
I have a Rails application that has a front end that lets users create objects called Events, and it saves them in a database on my server. What I would like is, after these Events are saved in the database, I want to call the Google Calendar API to create an event on a Google Calendar (that the server created, and only the server has access to modify that calendar).
I'm having lots of issues figuring out how to authenticate with the API using the ruby library. It doesn't make sense for me to use OAuth2 because I don't need to authorize anything with the user because I'm not interested in their data. I looked into Service Accounts (http://code.google.com/p/google-api-ruby-client/wiki/ServiceAccounts), but it looks like Google Calendars is not supported by Service Accounts.
Anyone have any ideas? This is the code I was experimenting with (using Service Accounts):
#client = Google::APIClient.new(:key => 'my_api_key')
path_to_key_file = '/somepath/aaaaaa-privatekey.p12'
passphrase = 'my_pass_phrase'
key = Google::APIClient::PKCS12.load_key(path_to_key_file, passphrase)
asserter = Google::APIClient::JWTAsserter.new(
'blah_blah#developer.gserviceaccount.com',
'https://www.googleapis.com/auth/calendar',
key)
# To request an access token, call authorize:
#client.authorization = asserter.authorize()
calendar = #client.discovered_api('calendar', 'v3')
event = {
'summary' => 'Appointment',
'location' => 'Somewhere',
'start' => {
'dateTime' => '2012-06-03T10:00:00.000-07:00'
},
'end' => {
'dateTime' => '2012-06-03T10:25:00.000-07:00'
},
'attendees' => [
{
'email' => 'attendeeEmail'
},
#...
]
}
result = #client.execute!(:api_method => calendar.events.insert,
:parameters => {'calendarId' => 'primary'},
:body => JSON.dump(event),
:headers => {'Content-Type' => 'application/json'})
Then of course I get this error message: Google::APIClient::ClientError (The user must be signed up for Google Calendar.) because the Service Account does not support Google Calendars.
I think you'll still need a real google user to host the calendar instance. But once you've got the calendar created under your identity, you can share it with the service account. In the sharing settings for the calendar, just use the email address of the service account (my service account ends with #developer.gserviceaccount.com). With the right sharing permissions, your service account can create/alter the event info, and not mess with your specific identity. From there, you can share the calendar with more people (or public) for their consumption of the mirrored events.
The other hitch I've run into is that it seems you can only authorize() the service account once per expiration period. You'll have to save the token you get and reuse it for the next hour, and then fetch a new one.
I don't know anything about Ruby. But it seems like understanding the underlying REST queries would help debug your problem. I've documented them here: http://www.tqis.com/eloquency/googlecalendar.htm
I was having trouble with this too and finally got a handle on it. The bottom line is that Google Calendar API v3 requires OAuth and you need to setup an App/Project through the Google Developer Console and then request OAuth permission on the target Google account. Once authorization is granted, you'll want to save the refresh token and use it on subsequent calls to get new access tokens (which expire!). I wrote a detailed blog post about this here: http://www.geekytidbits.com/google-calendar-api-from-ruby/ and this is my example script that should hopefully help you understand the flow:
#gem install 'google-api-client'
require 'google/api_client'
#Setup auth client
client_secrets = Google::APIClient::ClientSecrets.load #client_secrets.json must be present in current directory!
auth_client = client_secrets.to_authorization
auth_client.update!(
:scope => 'https://www.googleapis.com/auth/calendar',
:access_type => "offline", #will make refresh_token available
:approval_prompt =>'force',
:redirect_uri => 'http://www.myauthorizedredirecturl.com'
)
refresh_token_available = File.exist?('refresh_token.txt')
if !refresh_token_available
#OAuth URL - this is the url that will prompt a Google Account owner to give access to this app.
puts "Navigate browser to: '#{auth_client.authorization_uri.to_s}' and copy/paste auth code after redirect."
#Once the authorization_uri (above) is followed and authorization is given, a redirect will be made
#to http://www.myauthorizedredirecturl.com (defined above) and include the auth code in the request url.
print "Auth code: "
auth_client.code = gets
else
#If authorization has already been given and refresh token saved previously, simply set the refresh code here.
auth_client.refresh_token = File.read('refresh_token.txt')
end
#Now, get our access token which is what we will need to work with the API.
auth_client.fetch_access_token!
if !refresh_token_available
#Save refresh_token for next time
#Note: auth_client.refresh_token is only available the first time after OAuth permission is granted.
#If you need it again, the Google Account owner would have deauthorize your app and you would have to request access again.
#Therefore, it is important that the refresh token is saved after authenticating the first time!
File.open('refresh_token.txt', 'w') { |file| file.write(auth_client.refresh_token) }
refresh_token_available = true
end
api_client = Google::APIClient.new
cal = api_client.discovered_api('calendar', 'v3')
#Get Event List
puts "Getting list of events..."
list = api_client.execute(:api_method => cal.events.list,
:authorization => auth_client,
:parameters => {
'maxResults' => 20,
'timeMin' => '2014-06-18T03:12:24-00:00',
'q' => 'Meeting',
'calendarId' => 'primary'})
puts "Fetched #{list.data.items.count} events..."
#Update Event
puts "Updating first event from list..."
update_event = list.data.items[0]
update_event.description = "Updated Description here"
result = api_client.execute(:api_method => cal.events.update,
:authorization => auth_client,
:parameters => { 'calendarId' => 'primary', 'eventId' => update_event.id},
:headers => {'Content-Type' => 'application/json'},
:body_object => update_event)
puts "Done with update."
#Add New Event
puts "Inserting new event..."
new_event = cal.events.insert.request_schema.new
new_event.start = { 'date' => '2015-01-01' } #All day event
new_event.end = { 'date' => '2015-01-01' }
new_event.description = "Description here"
new_event.summary = "Summary here"
result = api_client.execute(:api_method => cal.events.insert,
:authorization => auth_client,
:parameters => { 'calendarId' => 'primary'},
:headers => {'Content-Type' => 'application/json'},
:body_object => new_event)
puts "Done with insert."

Twitter + Grackle, determining the logged in user

This is crazy, but I'm stumped! Once my user has logged into twitter via OAuth how do I determine their username using grackle?
#twitter = Grackle::Client.new(:auth => {
:type => :oauth,
:consumer_key => consumer_key,
:consumer_secret => consumer_secret,
:token => #access_token.token,
:token_secret => #access_token.secret
})
username = #twitter.something_here?
Try looking on here:
http://apiwiki.twitter.com/Twitter-REST-API-Method:-account%C2%A0verify_credentials
It tells you how via the main api how to get the current user information. You could look into hooking this up through Grackle.
Joe

Resources