Flickraw & VCR give unexpected results - ruby-on-rails
I´m using VCR to test a method which gets a list of photosets from Flickr
require 'rails_helper'
RSpec.describe Photoset, type: :model do
# ...
describe '.import' do
it "gets photosets" do
VCR.use_cassette('photosets_getList') do
expect(Photoset.import(user_id: ENV['FLICKR_TEST_USER_ID']).first).to be_a Photoset
end
end
it "sets title" do
VCR.use_cassette('photosets_getList') do
expect(Photoset.import(user_id: ENV['FLICKR_TEST_USER_ID']).first.title).to eq 'Showcase'
end
end
it "sets uid" do
VCR.use_cassette('photosets_getList') do
expect(Photoset.import(user_id: ENV['FLICKR_TEST_USER_ID']).first.uid).to eq '72157647753138397'
end
end
end
end
The method itself is pretty straight forward and uses flickraw to get the photos from
flickr.photosets.getList and them maps to Photoset objects.
class Photoset
include Mongoid::Document
include Mongoid::Timestamps
field :title, type: String
field :uid, type: String
validates_uniqueness_of :uid
belongs_to :user
# Get photosets from Flickr
# #param [Hash] opts
# #return [Enumerable]
def self.import(opts = {})
res = flickr.photosets.getList(opts)
res.map do |item|
new(
uid: item["id"],
title: item["title"]
)
end
end
end
However the specs fail intermittently as Flickraw also does a request to flickr.reflection.getMethods and
flickr.photosets.getList(opts).map { |x| x }
Sometimes returns the request methods instead of Photosets
[("flickr.activity.userComments", "flickr.activity.userPhotos", "flickr.auth.checkToken"...]
Am I using VCR wrong or is this a bug in Flickraw?
These are the recorded HTTP interactions:
---
http_interactions:
- request:
method: post
uri: https://api.flickr.com/services/rest/
body:
encoding: US-ASCII
string: method=flickr.reflection.getMethods&format=json&nojsoncallback=1
headers:
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
User-Agent:
- FlickRaw/0.9.8
Content-Type:
- application/x-www-form-urlencoded
response:
status:
code: 200
message: OK
headers:
Date:
- Mon, 30 Mar 2015 14:57:38 GMT
Content-Type:
- application/json
Content-Length:
- '1428'
P3p:
- policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV
TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY
ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV"
Cache-Control:
- private
X-Served-By:
- www235.flickr.bf1.yahoo.com
Vary:
- Accept-Encoding
Age:
- '0'
Via:
- http/1.1 fts124.flickr.bf1.yahoo.com (ApacheTrafficServer/4.0.2 [cMsSf ]),
http/1.1 r05.ycpi.dea.yahoo.net (ApacheTrafficServer [cMsSf ])
Server:
- ATS
Strict-Transport-Security:
- max-age=259200
Connection:
- keep-alive
body:
encoding: UTF-8
string: '{"methods":{"method":[{"_content":"flickr.activity.userComments"},{"_content":"flickr.activity.userPhotos"},{"_content":"flickr.auth.checkToken"},{"_content":"flickr.auth.getFrob"},{"_content":"flickr.auth.getFullToken"},{"_content":"flickr.auth.getToken"},{"_content":"flickr.auth.oauth.checkToken"},{"_content":"flickr.auth.oauth.getAccessToken"},{"_content":"flickr.blogs.getList"},{"_content":"flickr.blogs.getServices"},{"_content":"flickr.blogs.postPhoto"},{"_content":"flickr.cameras.getBrandModels"},{"_content":"flickr.cameras.getBrands"},{"_content":"flickr.collections.getInfo"},{"_content":"flickr.collections.getTree"},{"_content":"flickr.commons.getInstitutions"},{"_content":"flickr.contacts.getList"},{"_content":"flickr.contacts.getListRecentlyUploaded"},{"_content":"flickr.contacts.getPublicList"},{"_content":"flickr.contacts.getTaggingSuggestions"},{"_content":"flickr.favorites.add"},{"_content":"flickr.favorites.getContext"},{"_content":"flickr.favorites.getList"},{"_content":"flickr.favorites.getPublicList"},{"_content":"flickr.favorites.remove"},{"_content":"flickr.galleries.addPhoto"},{"_content":"flickr.galleries.create"},{"_content":"flickr.galleries.editMeta"},{"_content":"flickr.galleries.editPhoto"},{"_content":"flickr.galleries.editPhotos"},{"_content":"flickr.galleries.getInfo"},{"_content":"flickr.galleries.getList"},{"_content":"flickr.galleries.getListForPhoto"},{"_content":"flickr.galleries.getPhotos"},{"_content":"flickr.groups.browse"},{"_content":"flickr.groups.discuss.replies.add"},{"_content":"flickr.groups.discuss.replies.delete"},{"_content":"flickr.groups.discuss.replies.edit"},{"_content":"flickr.groups.discuss.replies.getInfo"},{"_content":"flickr.groups.discuss.replies.getList"},{"_content":"flickr.groups.discuss.topics.add"},{"_content":"flickr.groups.discuss.topics.getInfo"},{"_content":"flickr.groups.discuss.topics.getList"},{"_content":"flickr.groups.getInfo"},{"_content":"flickr.groups.join"},{"_content":"flickr.groups.joinRequest"},{"_content":"flickr.groups.leave"},{"_content":"flickr.groups.members.getList"},{"_content":"flickr.groups.pools.add"},{"_content":"flickr.groups.pools.getContext"},{"_content":"flickr.groups.pools.getGroups"},{"_content":"flickr.groups.pools.getPhotos"},{"_content":"flickr.groups.pools.remove"},{"_content":"flickr.groups.search"},{"_content":"flickr.interestingness.getList"},{"_content":"flickr.machinetags.getNamespaces"},{"_content":"flickr.machinetags.getPairs"},{"_content":"flickr.machinetags.getPredicates"},{"_content":"flickr.machinetags.getRecentValues"},{"_content":"flickr.machinetags.getValues"},{"_content":"flickr.panda.getList"},{"_content":"flickr.panda.getPhotos"},{"_content":"flickr.people.findByEmail"},{"_content":"flickr.people.findByUsername"},{"_content":"flickr.people.getGroups"},{"_content":"flickr.people.getInfo"},{"_content":"flickr.people.getLimits"},{"_content":"flickr.people.getPhotos"},{"_content":"flickr.people.getPhotosOf"},{"_content":"flickr.people.getPublicGroups"},{"_content":"flickr.people.getPublicPhotos"},{"_content":"flickr.people.getUploadStatus"},{"_content":"flickr.photos.addTags"},{"_content":"flickr.photos.comments.addComment"},{"_content":"flickr.photos.comments.deleteComment"},{"_content":"flickr.photos.comments.editComment"},{"_content":"flickr.photos.comments.getList"},{"_content":"flickr.photos.comments.getRecentForContacts"},{"_content":"flickr.photos.delete"},{"_content":"flickr.photos.geo.batchCorrectLocation"},{"_content":"flickr.photos.geo.correctLocation"},{"_content":"flickr.photos.geo.getLocation"},{"_content":"flickr.photos.geo.getPerms"},{"_content":"flickr.photos.geo.photosForLocation"},{"_content":"flickr.photos.geo.removeLocation"},{"_content":"flickr.photos.geo.setContext"},{"_content":"flickr.photos.geo.setLocation"},{"_content":"flickr.photos.geo.setPerms"},{"_content":"flickr.photos.getAllContexts"},{"_content":"flickr.photos.getContactsPhotos"},{"_content":"flickr.photos.getContactsPublicPhotos"},{"_content":"flickr.photos.getContext"},{"_content":"flickr.photos.getCounts"},{"_content":"flickr.photos.getExif"},{"_content":"flickr.photos.getFavorites"},{"_content":"flickr.photos.getInfo"},{"_content":"flickr.photos.getNotInSet"},{"_content":"flickr.photos.getPerms"},{"_content":"flickr.photos.getRecent"},{"_content":"flickr.photos.getSizes"},{"_content":"flickr.photos.getUntagged"},{"_content":"flickr.photos.getWithGeoData"},{"_content":"flickr.photos.getWithoutGeoData"},{"_content":"flickr.photos.licenses.getInfo"},{"_content":"flickr.photos.licenses.setLicense"},{"_content":"flickr.photos.notes.add"},{"_content":"flickr.photos.notes.delete"},{"_content":"flickr.photos.notes.edit"},{"_content":"flickr.photos.people.add"},{"_content":"flickr.photos.people.delete"},{"_content":"flickr.photos.people.deleteCoords"},{"_content":"flickr.photos.people.editCoords"},{"_content":"flickr.photos.people.getList"},{"_content":"flickr.photos.recentlyUpdated"},{"_content":"flickr.photos.removeTag"},{"_content":"flickr.photos.search"},{"_content":"flickr.photos.setContentType"},{"_content":"flickr.photos.setDates"},{"_content":"flickr.photos.setMeta"},{"_content":"flickr.photos.setPerms"},{"_content":"flickr.photos.setSafetyLevel"},{"_content":"flickr.photos.setTags"},{"_content":"flickr.photos.suggestions.approveSuggestion"},{"_content":"flickr.photos.suggestions.getList"},{"_content":"flickr.photos.suggestions.rejectSuggestion"},{"_content":"flickr.photos.suggestions.removeSuggestion"},{"_content":"flickr.photos.suggestions.suggestLocation"},{"_content":"flickr.photos.transform.rotate"},{"_content":"flickr.photos.upload.checkTickets"},{"_content":"flickr.photosets.addPhoto"},{"_content":"flickr.photosets.comments.addComment"},{"_content":"flickr.photosets.comments.deleteComment"},{"_content":"flickr.photosets.comments.editComment"},{"_content":"flickr.photosets.comments.getList"},{"_content":"flickr.photosets.create"},{"_content":"flickr.photosets.delete"},{"_content":"flickr.photosets.editMeta"},{"_content":"flickr.photosets.editPhotos"},{"_content":"flickr.photosets.getContext"},{"_content":"flickr.photosets.getInfo"},{"_content":"flickr.photosets.getList"},{"_content":"flickr.photosets.getPhotos"},{"_content":"flickr.photosets.orderSets"},{"_content":"flickr.photosets.removePhoto"},{"_content":"flickr.photosets.removePhotos"},{"_content":"flickr.photosets.reorderPhotos"},{"_content":"flickr.photosets.setPrimaryPhoto"},{"_content":"flickr.places.find"},{"_content":"flickr.places.findByLatLon"},{"_content":"flickr.places.getChildrenWithPhotosPublic"},{"_content":"flickr.places.getInfo"},{"_content":"flickr.places.getInfoByUrl"},{"_content":"flickr.places.getPlaceTypes"},{"_content":"flickr.places.getShapeHistory"},{"_content":"flickr.places.getTopPlacesList"},{"_content":"flickr.places.placesForBoundingBox"},{"_content":"flickr.places.placesForContacts"},{"_content":"flickr.places.placesForTags"},{"_content":"flickr.places.placesForUser"},{"_content":"flickr.places.resolvePlaceId"},{"_content":"flickr.places.resolvePlaceURL"},{"_content":"flickr.places.tagsForPlace"},{"_content":"flickr.prefs.getContentType"},{"_content":"flickr.prefs.getGeoPerms"},{"_content":"flickr.prefs.getHidden"},{"_content":"flickr.prefs.getPrivacy"},{"_content":"flickr.prefs.getSafetyLevel"},{"_content":"flickr.push.getSubscriptions"},{"_content":"flickr.push.getTopics"},{"_content":"flickr.push.subscribe"},{"_content":"flickr.push.unsubscribe"},{"_content":"flickr.reflection.getMethodInfo"},{"_content":"flickr.reflection.getMethods"},{"_content":"flickr.stats.getCollectionDomains"},{"_content":"flickr.stats.getCollectionReferrers"},{"_content":"flickr.stats.getCollectionStats"},{"_content":"flickr.stats.getCSVFiles"},{"_content":"flickr.stats.getPhotoDomains"},{"_content":"flickr.stats.getPhotoReferrers"},{"_content":"flickr.stats.getPhotosetDomains"},{"_content":"flickr.stats.getPhotosetReferrers"},{"_content":"flickr.stats.getPhotosetStats"},{"_content":"flickr.stats.getPhotoStats"},{"_content":"flickr.stats.getPhotostreamDomains"},{"_content":"flickr.stats.getPhotostreamReferrers"},{"_content":"flickr.stats.getPhotostreamStats"},{"_content":"flickr.stats.getPopularPhotos"},{"_content":"flickr.stats.getTotalViews"},{"_content":"flickr.tags.getClusterPhotos"},{"_content":"flickr.tags.getClusters"},{"_content":"flickr.tags.getHotList"},{"_content":"flickr.tags.getListPhoto"},{"_content":"flickr.tags.getListUser"},{"_content":"flickr.tags.getListUserPopular"},{"_content":"flickr.tags.getListUserRaw"},{"_content":"flickr.tags.getMostFrequentlyUsed"},{"_content":"flickr.tags.getRelated"},{"_content":"flickr.test.echo"},{"_content":"flickr.test.login"},{"_content":"flickr.test.null"},{"_content":"flickr.urls.getGroup"},{"_content":"flickr.urls.getUserPhotos"},{"_content":"flickr.urls.getUserProfile"},{"_content":"flickr.urls.lookupGallery"},{"_content":"flickr.urls.lookupGroup"},{"_content":"flickr.urls.lookupUser"}]},"stat":"ok"}'
http_version:
recorded_at: Mon, 30 Mar 2015 14:57:37 GMT
- request:
method: post
uri: https://api.flickr.com/services/rest/
body:
encoding: US-ASCII
string: user_id=62829091%40N05&method=flickr.photosets.getList&format=json&nojsoncallback=1
headers:
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
User-Agent:
- FlickRaw/0.9.8
Content-Type:
- application/x-www-form-urlencoded
response:
status:
code: 200
message: OK
headers:
Date:
- Mon, 30 Mar 2015 14:57:38 GMT
Content-Type:
- application/json
Content-Length:
- '878'
P3p:
- policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV
TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY
ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV"
Cache-Control:
- private
X-Served-By:
- www35.flickr.bf1.yahoo.com
Vary:
- Accept-Encoding
Age:
- '0'
Via:
- http/1.1 fts109.flickr.bf1.yahoo.com (ApacheTrafficServer/4.0.2 [cMsSf ]),
http/1.1 r14.ycpi.dea.yahoo.net (ApacheTrafficServer [cMsSf ])
Server:
- ATS
Strict-Transport-Security:
- max-age=259200
Connection:
- keep-alive
body:
encoding: UTF-8
string: '{"photosets":{"page":1,"pages":1,"perpage":10,"total":10,"photoset":[{"id":"72157647753138397","primary":"13362508473","secret":"73945d3830","server":"7300","farm":8,"photos":"10","videos":0,"title":{"_content":"Showcase"},"description":{"_content":""},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"0","count_comments":"0","can_comment":0,"date_create":"1411992696","date_update":"1420398843"},{"id":"72157642806447225","primary":"13362324935","secret":"792aed9e58","server":"7072","farm":8,"photos":"11","videos":0,"title":{"_content":"Offpistcamp,
Mars 2014"},"description":{"_content":""},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"18","count_comments":"0","can_comment":0,"date_create":"1395604793","date_update":"1420398843"},{"id":"72157635592985815","primary":"9789159454","secret":"68e3687ebf","server":"7304","farm":8,"photos":"49","videos":0,"title":{"_content":"Sara
& Adam\u00b4s wedding "},"description":{"_content":""},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"36","count_comments":"0","can_comment":0,"date_create":"1379447652","date_update":"1379448808"},{"id":"72157633225753747","primary":"8643524170","secret":"d31134cfac","server":"8387","farm":9,"photos":"11","videos":0,"title":{"_content":"\u00c5re
Park"},"description":{"_content":""},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"0","count_comments":"0","can_comment":0,"date_create":"1365784604","date_update":"1365784720"},{"id":"72157632691639823","primary":"8446828475","secret":"c27f229c79","server":"8079","farm":9,"photos":"5","videos":0,"title":{"_content":"\u00c5resj\u00f6n"},"description":{"_content":""},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"0","count_comments":"0","can_comment":0,"date_create":"1360071999","date_update":"1360072052"},{"id":"72157632228500139","primary":"8266649775","secret":"bea16448f6","server":"8337","farm":9,"photos":"36","videos":0,"title":{"_content":"Renskiljning"},"description":{"_content":""},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"8","count_comments":"0","can_comment":0,"date_create":"1355334260","date_update":"1365536767"},{"id":"72157632141702707","primary":"8234153651","secret":"82b1bababb","server":"8487","farm":9,"photos":"11","videos":0,"title":{"_content":"Ozone
Demodag 2012"},"description":{"_content":""},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"30","count_comments":"0","can_comment":0,"date_create":"1354372862","date_update":"1354373227"},{"id":"72157629510040228","primary":"6956421098","secret":"fe55925613","server":"7197","farm":8,"photos":"14","videos":0,"title":{"_content":"Slutskjutet
p\u00e5 Skutskjutet"},"description":{"_content":""},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"4","count_comments":"0","can_comment":0,"date_create":"1335109758","date_update":"1335109926"},{"id":"72157626719466442","primary":"5719219791","secret":"5966d75b4d","server":"2128","farm":3,"photos":"4","videos":0,"title":{"_content":"Trondheim"},"description":{"_content":""},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"1","count_comments":"0","can_comment":0,"date_create":"1305400311","date_update":"1354372544"},{"id":"72157626594657331","primary":"5719668226","secret":"d5c9c6e1bd","server":"2593","farm":3,"photos":"15","videos":0,"title":{"_content":"Rope
Swing Session"},"description":{"_content":"Oslo, norway"},"needs_interstitial":0,"visibility_can_see_set":1,"count_views":"8","count_comments":"0","can_comment":0,"date_create":"1305398192","date_update":"1305398195"}]},"stat":"ok"}'
http_version:
recorded_at: Mon, 30 Mar 2015 14:57:38 GMT
recorded_with: VCR 2.9.3
flickr.reflection.getMethods is called to build all the objects and methods. Flickraw does not know what methods are available when initiallzed. If you want a deterministic behavior, you can use flickraw-cached which embeds a list of all methods.
https://github.com/hanklords/flickraw/issues/86#issuecomment-96834525
Related
Can't get "Location" attribute from response header in karate [duplicate]
This question already has an answer here: How to get id in responseHeaders location? (1 answer) Closed last year. I am not able to fetch location attribute from response header in karate, while other headers are getting displayed when using below code also from postman i am able to see all the headers including location Background: * url APAuthorizationURL * def sessionTokenPayload = call read('DIGI-3049.feature') * def authToken = sessionTokenPayload.session_Token * configure cors = true * print authToken #Authorization Scenario: Authorization_100200 Given header Content-Type = 'application/json' * print authToken * def query = {client_id: '0oajtiuveymO1ES7G0h7',response_type : 'token',response_mode: 'okta_post_message', redirect_uri: 'https%3A%2F%2Fqa2-sc.adviser.ad.mlclife.com.au', scope:'advisor',prompt:'none',state:'203475b6-836d-4dcb-8a12-7b2b2b3a2cf9', sessionToken : 'authToken', nonce:'158261204839000', scope : 'advisor' } And params query When method get Then status 200 * print responseHeaders / location header is not printing * print 'headers:', karate.prevRequest.headers / location header is not printing
This works fine for me. Please paste this into a new Scenario and try: * url 'http://httpbin.org' * path 'redirect-to' * param url = 'http://httpbin.org/get' * param status_code = 200 * method get And the first request-response is: 19:04:20.612 [main] DEBUG com.intuit.karate - request: 1 > GET http://httpbin.org/redirect-to?url=http%3A%2F%2Fhttpbin.org%2Fget&status_code=200 1 > Accept-Encoding: gzip,deflate 1 > Connection: Keep-Alive 1 > Host: httpbin.org 1 > User-Agent: Apache-HttpClient/4.5.11 (Java/1.8.0_231) 19:04:21.287 [main] DEBUG com.intuit.karate - response time in milliseconds: 670.62 1 < 302 1 < Access-Control-Allow-Credentials: true 1 < Access-Control-Allow-Origin: * 1 < Connection: keep-alive 1 < Content-Length: 0 1 < Content-Type: text/html; charset=utf-8 1 < Date: Tue, 25 Feb 2020 13:34:21 GMT 1 < Location: http://httpbin.org/get 1 < Server: gunicorn/19.9.0 So you must be missing something or making the wrong request to the wrong end-point. Also make sure you read about the followRedirects configuration in the docs.
Lua POST request contains garbage
I'm trying to send a POST request but noticed the endpoint I'm trying to access doesn't seem to like the request, so to investigate the situation I redirected the request to localhost while listening with nc and saw the following request: nc -vlp 444 Connection from 127.0.0.1:53812 POST / HTTP/1.1 Host: localhost:4444 TE: trailers Cookie: Content-Type: application/x-www-form-urlencoded Connection: close, TE User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0 27 -- this line shouldn't be there username=username&password=password 0 -- also this one The code I'm using, just in case: local http = require("socket.http") -- even tried ssl.https ... function Session:post(url, payload) -- payload = "username=username&password=password" local response = Response local body = { } local r, c, h, s = http.request{ url = url, method = "POST", sink = ltn12.sink.table(body), source = ltn12.source.string(payload), headers = { ["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0", ["Content-Type"] = "application/x-www-form" }, } -- you can ignore this response.code = c response.status = s response.body = table.concat(body) self.cookies:parse(h["set-cookie"]) return response end Thinking it was a problem of ltn12 I copied the source code of it directly in my project but soon found out it only returned the payload without actually changing anything BLOCKSIZE = 2048 function generate_payload(s) if s then local i = 1 return function() local chunk = string.sub(s, i, i+BLOCKSIZE-1) i = i + BLOCKSIZE if chunk ~= "" then return chunk else return nil end end else return source.empty() end end
Managed to fix the issue by adding the Content-Length header.
rails no bitesize error to 3rd party API response
I have a rails app and I'm trying to get calendar freebusy events from google. When I run the following code I get undefined method "bytesize" for #<Hash.. error for the result = client.execute(.... method. I checked out some other stackoverflow answers, but I can't see what I'm doing wrong. Anyone can tell me how I should deal with this problem? controller include GoogleCalendarApi ...... #user = current_user #google = #user.socials.where(provider: "google_oauth2").first unless #google.blank? # #client = get_busy_events(#google) # #result = open_gcal_connection(get_busy_events, #client, #google) #result = get_busy_events(#google) end ..... lib/google_calendar_api.rb def init_google_api_calendar_client(google_account) #method only called if google_oauth2 social exists client = Google::APIClient.new client.authorization.access_token = google_account.token client.authorization.client_id = ENV['GOOGLE_API_KEY'] client.authorization.client_secret = ENV['GOOGLE_API_SECRET'] client.authorization.refresh_token = google_account.refresh_token return client end def get_busy_events(social_object) client = init_google_api_calendar_client(social_object) old_token = client.authorization.access_token service = client.discovered_api('calendar', 'v3') result = client.execute( api_method: service.freebusy.query, body: { timeMin: '2015-12-24T17:06:02.000Z', timeMax: '2016-01-30T17:06:02.000Z', items: [{ id: social_object.email }]}, headers: {'Content-Type' => 'application/json'}) new_token = client.authorization.access_token if old_token != new_token social_object.update_attribute(token: new_token) end return result end full error: Google::APIClient - Initializing client with options {} 21:33:15 puma.1 | Google::APIClient - Please provide :application_name and :application_version when initializing the client 21:33:15 puma.1 | Google::APIClient::Request Sending API request get https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest {"User-Agent"=>"google-api-ruby-client/0.8.6 Mac OS X/10.10.4\n (gzip)", "Accept-Encoding"=>"gzip", "Content-Type"=>""} 21:33:15 puma.1 | Decompressing gzip encoded response (12528 bytes) 21:33:15 puma.1 | Decompressed (103479 bytes) 21:33:15 puma.1 | Google::APIClient::Request Result: 200 {"expires"=>"Thu, 31 Dec 2015 05:36:09 GMT", "date"=>"Thu, 31 Dec 2015 05:31:09 GMT", "etag"=>"\"ye6orv2F-1npMW3u9suM3a7C5Bo/U5WRLEvUgzkUohB7qwzTs2ir15o\"", "vary"=>"Origin, X-Origin", "content-type"=>"application/json; charset=UTF-8", "x-content-type-options"=>"nosniff", "x-frame-options"=>"SAMEORIGIN", "x-xss-protection"=>"1; mode=block", "content-length"=>"12528", "server"=>"GSE", "age"=>"126", "cache-control"=>"public, max-age=300, must-revalidate, no-transform", "alternate-protocol"=>"443:quic,p=1", "alt-svc"=>"quic=\":443\"; ma=604800; v=\"30,29,28,27,26,25\"", "connection"=>"close"} 21:33:15 puma.1 | Google::APIClient::Request Sending API request post https://www.googleapis.com/calendar/v3/freeBusy {"User-Agent"=>"google-api-ruby-client/0.8.6 Mac OS X/10.10.4\n (gzip)", "Content-Type"=>"application/json", "Accept-Encoding"=>"gzip", "Authorization"=>"Bearer ya29.WQKv43gUEb0Jt3jTBevBs0_Z9VurfGxmbH8Knv8E9Sqbw4zxeCHjydwUeyo3MSAotYj0", "Cache-Control"=>"no-store"} 21:33:15 puma.1 | Completed 500 Internal Server Error in 382ms (ActiveRecord: 0.8ms) 21:33:15 puma.1 | 21:33:15 puma.1 | NoMethodError - undefined method `bytesize' for #<Hash:0x007fb6d25b9330>: 21:33:15 puma.1 | /Users/Silo/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/net/http/generic_request.rb:182:in `send_request_with_body' 21:33:15 puma.1 | /Users/Silo/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/net/http/generic_request.rb:120:in `exec'
From Pardeep's link, try result = client.execute( api_method: service.freebusy.query, body: URI.encode_www_form({ timeMin: '2015-12-24T17:06:02.000Z', timeMax: '2016-01-30T17:06:02.000Z', items: [{ id: social_object.email }]}), headers: {'Content-Type' => 'application/json'}) The problem is that the body could not be sent as a hash. You should encode as an string.
How send email with BCC header via GMAIL API?
How can I send email with BCC via GMAIL API? I send emails to TO or CC but BCC doesn't work. I use Base64.urlsafe_encode64(email.to_s)and this code create string without BCC. My working code example: email = Mail.new email.date = Time.now email.subject = subject email.to = email_array_to_email_to(to) email.cc = email_array_to_email_to(cc) email.bcc = email_array_to_email_to(bcc) email.reply_to = email_array_to_email_to(reply_to) email.html_part do body message end request = { api_method: #google_api.users.messages.to_h['gmail.users.messages.send'], parameters: { userId: 'me' }, body_object: { raw: Base64.urlsafe_encode64(email.to_s) }, } Do I have to call again GMAIL API and send this email with thread id and BCC as TO? I use google-api-client 0.7.1 EDIT: Mail object: #<Mail::Message:70336725981360, Multipart: true, Headers: <Date: Tue, 01 Dec 2015 14:09:08 +0100>, <Reply-To: >, <To: ["quatermain32 <my_email#gmail.com>"]>, <Cc: ["quatermain32 <my_email#gmail.com>"]>, <Bcc: ["my_email#gmail.com"]>, <Subject: Test subject>, <Content-Type: multipart/mixed>> Mail object with to_s: "Date: Tue, 01 Dec 2015 14:09:08 +0100\r\n To: my_email <my_email#gmail.com>\r\n Cc: my_email <my_email#gmail.com>\r\n Message-ID: <565d9c6e3cf0b_058b7#Olivers-MacBook-Pro.local.mail>\r\n Subject: Test subject\r\n Mime-Version: 1.0\r\n Content-Type: multipart/mixed;\r\n boundary=\"--==_mimepart_565d9bf468e77_cb0d35e200577a\";\r\n charset=UTF-8\r\n Content-Transfer-Encoding: 7bit\r\n \r\n \r\n ----==_mimepart_565d9bf468e77_cb0d3ff88645e200577a\r\n Content-Type: text/html;\r\n charset=UTF-8\r\n Content-Transfer-Encoding: 7bit\r\n \r\n <p>Test content</p>\r\n ----==_mimepart_565d9bf468e77_cb0d3ff88645e200577a--\r\n "
You have to manually add the bcc header to the email, it will not be sent to the recipients. Same as gmail-ruby-api does it https://github.com/jhk753/gmail-ruby-api/blob/e0d62a751bc31397926c5800532f26e185e00b16/lib/gmail/message.rb encoded = mail.encoded if bcc = mail.bcc.join(",").presence encoded.prepend "Bcc: #{bcc}\n" end ... send email ...
ruby mailman remove header from email body
I am trying to display an email body in my RoR project. class IncomingMail def initialize(message, params) if person = Person.find_by_email(message.from) changeMessage = Message.where({person_id: person.id}) #message = message.subject.force_encoding("UTF-8") message = message.body.encoded changeMessage.first.text = message changeMessage.first.backInMinutes = 0 changeMessage.first.showText = 1 changeMessage.first.doNotDisturb = 0 changeMessage.first.save end end but i also get the email header > --e89a8ff1c0465030f204c082e054 Date: Mon, 21 May 2012 04:45:12 +0200 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 > Content-Transfer-Encoding: 7bit Content-ID: > <4fb9ac38c71d2_1e1343dd8042105b#ubuntu.mail> Text of the mail how can I remove the header ? with the subject it works like this message = message.subject.force_encoding("UTF-8") But not with the body.
I have found the solution!!! change: message = message.body.encoded to: message = message.text_part.body.decoded that cuts all the header details away and gives me only the TEXT of the email. It took a long time but it worked I hope it also helps other users