Using Twilio API in Ruby, How to pass parameters between actions? - ruby-on-rails

In the ruby controller, I have two methods in the same controller.
class NotificationsController < ApplicationController
def send
my_variable = xxx
twilio_client = Twilio::REST::Client.new account_sid, auth_token
twilio_client.send_text(user, message)
end
def receive
response = Twilio::TwiML::MessagingResponse.new
response.message do |message|
message.body("Hello World!")
end
puts params["Body"]
end
end
The method send would send message to the specific user, and the method receive receive the message from the user. However, the my_variable in the send method lost between actions. I want to use the variable in the receive method, but don't know how to do that.
I tried to assign the variable one to a session hash. session[:variable_one] = variable_one, and access it in the method receive. But it turns out the session[:variable_one] in the method receive is nil.
I read the documents from Twilio, but still very confuse how to pass the extra parameters.
Could you please have some suggestions on this problem? Thanks so much.

Related

Accessing more than default parameters (to, from, subject, reply_to) for rails mail interceptor

I have a method within a mailer called notification_mailer.rb:
def reminder_email
#community = #reminder.community
subject = "random subject text"
mail(from: address_for(support), reply_to: address_for(support), to: to_address, subject: subject)
end
I am trying to use a mail interceptor check_mail_settings.rb:
class CheckMailSettings
def self.delivering_email(mail)
if #community.status = "mute"
mail.perform_deliveries = false
end
end
end
ActionMailer::Base.register_interceptor(CheckMailSettings)
But this interceptor does not actually have access to the #community variable. I have tried passing it in the mail call in notification_mailer.rb like so
mail(community: #community, from: address_for(support).....)
and accessing it within the interceptor check_mail_settings.rb like this
mail.community
but that does not work either.
Is there any way I can get access to this #community variable within the interceptor check_mail_settings.rb or will I need to do any conditionals involving #community within the notification_mailer.rb beforehand?
while i don't think that what you are doing there really makes sense, it is possible.
in the interceptor you get an instance of Mail::Message. it has access to whatever you pass into the mail call.
so in the example you provided it would be
mail[:community].value

Rails 5 ActionCable establish stream from URL parameters

I am almost completely new to Rails, or I am sure I would know how to answer this question myself. I am just trying to modify the basic chat app created in the basic ActionCable demo: https://medium.com/#dhh/rails-5-action-cable-demo-8bba4ccfc55e#.6lmd6tfi7
Instead of having just one chat room, I want to have multiple chat rooms, so I modified my routes.rb by adding this line:
get '/rooms/show/:topic', to: 'rooms#show'
So now I can visit different chat rooms based on different topics. The rooms controller at /app/controllers/rooms_controller.rb handles these routes with no problem:
class RoomsController < ApplicationController
def show
#topic = params[:topic]
#messages = Message.all
end
end
But this parameter is not being passed to app/channels/room_channel.rb, and I'm just not sure what modifications I need to make. My current attempt:
class RoomChannel < ApplicationCable::Channel
def subscribed
stream_from "room_channel_#{params[:topic]}"
end
only returns "room_channel_"
The problem here was that I failed to understand from where the subscribed method was being called, and thus did not know how to pass parameters to it.
By reading the actioncable documentation: https://github.com/rails/rails/tree/master/actioncable
I found out that the subscribed method is called via client-side javascript, not by the rails controller. In the case of the example chat app, this means I had to change the first line of the file /app/assets/javascripts/channels/room.coffee
App.room = App.cable.subscriptions.create "RoomChannel",
to
App.room = App.cable.subscriptions.create { channel: "RoomChannel", topic: topic},
Passing a javascript object to this method allowed me to access those parameters in the subscribed method of rooms_controller.rb.
Set the topic_id in a HTML tag, maybe in the body tag in your layout file.
<body data-topic-id="<%= #topic.id %>">
Now read it from JS like this:
document.querySelector('body').dataset.topicId
Your subscription creation line would look like this:
App.room = App.cable.subscriptions.create (channel: 'RoomChannel', topic_id: document.querySelector('body').dataset.topicId)

Error passing object to method using send() in Ruby

I'm having a problem using send() to call a method while passing said method an object. I receive an undefined method ``employee_feedback(#<WorkItem:0x000000057cc7c0>)' for WorkItemMailer:Class error.
This is in my work_item.rb model:
def send_work_item_mail
forms_needing_mail = ["employee", "install", "repair"]
if forms_needing_mail.include?(self.form)
WorkItemMailer.send("#{self.form}_feedback(#{self})").deliver_now
end
end
Which is being called as:
#work_item.send_work_item_mail
in my work_items_controller.rb
And the following is the method in my mailer:
def employee_feedback(work_item)
#work_item = work_item
#employee = User.find_by(id: #work_item.employee)
#manager = User.find_by(id: #employee.manager)
mail to: #manager.email, subject: "Employee feedback for #{#employee.name}"
end
Am I using send incorrectly, or is there something else at play here?
try this
WorkItemMailer.send("#{self.form}_feedback".to_sym, self).deliver_now
Calling send on an object is identical as calling a method directly. The difference is that you pass the method name as an argument to send.
Subsequent arguments to send, (after the method name) are passed as parameters in the method
So this:
WorkItemMailer.employee_feedback(self)
Should be called as:
WorkItemMailer.send(:employee_feedback, self)
In your case:
WorkItemMailer.send("#{self.form}_feedback", self).deliver_now

ActionMailer send email in background, queue_classic

I am using queue_classic,
How can I send the following email using queue_classic?
Notifier.welcome(david).deliver # sends the email
UPDATE
I have added a new class method into User class
def.say_hello
puts "hello!"
Notifier.welcome(#david).deliver
end
QC.enqueue("puts", "hello world") works fine,
but QC.enqueue("User.say_hello") doesn't send email"
What could I do?
It looks like queue_classic's enqueue method takes two arguments:
method to call
arguments to pass to this method
So you need to write a method that you can call with the two items above that will deliver your email.
module QueueNotifier
def self.send_welcome_email_to_user(id)
user = User.find(id)
Notifier.welcome(user).deliver
end
end
Then in order to enqueue these sending events, you would queue up the method name (QueueNotifier.send_email_to_user) and the argument (whatever the user id of david or the user you want to send to).
QC.enqueue("QueueNotifier.send_welcome_email_to_user", 14)

how to parse json url response in rails

I've a simple Rails app that makes a request to an external website and returns a json url response with a callback to my site to notify my Rails app about the response. The json url sample is https://voguepay.com/?v_transaction_id=demo-1345109950&type=json and the response body is below:
{"merchant_id":"demo","transaction_id":"demo-1345109950","email":"testuser#buyerdomain.com","total":"10","total_paid_by_buyer":"10.00","total_credited_to_merchant":"9.90","extra_charges_by_merchant":"0.00","merchant_ref":"","memo":"Donation of N10 to Test User","status":"Approved","date":"2012-01-01 11:39:11","referrer":"http:\/\/sellerdomain.com\/buy_now.html","method":"VoguePay","fund_maturity":"2012-01-03"}
I'd like to convert this response into a Rails method than can simply give me the attribute I need to make my query. For example, from the response body I need to make an action like:
def notify
response = Json.parse('https://voguepay.com/?v_transaction_id=demo-1345109950&type=json').body
response.status
response.date
response.merchant_id
response.total
end
The code above is just a sample to explain what I want to achieve. Any help will be great.
I've tried both typhoeus and yajl-ruby gems but when the request comes in, all my authentication methods are removed and I keep getting the error message cannot authenticate csrf meta token. Even if I skip it the current user will be signed out automatically ( with devise authentication). The code sample used is below:
class NotificationsController < ApplicationController
skip_before_filter :verify_authenticity_token
def notify
#transaction_id = params[:transaction_id]
do_notify
end
private
def do_notify
hydra = Typhoeus::Hydra.new
request = Typhoeus::Request.new("https://voguepay.com/?v_transaction_id=#{#transaction_id}&type=json")
request.on_complete do |response|
logger.info("#{response.request.url} in #{response.time} seconds") #remove in production to avoid huge logs
transaction = Yajl::Parser.parse(response.body) #or Yajl::Parser.parse(response.body)
#Now we have the following keys in our transaction hash you can do whatever
transaction[:merchant_id]
transaction[:transaction_id]
transaction[:email]
transaction[:total]
transaction[:merchant_ref]
transaction[:memo]
transaction[:status]
transaction[:date]
transaction[:referrer]
transaction[:method]
#plan = Plan.find_by_id(transaction[:merchant_ref])
if(transaction[:total] == 0)
logger.error "Invalid total for transaction:#{#transaction_id}"
#do not subscribe the user or generate invoice, notify user of error n cancel order
elsif(transaction[:status] != 'Approved')
logger.error "Failed transaction for transaction:#{#transaction_id}"
#do not subscribe the user or generate invoice, notify user of error n cancel order
elsif(transaction[:total] >= #plan.naira_price.to_s)
current_user.award_user_credits(#plan.hjc.to_i)
end
end
hydra.queue(request)
hydra.run
end
end
Anymore, I don't want to use a gem I want to do it manually to see if the csrf meta token will not be affected. So any idea on how I can achieve this will be great. I am using rails 3.2.9.
Thank you!
You can do:
def notify
response = JSON('https://voguepay.com/?v_transaction_id=demo-1345109950&type=json').body
response["status"]
response["date"]
response["merchant_id"]
response["total"]
end

Resources