简体   繁体   中英

Using url_helpers inside lib class in rails 4

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)

Debugging:

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).


Conclusion:

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.


Alternative suggestion:

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM