Reputation: 83
In my rails app a lib class is used to recieve emails. The email reciever class parses the email and post it to a application controller using a HTTP response. The code for this is as shown :
uri = 'http://localhost:3000/incoming_mail'
body = {'from'=> from, 'to' => to, 'subject' => subject, 'message' => message}
response = Net::HTTP::post_form(URI.parse(uri), body)
The problem is I don't want to specify the complete URL. Is there any way to use 'incoming_mail_path' instead of 'localhost:3000/incoming_mail' ? I tried to add :
include Rails.application.routes.url_helpers
But this is not working and gives the following error :
<class:EmailReceiver>': uninitialized constant EmailReceiver::Rails (NameError)
Can anyone please suggest a solution for this.
I am posting the entire class here(Updated the class with include statement):
require 'mail'
require 'net/https'
require 'net/http'
require 'uri'
class EmailReceiver
include Rails.application.routes.url_helpers
attr_accessor :url
def initialize
end
def submit(content)
mail = Mail.read_from_string(content)
body = mail.body.decoded
from = mail.from.first
to = mail.to.first
subject = mail.subject
if mail.multipart?
part = mail.parts.select { |p| p.content_type =~ /text\/plain/ }.first rescue nil
unless part.nil?
message = part.body.decoded
end
else
message = mail.decoded
end
unless message.nil?
uri = incoming_mail_url
#uri = 'http://localhost:3000/incoming_mail'
body = {'from'=> from, 'to' => to, 'subject' => subject, 'message' => message}
response = Net::HTTP::post_form(URI.parse(uri), body)
end
end
end
handler = EmailReceiver.new
handler.submit(STDIN.read)
Upvotes: 3
Views: 1043
Reputation: 3597
After reading your comments, i figured out that you are running it as a ruby script which does't even recognize Rails.
Before figuring out how to include all the requirements to the file. I tried to run the file through rails environment (while the server was already running) by:
cat sample.email | bundle exec rails runner "eval(File.read 'lib/email_receiver.rb')"
I got the error for the incoming_mail_url
:
Missing host to link to! Please provide the :host parameter,
set default_url_options[:host], or set :only_path to true (ArgumentError)
While the incoming_mail_path
successfully executed /incoming_mail
(which is not what you need).
This means that what ever you do, as long as you don't run the file from the server (ex: initializers) then the host will never exist.
When you run this module from your server, its going to recogize the route
through the url_helpers
that you have included.
Griddler gem is a Rails engine that provides an endpoint for services that convert incoming emails to HTTP POST requests. It parses these POSTs and hands off a built email object to a class implemented by you.
Upvotes: 2
Reputation: 746
To solve your immediate problem you may want to try to unscope your include statement. Right now it seems that interpreter thinks that "Rails" is a class within the EmailReceiver namespace. if you Add :: to the include statement it should reference "Rails" at the top level which is what you want.
It should work, but there maybe something else wrong in your setup that is causing you to have use this otherwise unnecessary workaround
Edit What I meant by add "::" just to clarify
include ::Rails.application.routes.url_helpers
Upvotes: 0