https://github.com/honeybadger-io/incoming
Incoming! helps you receive email in your Rack apps.
https://github.com/honeybadger-io/incoming
Last synced: 19 days ago
JSON representation
Incoming! helps you receive email in your Rack apps.
- Host: GitHub
- URL: https://github.com/honeybadger-io/incoming
- Owner: honeybadger-io
- License: mit
- Created: 2013-02-17T05:28:30.000Z (about 12 years ago)
- Default Branch: main
- Last Pushed: 2024-07-11T16:58:23.000Z (9 months ago)
- Last Synced: 2025-03-04T18:46:27.700Z (about 1 month ago)
- Language: Ruby
- Homepage: https://www.honeybadger.io/
- Size: 204 KB
- Stars: 308
- Watchers: 15
- Forks: 17
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: MIT-LICENSE
Awesome Lists containing this project
- awesome-ruby - Incoming - Incoming! helps you receive email in your Rack apps. (Email)
README
Incoming!
-----------### Receive email in your Rack apps.
Incoming! receives a `Rack::Request` and hands you a [`Mail::Message`](https://github.com/mikel/mail/), much
like `ActionMailer::Base.receive` does with a raw email. We currently
support the following services:* SendGrid
* Mailgun
* Postmark
* CloudMailin
* Mandrill
* Any mail server capable of routing messages to a system commandBrought to you by :zap: **Honeybadger.io**, painless [Rails exception tracking](https://www.honeybadger.io/).
[](https://travis-ci.org/honeybadger-io/incoming)
[](http://badge.fury.io/rb/incoming)## Installation
1. Add Incoming! to your Gemfile and run `bundle install`:
```ruby
gem "incoming"
```2. Create a new class to receive emails (see examples below)
3. Implement an HTTP endpoint to receive HTTP post hooks, and pass the
request to your receiver. (see examples below)## SendGrid Example
```ruby
class EmailReceiver < Incoming::Strategies::SendGrid
def receive(mail)
%(Got message from #{mail.to.first} with subject "#{mail.subject}")
end
endreq = Rack::Request.new(env)
result = EmailReceiver.receive(req) # => Got message from [email protected] with subject "hello world"
```[Sendgrid API reference](http://sendgrid.com/docs/API_Reference/Webhooks/parse.html)
## Mailgun Example
```ruby
class EmailReceiver < Incoming::Strategies::Mailgun
setup api_key: "asdf"def receive(mail)
%(Got message from #{mail.to.first} with subject "#{mail.subject}")
end
endreq = Rack::Request.new(env)
result = EmailReceiver.receive(req) # => Got message from [email protected] with subject "hello world"
```[Mailgun API reference](http://documentation.mailgun.net/user_manual.html#receiving-messages)
## Postmark Example
```ruby
class EmailReceiver < Incoming::Strategies::Postmark
def receive(mail)
%(Got message from #{mail.to.first} with subject "#{mail.subject}")
end
endreq = Rack::Request.new(env)
result = EmailReceiver.receive(req) # => Got message from [email protected] with subject "hello world"
```[Postmark API reference](http://developer.postmarkapp.com/developer-inbound.html)
## CloudMailin Example
Use the Raw Format when setting up your address target.
```ruby
class EmailReceiver < Incoming::Strategies::CloudMailin
def receive(mail)
%(Got message from #{mail.to.first} with subject "#{mail.subject}")
end
endreq = Rack::Request.new(env)
result = EmailReceiver.receive(req) # => Got message from [email protected] with subject "hello world"
```[CloudMailin API reference](http://docs.cloudmailin.com/http_post_formats/)
## Mandrill Example
Mandrill is capable of sending multiple events in a single webhook, so
the Mandrill strategy works a bit differently than the others. Namely,
the `.receive` method returns an Array of return values from your
`#receive` method for each inbound event in the payload. Otherwise, the
implementation is the same:```ruby
class EmailReceiver < Incoming::Strategies::Mandrill
def receive(mail)
%(Got message from #{mail.to.first} with subject "#{mail.subject}")
end
endreq = Rack::Request.new(env)
result = EmailReceiver.receive(req) # => Got message from [email protected] with subject "hello world"
```[Mandrill API reference](http://help.mandrill.com/entries/22092308-What-is-the-format-of-inbound-email-webhooks-)
## Postfix Example
```ruby
class EmailReceiver < Incoming::Strategies::HTTPPost
setup secret: "6d7e5337a0cd69f52c3fcf9f5af438b1"def receive(mail)
%(Got message from #{mail.to.first} with subject "#{mail.subject}")
end
endreq = Rack::Request.new(env)
result = EmailReceiver.receive(req) # => Got message from [email protected] with subject "hello world"
``````
# /etc/postfix/virtual
@example.com http_post# /etc/mail/aliases
http_post: "|http_post -s 6d7e5337a0cd69f52c3fcf9f5af438b1 http://www.example.com/emails"
```
## Qmail Example:```ruby
class EmailReceiver < Incoming::Strategies::HTTPPost
setup secret: "6d7e5337a0cd69f52c3fcf9f5af438b1"def receive(mail)
%(Got message from #{mail.to.first} with subject "#{mail.subject}")
end
endreq = Rack::Request.new(env)
result = EmailReceiver.receive(req) # => Got message from [email protected] with subject "hello world"
```To setup a *global* incoming email alias:
```
# /var/qmail/alias/.qmail-whoever - mails to whoever@ will be delivered to this alias.
|http_post -s 6d7e5337a0cd69f52c3fcf9f5af438b1 http://www.example.com/emails
```Domain-specific incoming aliases can be set as follows:
```
#/var/qmail/control/virtualdomains
example.com:example#~example/.qmail-whoever
|http_post -s 6d7e5337a0cd69f52c3fcf9f5af438b1 http://www.example.com/emails
```
Now mails to `[email protected]` will be posted to the corresponding URL above. To post all mails for `example.com`, just add the above line to `~example/.qmail-default`.## Example Rails Controller
```ruby
# app/controllers/emails_controller.rb
class EmailsController < ActionController::Base
def create
if EmailReceiver.receive(request)
render json: { status: "ok" }
else
render json: { status: "rejected" }, status: 403
end
end
end
``````ruby
# config/routes.rb
Rails.application.routes.draw do
post "/emails" => "emails#create"
end
``````ruby
# spec/controllers/emails_controller_spec.rb
require "spec_helper"describe EmailsController, "#create" do
it "responds with success when request is valid" do
allow(EmailReceiver).to receive(:receive).and_return(true)
post :create
expect(response.success?).to eq(true)
expect(response.body).to eq(%({"status":"ok"}))
endit "responds with 403 when request is invalid" do
allow(EmailReceiver).to receive(:receive).and_return(false)
post :create
expect(response.status).to eq(403)
expect(response.body).to eq(%({"status":"rejected"}))
end
end
```## TODO
1. Provide authentication for all strategies where possible (currently
only Mailgun requests are authenticated.)## Contributing
1. Fork it.
2. Create a topic branch `git checkout -b my_branch`
3. Commit your changes `git commit -am "Boom"`
3. Push to your branch `git push origin my_branch`
4. Send a [pull request](https://github.com/honeybadger-io/incoming/pulls)## License
Incoming! is free software, and may be redistributed under the terms specified
in the MIT-LICENSE file.