Gmail: Ruby gem google-api-client broken? - google-api

Nobody has encountered this?
I can get the email message object (Google::Apis::GmailV1::Message) but other Message attributes just returns Nil. Only id, thread_id seems to be returned.
SCOPE = Google::Apis::GmailV1::AUTH_GMAIL_MODIFY
service = Google::Apis::GmailV1::GmailService.new
service.client_options.application_name = APPLICATION_NAME
service.authorization = authorize
user_msgs = service.list_user_messages('me',
{:include_spam_trash => false, :label_ids => ['INBOX'], :q => "is:unread"})
user_msgs.messages.each do |msg|
puts "CLASS: #{msg.class}" # Google::Apis::GmailV1::Message
puts "MESSAGE ID: #{msg.id}" # WORKS I get the email ID
msg_part = msg.payload
puts "MSGPART: #{msg_part.class}" # NIL !!!, All other attributes are also NIL
end
So basically I do get the email with the correct ID, but that's about it, all methods or attributes of the GmailV1::Message class is Nil. I also tried changing the SCOPE to MODIFY and same result.
Attributes that just returns Nil:
internal_date label_ids payload raw size_estimate snippet
Also noticed that github project linked in their documentation opens a 404 page on some.

Might be due to Google now forcing developers to have publicly available apps reviewed first: https://developers.google.com/gmail/api/auth/about-auth (see the notification in the blue box with the star)

Related

Creating a Ruby API

I have been tasked with creating a Ruby API that retrieves youtube URL's. However, I am not sure of the proper way to create an 'API'... I did the following code below as a Sinatra server that serves up JSON, but what exactly would be the definition of an API and would this qualify as one? If this is not an API, how can I make in an API? Thanks in advance.
require 'open-uri'
require 'json'
require 'sinatra'
# get user input
puts "Please enter a search (seperate words by commas):"
search_input = gets.chomp
puts
puts "Performing search on YOUTUBE ... go to '/videos' API endpoint to see the results and use the output"
puts
# define query parameters
api_key = 'my_key_here'
search_url = 'https://www.googleapis.com/youtube/v3/search'
params = {
part: 'snippet',
q: search_input,
type: 'video',
videoCaption: 'closedCaption',
key: api_key
}
# use search_url and query parameters to construct a url, then open and parse the result
uri = URI.parse(search_url)
uri.query = URI.encode_www_form(params)
result = JSON.parse(open(uri).read)
# class to define attributes of each video and format into eventual json
class Video
attr_accessor :title, :description, :url
def initialize
#title = nil
#description = nil
#url = nil
end
def to_hash
{
'title' => #title,
'description' => #description,
'url' => #url
}
end
def to_json
self.to_hash.to_json
end
end
# create an array with top 3 search results
results_array = []
result["items"].take(3).each do |video|
#video = Video.new
#video.title = video["snippet"]["title"]
#video.description = video["snippet"]["description"]
#video.url = video["snippet"]["thumbnails"]["default"]["url"]
results_array << #video.to_json.gsub!(/\"/, '\'')
end
# define the API endpoint
get '/videos' do
results_array.to_json
end
An "API = Application Program Interface" is, simply, something that another program can reliably use to get a job done, without having to busy its little head about exactly how the job is done.
Perhaps the simplest thing to do now, if possible, is to go back to the person who "tasked" you with this task, and to ask him/her, "well, what do you have in mind?" The best API that you can design, in this case, will be the one that is most convenient for the people (who are writing the programs which ...) will actually have to use it. "Don't guess. Ask!"
A very common strategy for an API, in a language like Ruby, is to define a class which represents "this application's connection to this service." Anyone who wants to use the API does so by calling some function which will return a new instance of this class. Thereafter, the program uses this object to issue and handle requests.
The requests, also, are objects. To issue a request, you first ask the API-connection object to give you a new request-object. You then fill-out the request with whatever particulars, then tell the request object to "go!" At some point in the future, and by some appropriate means (such as a callback ...) the request-object informs you that it succeeded or that it failed.
"A whole lot of voodoo-magic might have taken place," between the request object and the connection object which spawned it, but the client does not have to care. And that, most of all, is the objective of any API. "It Just Works.™"
I think they want you to create a third-party library. Imagine you are schizophrenic for a while.
Joe wants to build a Sinatra application to list some YouTube videos, but he is lazy and he does not want to do the dirty work, he just wants to drop something in, give it some credentials, ask for urls and use them, finito.
Joe asks Bob to implement it for him and he gives him his requirements: "Bob, I need YouTube library. I need it to do:"
# Please note that I don't know how YouTube API works, just guessing.
client = YouTube.new(api_key: 'hola')
video_urls = client.videos # => ['https://...', 'https://...', ...]
And Bob says "OK." end spends a day in his interactive console.
So first, you should figure out how you are going to use your not-yet-existing lib, if you can – sometimes you just don't know yet.
Next, build that library based on the requirements, then drop it in your Sinatra app and you're done. Does that help?

Mandrill - No message exists with id

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.

undefined method error on local server where method works on live server-Why is the new code breaking it?

I'm trying to integrate our app with MailChimp, so that new users get added to our mailing list and new paid subscribers get updated on the mailing list as paid subscribers (we have a MERGE VARS for that). In order to test that the list is updating properly when the customer pays for a subscription, I'm trying to run the code with the test server for Stripe. (I inherited the code after we had tested it, so I haven't done this before.)
I'm running into an undefined method error, and I can't figure out where it's coming from, since it is working just fine on the live site, and I haven't changed that part of the code.
in the initializer file stripe.rb, I changed Stripe.api_key
="the live secret key" to the test secret key, just subbing in the other key.
I did the same in our layout/application.html.erb file (where we put the initial call to Stripe per Stripe's instructions), swapping out the public live key for the public test key.
In the account_controller processing method (which is called for payment processing on the Stripe token and updating our server with the type of subscription.):
def processing
begin
if params[:coupon][0] != "_"
#coupon = params[:coupon]
else
#coupon = nil
end
customer = Stripe::Customer.create(
:email => current_user.email,
:card => params[:stripeToken],
:plan => params[:plan],
:coupon => #coupon
)
current_user.subscription = params[:plan]
current_user.stripe_id = customer.id
current_user.canceled = false
current_user.save!
rescue Stripe::CardError => e
flash[:error] = e.message
end
#only this code is new, from here:
#for gibbon updating subscription status
gb=Gibbon::API.new
email=current_user.email
subscription=user.subscription
updated_date=user.updated_at.strftime('%B %d, %Y')
gb.lists.subscribe({:id => "our list id", :email => {:email => "#{email}"}, :merge_vars => {:SUB => "test", :UPDATE => "#{updated_date}"}, :update_existing=>true , :double_optin => false, :send_welcome=> false})
#to here is new code
current_user
respond_to do |format|
format.html { redirect_to account_confirmation_path }
end
end
I'm getting a "NoMethodError in AccountController#processing
undefined method 'canceled=' for #User:an-id-here" (note the #User: an id here is in pointy brackets, but those aren't showing up here.)
error. This code works on the live site, so that makes me think it must be something I've done here. Canceled is a column on our User model, which is a boolean indicating whether they've canceled. It is not set as attr_accesible or attr_accessor, but as I said, that code hasn't changed and works on the live site.
I'm not sure what the problem is and I feel like I don't have enough information to start figuring it out. The server is only recording the same error message as shows up in the browser. (Oh, and I'm running the test code only on my local server, not the live server).
What might be causing the undefined method error? I'm not seeing anything in the code I changed that should do it.

Ruby Viewpoint Gem 1.27

I'm trying to send a message with the Viewpoint Ruby Gem to an EWS endpoint. I am only able to send the message in plain text format. How can I send it in html format?
Here is the code:
Viewpoint::EWS::EWS.endpoint=Conf.application.email.ews.endpoint
Viewpoint::EWS::EWS.set_auth(Conf.application.email.ews.username,Conf.application.email.ews.password)
Viewpoint::EWS::Message.send(options[:subject],msg_str,to_addresses)
I see that there is a text_only "instance" method, but am not able to initialize an instance of a message object to use it.
Trick is to set body_type. Note: This example is derived from the example at https://github.com/zenchild/Viewpoint based on v1.0beta.
require 'viewpoint'
include Viewpoint::EWS
endpoint = 'https://example.com/ews/Exchange.asmx'
user = 'username'
pass = 'password'
cli = Viewpoint::EWSClient.new endpoint, user, pass
cli.send_message do |m|
m.subject = "Test"
m.body = "<html><body><strong>Test</strong> message</body></html>"
m.body_type = 'HTML'
m.to_recipients << 'test#example.com'
end

Rally: How do I access custom created fields via the Web Services API

I have read through the Web Services site at http://developer.rallydev.com/help/
The basic issue I have is that I am trying to update custom created fields in Rally from a Ruby script and I do not know the format to use. The Rally Devs said this was possible and directed me to post here as they do not support users with such things.
I am wondering if anyone else has been able to do this. I can get the defect, but the debug info has not given me any clues as to where these custom fields may be lurking. Thanks in advance for your help and please let me know if you need any additional information. The simple code I have right now is this:
#!/usr/bin/ruby
require 'rubygems'
require 'rally_rest_api'
defect = "DE677"
logger = Logger.new("debug-rally.txt")
logger.level = Logger::DEBUG
rally = RallyRestAPI.new(:username => "hidden",
:password => "hidden",
:logger => logger,
:version => 1.34)
result = rally.find(:defect) { equal :formattedid, defect }
if result.page_length == 0
puts "The defect "+defect+" was not found"
elsif result.page_length == 1
puts "Found it"
res_array = result.results
thedefect = res_array.at(0)
puts thedefect.state
puts thedefect.requirement.defects
else
puts "Returned more than one result"
puts result.page_length
res_array = result.results
for i in res_array
puts i
end
end
EDIT:It was actually staring me right in the face. When I checked the debug log again they were in the xml. For instance in the UI there was a custom field called fu and in the resulting xml it was there as bar.
There is a display name and a name property when you create it. In your example my guess is fu is your display name and bar is the name.

Resources