I am new to Rails and Twilio, and am trying to run the Twilio Appointment Reminder sample code. I am able to place the call, but am unable to get any feedback from Twilio about the number keys pressed by the caller.
After the call is made, the reminder TwiML is run: here the Gather command should prompt Twilio to record a single digit input from the caller:
xml.instruct!
xml.Response do
xml.Gather(:action => #post_to, :numDigits => 1) do
xml.Say "Hello this is a call"
xml.Say "Please press 1 to repeat this menu. Press 2 for directions. Or press 3 if you are done."
end
end
After a digit is pushed, the Twilio should POST to my directions command in the controller :
def directions
if params['Digits'] == '3'
redirect_to :action => 'goodbye'
return
end
if !params['Digits'] or params['Digits'] != '2'
redirect_to :action => 'reminder'
return
end
#redirect_to = BASE_URL + '/reminder'
render :action => "directions.xml.builder", :layout => false
end
However, every time i call myself and enter a number, the call keeps looping back to the original message. I then checked my logs and apparently there is no 'Digits' parameter being sent from Twilio.
Anyone encounter this problem?
Usually what's happening in a case like this is that the URL being posted to immediately issues a redirect because of something like URL rewriting or HTTPS redirection or the like. Twilio follows the redirect and on the subsequent GET request sends along the standard set of parameters which doesn't include the Digits parameter that is only sent on the initial POST to the <Gather> action URL.
Related
I am having a destroy method in employees controller as:
# DELETE /employees/1
def destroy
if #employee.destroy
redirect_to employees_url, notice: ‘Employee record was successfully destroyed.'
else
alert = ['Employee record could not be destroyed']
alert += #employee.errors.full_messages.map{ |s| "#{s}." } #because of some reason
alert = alert.join(' ')
redirect_back :fallback_location => #employee, :alert => alert
end
end
Output alert message: Employee record could not be destroyed because of some other
reason
It is redirecting to same show page but when I am navigating to some other page, the same alert message is persisted wherever I navigate.
I tried modifying it using flash[:alert], flash.now.alert and etc but no luck.
Could you please suggest how to fix this from controller end?
Rails redirect_to API documents an undesirable scenario that might happen when you are making a request with something other than a GET or POST (in this case using a DELETE)
If you are using XHR requests other than GET or POST and redirecting after the request then some browsers will follow the redirect using the original request method. This may lead to undesirable behavior such as a double DELETE. To work around this you can return a 303 See Other status code which will be followed using a GET request.
The solution is to try adding a status on your options array in the redirect_back
redirect_back fallback_location: #employee, alert: alert, status: 303
I have a simple demo app set up to be able to access Salesforce.com from a Ruby on Rails app. My code is extremely simple:
def sign_in_salesforce
client = OAuth2::Client.new(ENV['SALESFORCE_CONSUMER_KEY'], ENV['SALESFORCE_CONSUMER_SECRET'], :site => 'https://login.salesforce.com/', :authorize_url => 'services/oauth2/authorize', :token_url => 'services/oauth2/token')
auth_url = client.auth_code.authorize_url(:redirect_uri => 'https://99.44.242.76:3000/users/oauth_callback')
redirect_to auth_url
end
I then have a method to take care of the callback.
def oauth_callback
db_client = Databasedotcom::Client.new
db_client.authenticate(:token => params[:code])
puts db_client.inspect
end
The error in the console is:
ArgumentError (ArgumentError):
app/controllers/users_controller.rb:60:in `oauth_callback'
The line that is causing the error is:
db_client.authenticate(:token => params[:code])
like the token that I am getting is invalid or something.
It worked fine until I changed my Salesforce password (which they required me to do). What am I missing? Thanks for the help.
If the response you receive is that your refresh token is no longer valid then you need to restart the OAuth process from scratch to obtain a new refresh token; you can then use to get new session tokens in subsequent uses of the app as you have been up until now.
Essentially, start the process as you would for the very first time the app is launched.
I have a list of stories assigned to me in Cucumber, one of them being "Then the user should receive a confirmation email". I think testing that the user receives it is beyond the power of the application, but how can I test that an email had just been sent?
You can use this step definition :
Then "the user should receive a confirmation email" do
# this will get the first email, so we can check the email headers and body.
email = ActionMailer::Base.deliveries.first
email.from.should == "admin#example.com"
email.to.should == #user.email
email.body.should include("some key word or something....")
end
Tested with Rails 3.2
Source
email_spec + action_mailer_cache_delivery gems are your friends for doing this
I would suggest you to verify the last_response after some action ocurrs, like, a user click on a button, or something like that.
Or if you are updating a record after doing something, check for the updated_at attribute to see if it was changed or not.
Check dockyard/capybara-email gem:
feature 'Emailer' do
background do
# will clear the message queue
clear_emails
visit email_trigger_path
# Will find an email sent to test#example.com
# and set `current_email`
open_email('test#example.com')
end
scenario 'following a link' do
current_email.click_link 'your profile'
expect(page).to have_content 'Profile page'
end
scenario 'testing for content' do
expect(current_email).to have_content 'Hello Joe!'
end
scenario 'testing for a custom header' do
expect(current_email.headers).to include 'header-key'
end
scenario 'testing for a custom header value' do
expect(current_email.header('header-key')).to eq 'header_value'
end
scenario 'view the email body in your browser' do
# the `launchy` gem is required
current_email.save_and_open
end
end
Another option is PutsBox. You can send an email to whatever-you-want#putsbox.com, wait for a few seconds (SMTP stuff ins't instantaneous) then check your email via http://preview.putsbox.com/p/whatever-you-want/last.
This post tutorial has some examples.
I'd like to test if an email is delivered if I call a controller method with :post. I'll use email_spec so I tried this snipped here: http://rubydoc.info/gems/email_spec/1.2.1/file/README.rdoc#Testing_In_Isolation
But it doesn't work, because I pass an instance of the model-object to the delivery-method and the instance is saved before the delivery.
I tried to create an other instance of the model-object, but then the id isn't the same.
My controller-method looks like this:
def create
#params = params[:reservation]
#reservation = Reservation.new(#params)
if #reservation.save
ReservationMailer.confirm_email(#reservation).deliver
redirect_to success_path
else
#title = "Reservation"
render 'new'
end
end
Do you have any idea to solve this?
Assuming your test environment is set up in the usual fashion (that is, you have config.action_mailer.delivery_method = :test), then delivered emails are inserted into the global array ActionMailer::Base.deliveries as Mail::Message instances. You can read that from your test case and ensure the email is as expected. See here.
Configure your test environment to accumulate sent mails in ActionMailer::Base.deliveries.
# config/environments/test.rb
config.action_mailer.delivery_method = :test
Then something like this should allow you to test that the mail was sent.
# Sample parameters you would expect for POST #create.
def reservation_params
{ "reservation" => "Drinks for two at 8pm" }
end
describe MyController do
describe "#create" do
context "when a reservation is saved" do
it "sends a confirmation email" do
expect { post :create, reservation_params }.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end
end
end
Note that my example uses RSpec 3 syntax.
I know I'm late to the party with this one, but for future Googlers...
I think a better solution to this problem is answered here
The previously accepted answer is testing the Mailer itself (inside the controller spec). All you should be testing for here is that the Mailer gets told to deliver something with the right parameters.
You can then test the Mailer elsewhere to make sure it responds to those parameters correctly.
ReservationMailer.should_receive(:confirm_email).with(an_instance_of(Reservation))
This is way how to test that Mailer is called with right arguments. You can use this code in feature, controller or mailer spec:
delivery = double
expect(delivery).to receive(:deliver_now).with(no_args)
expect(ReservationMailer).to receive(:confirm_email)
.with('reservation')
.and_return(delivery)
Anyone using rspec +3.4 and ActiveJob to send async emails, try with:
expect {
post :create, params
}.to have_enqueued_job.on_queue('mailers')
To add a little more, make sure if you're going to stub out a call using should_receive that you have an integration test elsewhere testing that you're actually calling the method correctly.
I've been bit a few times by changing a method that was tested elsewhere with should_receive and having tests still pass when the method call was broken.
If you prefer to test the outcome rather than using should_receive, shoulda has a nice matcher that works like the following:
it { should have_sent_email.with_subject(/is spam$/) }
Shoulda documentation
More information on using Shoulda Matchers with rSpec
If you're using Capybara with Capybara Email and you sent an email to test#example.com, you can also use this method:
email = open_email('test#example.com')
And then you can test it like this:
expect(email.subject).to eq('SUBJECT')
expect(email.to).to eq(['test#example.com'])
Try email-spec
describe "POST /signup (#signup)" do
it "should deliver the signup email" do
# expect
expect(UserMailer).to(receive(:deliver_signup).with("email#example.com", "Jimmy Bean"))
# when
post :signup, "Email" => "email#example.com", "Name" => "Jimmy Bean"
end
end
more examples here: https://github.com/email-spec/email-spec#testing-in-isolation
I think problem is around $api->listSubscribers()
include('../libs/mailchimp/MCAPI.class.php');
$options = array('list_id' => '$list_id', 'subject' => 'Prova', 'from_name' => 'name', 'from_email' => 'info#example.com');
$content = array('html' => '<p>Testo di prova</p>');
$api = new MCAPI($apikey);
$campaignId = $api->campaignCreate('trans', $options, $content);
$api->listSubscribe($options['list_id']);
$api->campaignSendNow($campaignId);
if ($api->errorCode){
echo "Unable to Create New Campaign!";
echo "\n\tCode=".$api->errorCode;
echo "\n\tMsg=".$api->errorMessage."\n";
} else {
echo "New Campaign ID:".$campaignId ."\n";
}
Why does'nt it send an email?
You have a several issues here:
The first one is that you are not doing error checking after each API call. If you take the error checking code from the bottom and stick it after the listSubscribe() call, you'll immediately get an error because you aren't passing any sort of subscriber data (at the very least you need the email address). The docs for listSubscribe are here
Once you do that - unless you've thoroughly read and considered the options in the listSubscribe docs - your second issue is going to be that you are running listSubscribe with the double_optin parameter set to true (the default), which means they won't be subscribed until clicking a link in the confirmation email.
Next, that code is just going to get you in trouble, and probably quickly. If you are going to use psuedo-transcational campaigns it is imperrative that you only create ONE psuedo-trans campaign per type of email and then send that campaign over and over. That's how they are intended to work. Not doing that is going to cause you to fill up your account with a whole bunch of trash campaigns at which point there's no point in using a psuedo-trans campaign since that's the same as creating/sending a regular campaign to a single user over and over.
Do you get any errors?
It seems you are not including the api key, it should look like:
$api = new MCAPI($apikey);
Instead of:
$api = new MCAPI('apikey');
You get the API Key from your api dashboard: http://admin.mailchimp.com/account/api