I can send mail from my site fine using Sinatra and Pony mail.The problem lies in setting the body to use an erb template.
So my config is set like so
post '/' do
from = params[:name]
subject = "#{params[:name]} has contacted you"
body = erb(:mail)
Pony.mail(
:from => from,
:to => ENV["EMAIL_ADDRESS"],
:subject => subject,
:body => body,
:via => :smtp,
:via_options => {
:address => 'smtp.gmail.com',
:port => '587',
:enable_starttls_auto => true,
:user_name => ENV["USER_NAME"],
:password => ENV["PASSWORD"],
:authentication => :plain,
:domain => "localhost.localdomain"
})
flash[:notice] = "Thanks for your email. I will be in touch soon."
redirect '/success'
So my subject renders correclty, but the body of the message is actually returned as the html source for my webpage (as if i had right clicked view source)
My erb template is like so
Hello Rich,
Seems as if you have recieved an email from <%= params[:name] %> via your website.
Their email address is <%= params[:email] %>, this is what they said.
<%= params[:message] %>
So why isnt the body rendering the erb tempalte?
Im a bit confused here? Have i set something up incorrectly within the erb template?
Thanks
Ok so for anyone else with same issue what i needed to do was tell sinatra not to use my layout file, so when setting
body = erb(:mail)
It needed to be
body = erb(:mail, layout: false )
Related
I am trying to create some simple Ruby code to add emails using the Campaign Monitor API. Below is my code.
require 'httparty'
require 'json'
def request
url = 'https://api.createsend.com/api/v3.1/subscribers/MYLISTID.json'
auth = {:username => 'MYAPIKEY', :password => 'x'}
response = HTTParty.post(url,
:basic_auth => auth, :body => {
'EmailAddress' => 'mike#hotmail.com',
'Name' => 'Test',
'Resubscribe' => true,
'RestartSubscriptionBasedAutoresponders' => true
})
puts response
puts response.code
end
request
I can connect with the API. However, when I try to add the email I am getting the following response.
{"Code"=>400, "Message"=>"Failed to deserialize your request.
Please check the documentation and try again.
Fields in error: subscriber"}
400
When I change the request to get instead of put
my response is:
{"Code"=>1, "Message"=>"Invalid Email Address"}
I can't understand what I am doing wrong as I have followed the documentation on the Campaign Monitor API
It looks like you have everything setup correctly, you just need to turn the body of the post into a json string.
response = HTTParty.post(url,
:basic_auth => auth, :body => {
'EmailAddress' => 'mike#hotmail.com',
'Name' => 'Test',
'Resubscribe' => true,
'RestartSubscriptionBasedAutoresponders' => true
}.to_json)
I'd like to point out that a Campaign Monitor API gem also exists that will do all of that work for you.
Campaign Monitor API Gem
I've been working on integrating Postmates with my ecommerce rails application for on demand deliveries. I've built a controller and view for testing purposes and configured it in my routes file (built in my dev environment). For reference, here is the documentation from Postmates: docs and here is a technical blogpost: blog
Routes file:
resources :postmates do
member do
post 'get_delivery'
end
end
The controller:
require 'httparty'
require 'json'
class PostmatesController < ApplicationController
def get_delivery
api_key = **hidden**
#customer = 'cus_K8mRn4ovuNyNKV'
#urlstring_to_post = 'https://api.postmates.com/v1/customers/' + #customer + '/delivery_quotes'
#result = HTTParty.post(#urlstring_to_post.to_str,
:body => { :dropoff_address => "205 E 95th Street, New York, NY 10128",
:pickup_address => "619 W 54th St, New York, NY 10019"
}.to_json,
:basic_auth => { :username => api_key },
:headers => { 'Content-Type' => 'application/json' })
end
end
The view:
<div class="container">
<%= form_tag url_for(:controller => 'postmates', :action => 'get_delivery'), :method => 'post' do %>
<%= submit_tag "Get Delivery", :action => 'get_delivery', :controller => 'postmates'%>
<% end %>
</div>
<p>Result: <%= #result %></p>
Here is the response back from the api:
{"kind"=>"error", "code"=>"invalid_params", "params"=>{"dropoff_address"=>"This field is required.", "pickup_address"=>"This field is required."}, "message"=>"The parameters of your request were invalid."}
It seems to me that the dropoff and pickup address are not being submitted in the HTTP request. Can anyone tell me if I'm making some minor syntax error or something? The fact that I'm getting this response means that my authentication is fine and so is the url. Any ideas?
Thanks.
It looks like you're posting JSON data to the API, while the documentation (https://postmates.com/developer/docs#basics) says you should POST the data as application/x-www-form-urlencoded
I'm not really familiar with HTTParty, but you can probably just remove the .to_json and don't specify the content-type header.
Unrelated to your question, but you shouldn't publicly post your API key. ;)
config/application.rb file
require File.expand_path('../boot', __FILE__)
require 'rails/all'
Bundler.require(*Rails.groups)
module Blog
class Application < Rails::Application
config.middleware.insert_before 0, "Rack::Cors", :debug => true, :logger => (-> { Rails.logger }) do
allow do
origins '*'
resource '/cors',
:headers => :any,
:methods => [:post],
:credentials => true,
:max_age => 0
resource '*',
:headers => :any,
:methods => [:get, :post, :delete, :put, :options, :head],
:max_age => 0
end
end
end
end
pusher_controller.rb
pusher api is used for the pop up notofocation as said in takeofflabs.com
class PusherController < ApplicationController
def auth
if current_user && params[:channel_name]=="private-user-current-#{current_user_id}"
response = Pusher[params[:channel_name]].authenticate(params[:socket_id])
render :json => response
else
render "not_authorized" , :status =>'403'
end
end
def show
Pusher.app_id = PUSHER_APP_ID
Pusher.key = PUSHER_KEY
Pusher.secret = PUSHER_SECRET
x= render_to_string(:partial => "/views/notifications/notification")
Pusher["private-user-#{#notification.user_id}"].trigger('new-notification',x)
end
end
environment.rb file
require File.expand_path('../application', FILE)
PUSHER_APP_ID = "101053"
PUSHER_KEY = "89979ad24549eabc3764"
PUSHER_SECRET = "f4c1a6ca70d523e9e72e"
application.html.erb
<html>
<head>
<title>Blog</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<%= javascript_include_tag "http://js.pusherapp.com/2.2/pusher.min.js" %>
<script>
var pusher = new Pusher("#{PUSHER_KEY}");
var userChannel = pusher.subscribe("private-user-#{current_user.id}");
userChannel.bind('new-notification', function(message) {
$(".notifications_area").html(message);
});
</script>
</head>
<body>
<%if current_user %>
Logged in as: <%= current_user.email if current_user %>
<%else%>
PLEASE LOG IN TO SEE THE ARTICLES
<%end%>
<%= yield %>
</body>
</html>
Rails.application.initialize!
Although your question doesn't directly say this I'm assuming that the CORS error occurs when the private channel subscription authentication is taking place.
I'm not too familiar with Rack CORS however the way these things usually work is that they require an authentication token to be passed with any request to the server. The way to do this in with the Pusher JavaScript library is to pass in an auth option when you construct the Pusher instance:
var options = {
auth: {
headers: {
'x-domain-token': YOUR_CORS_TOKEN
}
}
};
var pusher = new Pusher( YOUR_APP_KEY, options );
You will need to check:
Where Rack CORS expects the token to be. It may be in a header or as a POST or GET parameter. You can also set these via options
What the name of the parameter is. Above I've guessed at x-domain-token
For information on options see the Pusher docs on the options.auth parameter.
There is also a Pusher CSRF RoR FAQ which may provide additional insight.
I received the following code from a development team:
curl -u EMAILADDRESS:PASSWORD -d "sender=NAME <EMAILADDRESS>&message=[Invite Link]&collector=COLLECTOR&subject=Test Invite&footer=My Custom Text [Unsubscription Link]"
I have been told that the above works fine. This is what I translated it to in Ruby 1.9.3, using the httparty gem:
call= "/api/v2/emails/?survey=#{i}"
puts collector_final_id
url= HTTParty.post("https://www.fluidsurveys.com#{call}",
:basic_auth => auth,
:headers => { 'Content-Type' => 'application/x-www-form-urlencoded','Accept' => 'application/x-www-form-urlencoded' },
:collector => collector,
:body => {
"subject" => "Test Invite",
"sender" => "NAME <EMAILADDRESS>",
"message" => "[Invite Link]"
},
:footer => "My Custom Text [Unsubscription Link]"
)
Everything within this works fine except for the :footer and :collector parameters. It doesn't seem to recognize them at all.
There are no errors thrown, they just aren't included in the actual email I am sending. What am I doing wrong when passing in those two parameters?
Your :collector and :footer are not correct.
I wrote a little Sinatra service to receive a POST request with any parameters:
require 'pp'
require 'sinatra'
post "/*" do
pp params
end
And ran it, launching the web-server on my Mac OS laptop. As Sinatra apps do, it resides at 0.0.0.0:4567.
Running this code:
require 'httparty'
url = HTTParty.post(
"http://localhost:4567/api/v2/emails?survey=1",
:headers => {
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/x-www-form-urlencoded'
},
:body => {
"subject" => 'subject',
"sender" => 'sender',
"message" => 'message',
},
:collector => 'collector',
:footer => 'footer'
)
puts url
Outputs:
["survey", "1"]["subject", "subject"]["sender", "sender"]["message", "message"]["splat", ["api/v2/emails"]]["captures", ["api/v2/emails"]]
Sinatra said:
127.0.0.1 - - [11/Sep/2013 17:58:47] "POST /api/v2/emails?survey=1 HTTP/1.1" 200 - 0.0163
{"survey"=>"1",
"subject"=>"subject",
"sender"=>"sender",
"message"=>"message",
"splat"=>["api/v2/emails"],
"captures"=>["api/v2/emails"]}
Changing :collector and :footer to strings and moving them inside the body, where they should be:
require 'httparty'
url = HTTParty.post(
"http://localhost:4567/api/v2/emails?survey=1",
:headers => {
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/x-www-form-urlencoded'
},
:body => {
"subject" => 'subject',
"sender" => 'sender',
"message" => 'message',
'collector' => 'collector',
'footer' => 'footer'
},
)
puts url
Outputs:
["survey", "1"]["subject", "subject"]["sender", "sender"]["message", "message"]["collector", "collector"]["footer", "footer"]["splat", ["api/v2/emails"]]["captures", ["api/v2/emails"]]
And Sinatra said:
127.0.0.1 - - [11/Sep/2013 18:04:13] "POST /api/v2/emails?survey=1 HTTP/1.1" 200 - 0.0010
{"survey"=>"1",
"subject"=>"subject",
"sender"=>"sender",
"message"=>"message",
"collector"=>"collector",
"footer"=>"footer",
"splat"=>["api/v2/emails"],
"captures"=>["api/v2/emails"]}
The problem is, the POST request ONLY uses a URL and a :body hash. Inside the :body hash go all the variables you're sending to the server. That's why the second version of the code, with 'collector' and 'footer' works.
There is no comma after your :body parameter
I have a html form on my website that a user fills out. When the user clicks on the submit button I have a controller file that takes all the values from the form and uses them to insert into database. But if there was an error with their input I would like them to be redirected back to form page with an error message that would be on the screen or even redirected to another web page with same background and error message on the screen.
I have not been using ruby on rails for long so was wondering would anyone have any input into how I could do this?
Thanks in advance
Code:
user = User.new(:email => params[:email],
:password => password_gen,
:password_confirmation => password_gen,
:name => params[:name],
:surname => params[:surname],
:phone => params[:phone],
:mobile => params[:mobile])
if #user.save
logger.debug "---------------------------"
logger.debug user.inspect
logger.debug user.errors.inspect
render :json => ["Form submitted ok for user"].to_json()
redirect_to users_path, :notice => "User correctly created"
else
logger.debug user.inspect
logger.debug user.errors.inspect
render :json => ["Error in submitting form"].to_json()
end