Skip to content

Instantly share code, notes, and snippets.

@beathyate
Created December 24, 2010 07:12
Show Gist options
  • Save beathyate/753991 to your computer and use it in GitHub Desktop.
Save beathyate/753991 to your computer and use it in GitHub Desktop.
Cloudmailin Rails 3 Mongoid CarrierWave GridFS
# config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.storage = :grid_fs
config.grid_fs_access_url = "/files"
config.grid_fs_database = Mongoid.database.name
if Rails.env.production?
config.grid_fs_database = ENV['MONGOID_DATABASE'] || Mongoid.database.name
config.grid_fs_host = ENV['MONGOID_HOST']
config.grid_fs_port = ENV['MONGOID_PORT']
config.grid_fs_username = ENV['MONGOID_USERNAME']
config.grid_fs_password = ENV['MONGOID_PASSWORD']
end
end
source :rubygems
gem 'rails', '3.0.3'
gem 'mongo', '1.1.5'
gem 'bson', '1.1.5'
gem 'bson_ext', '1.1.5'
gem 'mongoid', '2.0.0.beta.20'
gem 'carrierwave'
# app/models/incoming_mail.rb
require 'mail'
class IncomingMail
include Mongoid::Document
include Mongoid::Timestamps
# allowed Mail object methods on IncomingMail instance
ALLOWED_METHODS = %w([] from to cc subject text_part html_part multipart? parts)
mount_uploader :raw_mail, RawMailUploader
def self.new_from_cloudmailin(args)
raw_mail_file = StringIO.new(args[:message])
raw_mail_file.class.class_eval { attr_accessor :original_filename, :content_type }
raw_mail_file.original_filename = args[:subject].present? ? "#{args[:subject].parameterize}.eml" : "untitled.eml"
raw_mail_file.content_type = "message/rfc822"
new(:raw_mail => raw_mail_file)
end
ALLOWED_METHODS.each do |method|
define_method(method) do |args|
mail.send(method, args)
end
end
private
def mail
@mail ||= Mail.new(raw_mail.read)
end
end
# app/controllers/incoming_mails_controller.rb
class IncomingMailsController < ApplicationController
skip_before_filter :verify_authenticity_token
before_filter :verify_signature
SECRET = ENV['CLOUDMAILIN_SECRET'] || ''
def create
message = IncomingMail.new_from_cloudmailin(params)
if message.save
render :text => 'success', :status => 200
else
render :text => 'error', :status => 404
end
end
protected
def verify_signature
provided = request.request_parameters.delete(:signature)
signature = Digest::MD5.hexdigest(request.request_parameters.sort.map{|k,v| v}.join + SECRET)
if provided != signature
render :text => "Message signature fail #{provided} != #{signature}", :status => 403, :content_type => Mime::TEXT.to_s
return false
end
end
end
# app/uploaders/raw_mail_uploader.rb
# encoding: utf-8
class RawMailUploader < CarrierWave::Uploader::Base
def store_dir
"raw_mails/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# heroku tmp folder
def cache_dir
"#{Rails.root}/tmp/raw_mails"
end
end
# config/routes.rb
# add this to your routes
resources :incoming_mails
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment