Speed up Ruby class to avoid requests to JIRA and Slack API - ruby

My, pure Ruby, class pull out user names from Jira API to convert it into email address and pass these email addresses to another class based on which Slack ID is extracted.
module Request
class GetUser
def call
setup_email
end
private
def setup_email
devops_email = dev_role['actors'].map { |user| "#{user['name']}#example.com" }
devops_email.each do |email|
::Slack::GetUserId.new(email: email).call
end
end
def dev_role
HTTParty.get('https://company_name.atlassian.net/rest/api/3/project/1234/role/1234',
basic_auth: { username: 'user', password: 'pass' },
headers: { 'content-type' => 'application/json' })
end
end
end
Because above class will be called every day (AWS Lambda schedule), I want to speed up the class. What should I use to achieve that? Should I use some database (Dynamodb probably?) to save user data (userID and user email) and make a query to check if the data (e.g. user name) has changed?
Or maybe should I change some implementation and leave these requests without saving data to the database?

Related

Get Gmail User Profile Picture and Name with Google API client

The Google API client has Class: Google::Apis::PeopleV1::Name and Google::Apis::PeopleV1::Photo how do I hit these endpoints? I tried
p = Google::Apis::PeopleV1::Photo.new
response = p.url
But it returns nil. Opposed to this GmailService has instance methods like get_user_message which I can call like this
#service = Google::Apis::GmailV1::GmailService.new
# authorization is done
response = #service.get_user_message(user_id, message_id)
It returns a response object which has the message, now I want to fetch the User's name and Photo, but I did not find any method to access this information. How do I retrieve the User's name and photo using the API client?
I think that the value retrieved with the method of users.messages.get in Gmail API doesn't include "User Profile Picture". Ref So for example, in order to retrieve the URL of user's profile photo, how about using the method of people.connections.list in People API? The sample script is as follows.
Sample script:
service = Google::Apis::PeopleV1::PeopleServiceService.new
service.authorization = authorize
response = service.list_person_connections(
'people/me',
'page_size': 1000,
'person_fields': "names,emailAddresses,photos"
)
puts "No connections" if response.connections.empty?
result = response.connections.map {|person| {
'resourceName': person.resource_name,
'email': person.email_addresses[0].value,
'photos': person.photos.map {|e| e.url}
}}
puts result
Result:
When above script is run, the following result is returned.
[
{"resourceName": "people/###", "email": "###", "photos": ["https://###"]},
{"resourceName": "people/###", "email": "###", "photos": ["https://###", "https://###"]},
,
,
,
]
The URLs of phtots are the URLs of the user's photo images.
Note:
In this case, it seems that the method of otherContacts.list doesn't return the user's photo data.
Reference:
Method: people.connections.list

Reading a JSON object in Ruby on Rails

I'm a Ruby on Rails beginner and I'm trying to convert a static website I've made into Rails app where I can store customers and quote data. I'm trying to do this as a RESTful API where my site sends a JSON object containing the customer's information. I check to see if the email in the JSON object matches any of the emails I have in my database and if it does I send back the id of that customer. If not then I create a new customer and send back that id. The problem I'm having is that no matter how I write it, my rails app is not reading the JSON data, so if I have nothing in my database it creates a customer with all null attributes and when I run it again it goes "Oh, I have customer with a null email" and returns that customer.
{
"fname": "William",
"lname": "Shakespeare",
"email": "wshakespeare#test.com",
"bname": "MyCompany",
"primary": "555-555-5555",
"secondary": ""
}
Here's an example of my JSON object.
Here's how my controller is looking:
class CustomersController < ApplicationController
skip_before_action :verify_authenticity_token
wrap_parameters format: [:json, :xml, :url_encoded_form, :multipart_form]
def create
#query = Customer.where(:email === params[:email])
if #query.empty? == true
redirect_to action: "new", status: 301
else
#theid = #query.first.id
render json: {status: 'SUCCESS', message: 'Existing customer', theid:#theid}
end
end
def new
Customer.create(fname: params[:fname], lname: params[:lname], email: params[:email], bname: params[:bname], primary: params[:primary], secondary: params[:secondary])
render json: {status: 'SUCCESS', message: 'New customer', theid: Customer.last.id}
end
Any help would be greatly appreciated. Thanks.

ActiveModel serializer ignores root key when posts or post is empty or nil

I am using active model serializer V0.10.0 with Rails 5 api only application. During implementation I noticed the AMS is completely ignoring the root key when the posts/post is empty or nil respectively. This behavior actually breaks my mobile app as it always expects root key data in all response.
So what I want to achieve here is no matter what I always want data as root element of my Rails app response for all requests.
Response for SHOW API when the post is empty
SHOW render json: #post, root: 'data'
Expected
{
"data": {}
}
Actual
null
Response for INDEX API when the posts are empty
INDEX render json: #posts, root: 'data'
Expected
{
"data": []
}
Actual
{
"posts": []
}
class ApplicationSerializer < ActiveModel::Serializer
include Rails.application.routes.url_helpers
ActiveModelSerializers.config.adapter = :json
def host
Rails.application.secrets.dig(:host_url)
end
end
class PostSerializer < ApplicationSerializer
attributes :id
has_many :comments
end

Testing with Postman keeps returning Invalid JSON error

I have created REST Api in Ruby on Sinatra platform. I am testing the service with Postman and whatever JSON form I try to POST I keep getting an error 400 Invalid JSON SUCKER. The error is defined on the back end in case of invalid JSON form. Please take a look at the back end and tell me what am I doing wrong.
I have to mention that GET method works with Postman and cURL from the command line while POST works only if I use it with cURL but NOT in POSTMAN.
#server.rb
require 'sinatra'
require 'mongoid'
require 'sinatra/namespace'
require 'sinatra/base'
#require 'json'
before do
content_type :json
headers 'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => ['OPTIONS', 'GET', 'POST', 'PATCH']
end
#load database config
Mongoid.load! "mongoid.config"
#Class Company
class Company
include Mongoid::Document
field :compid, type: String
field :name, type: String
field :address, type: String
field :city, type: String
# validates :compid, presence: true
# validates :name, presence: true
index({ compid:1 }, { unique: true, name: "compid_index" })
index({ name: 'text' })
scope :name, -> (name) { where(name: /^#{name}/) } # this could be changed to /^#{title}/i to make case insensitive searcg =end
scope :compid, -> (compid) { where(compid: compid) }
end
#Serializers
class Serializer
def initialize(company)
#company = company
end
def as_json(*)
data ={
id:#company.compid.to_s,
name:#company.name,
address:#company.address,
city:#company.city,
}
data[:errors] = #company.errors if#company.errors.any?
data
end
end
# Endpoints
get '/' do
'List of all Companies'
end
namespace '/api/v1' do
before do
content_type 'application/json'
end
helpers do
def base_url
#base_url ||= "#{request.env['rack.url_scheme']}://{request.env['HTTP_HOST']}"
end
def json_params
begin
JSON.parse(request.body.read)
rescue
halt 400, { message:'Invalid JSON' }.to_json
end
end
end
get '/companies' do
companies = Company.all
[ :name, :compid,].each do |filter|
companies = companies.send(filter, params[filter]) if params[filter]
end
#put it through the serializer not to get all te atributes
companies.map { |company| Serializer.new(company) }.to_json
end
get '/companies/:compid' do |compid| #get the details about the company by searching with compid
company = Company.where(compid: compid).first
halt(404, { message:'Company Not Found'}.to_json) unless company
Serializer.new(company).to_json
end
post '/companies' do
company = Company.new(json_params)
if company.save
response.headers['Location'] = "#{base_url}/api/v1/companies{company.copmid}" # "{company.id}"
status 201
else
status 422
body Serializer.new(company).to_json
end
end
The data that I GET with the Postman looks like this:
[{"id":"5a1271f7943e8a0f5fd76008","name":"The Power Of Habit","address":"Charles Duhigg Vej","city":"Viborg"}]
I have tried to POST data in various forms:
[{"id":"5a1271f79asdd76008","name":"The Power Of Habit","address":"Charles Duhigg Vej","city":"Viborg"}]
{"id":"5a1271f79asdd76008","name":"The Power Of Habit","address":"Charles Duhigg Vej","city":"Viborg"}
[{"compid":"5a1271f79asdd76008","name":"The Power Of Habit","address":"Charles Duhigg Vej","city":"Viborg"}]
{"compid":"5a1271f79asdd76008","name":"The Power Of Habit","address":"Charles Duhigg Vej","city":"Viborg"}

How to respond_with multiple objects in Rails 3.1

I have a route for example
POST /interaction.json
where the client posts a new interaction. Normally my controller would look like
class InteractionController < ApplicationController
def create
respond_with #log
end
end
and I will get back a json response
{ "log" : { "id" : 20, .... } }
and the location header set to
http://foo.com/log/20
However if I wish to return more objects in my :json response than just the #log. For example to notify the client that some thing has changed with respects to this interaction the normal. Perhaps the user has won a prize for making this interaction. It would be nice to be able to do
response_with #log, #prize
and get the response
{ "log": { "id": 20, ... },
"prize": { "id": 50, ...}
}
but that is not the way respond_with works. It treats #prize as a nested resource of #log. Can anyone suggest an idea for this?
Merging two independent objects is dangerous and will override any existing attributes in the caller.
Instead you could always wrap the objects and respond with the wrapper instead:
#response = {:log => #log, :price => #price}
respond_with #response
Assuming that #log and #prize are both hashes, you could merge both hashes and return the merge.
respond_with #log.merge(#prize)
I'm thinking it might overwrite the #log.id with #prize.id though. Can try something else if it does.

Resources