{"id":13483989,"url":"https://github.com/honeybadger-io/incoming","last_synced_at":"2025-12-29T23:55:53.490Z","repository":{"id":6984450,"uuid":"8246551","full_name":"honeybadger-io/incoming","owner":"honeybadger-io","description":"Incoming! helps you receive email in your Rack apps.","archived":false,"fork":false,"pushed_at":"2024-07-11T16:58:23.000Z","size":209,"stargazers_count":308,"open_issues_count":3,"forks_count":17,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-03-04T18:46:27.700Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.honeybadger.io/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/honeybadger-io.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-02-17T05:28:30.000Z","updated_at":"2025-02-27T18:54:28.000Z","dependencies_parsed_at":"2024-06-16T08:22:34.808Z","dependency_job_id":"4ab8441d-e36c-42a9-ac0c-f15082bef9fd","html_url":"https://github.com/honeybadger-io/incoming","commit_stats":{"total_commits":145,"total_committers":12,"mean_commits":"12.083333333333334","dds":0.3172413793103448,"last_synced_commit":"1c96565c217c19147ed203df16a4cac53ef76237"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/honeybadger-io%2Fincoming","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/honeybadger-io%2Fincoming/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/honeybadger-io%2Fincoming/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/honeybadger-io%2Fincoming/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/honeybadger-io","download_url":"https://codeload.github.com/honeybadger-io/incoming/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245871718,"owners_count":20686252,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T17:01:17.644Z","updated_at":"2025-12-29T23:55:53.452Z","avatar_url":"https://github.com/honeybadger-io.png","language":"Ruby","funding_links":[],"categories":["Ruby","Email"],"sub_categories":[],"readme":"Incoming!\n-----------\n\n### Receive email in your Rack apps.\n\nIncoming! receives a `Rack::Request` and hands you a [`Mail::Message`](https://github.com/mikel/mail/), much\nlike `ActionMailer::Base.receive` does with a raw email. We currently\nsupport the following services:\n\n* SendGrid\n* Mailgun\n* Postmark\n* CloudMailin\n* Mandrill\n* Any mail server capable of routing messages to a system command\n\nBrought to you by :zap: **Honeybadger.io**, painless [Rails exception tracking](https://www.honeybadger.io/).\n\n[![Build Status](https://travis-ci.org/honeybadger-io/incoming.png)](https://travis-ci.org/honeybadger-io/incoming)\n[![Gem Version](https://badge.fury.io/rb/incoming.png)](http://badge.fury.io/rb/incoming)\n\n## Installation\n\n1. Add Incoming! to your Gemfile and run `bundle install`:\n\n    ```ruby\n    gem \"incoming\"\n    ```\n\n2. Create a new class to receive emails (see examples below)\n\n3. Implement an HTTP endpoint to receive HTTP post hooks, and pass the\n   request to your receiver. (see examples below)\n\n## SendGrid Example\n\n```ruby\nclass EmailReceiver \u003c Incoming::Strategies::SendGrid\n  def receive(mail)\n    %(Got message from #{mail.to.first} with subject \"#{mail.subject}\")\n  end\nend\n\nreq = Rack::Request.new(env)\nresult = EmailReceiver.receive(req) # =\u003e Got message from whoever@wherever.com with subject \"hello world\"\n```\n\n[Sendgrid API reference](http://sendgrid.com/docs/API_Reference/Webhooks/parse.html)\n\n## Mailgun Example\n\n```ruby\nclass EmailReceiver \u003c Incoming::Strategies::Mailgun\n  setup api_key: \"asdf\"\n\n  def receive(mail)\n    %(Got message from #{mail.to.first} with subject \"#{mail.subject}\")\n  end\nend\n\nreq = Rack::Request.new(env)\nresult = EmailReceiver.receive(req) # =\u003e Got message from whoever@wherever.com with subject \"hello world\"\n```\n\n[Mailgun API reference](http://documentation.mailgun.net/user_manual.html#receiving-messages)\n\n## Postmark Example\n\n```ruby\nclass EmailReceiver \u003c Incoming::Strategies::Postmark\n  def receive(mail)\n    %(Got message from #{mail.to.first} with subject \"#{mail.subject}\")\n  end\nend\n\nreq = Rack::Request.new(env)\nresult = EmailReceiver.receive(req) # =\u003e Got message from whoever@wherever.com with subject \"hello world\"\n```\n\n[Postmark API reference](http://developer.postmarkapp.com/developer-inbound.html)\n\n## CloudMailin Example\n\nUse the Raw Format when setting up your address target.\n\n```ruby\nclass EmailReceiver \u003c Incoming::Strategies::CloudMailin\n  def receive(mail)\n    %(Got message from #{mail.to.first} with subject \"#{mail.subject}\")\n  end\nend\n\nreq = Rack::Request.new(env)\nresult = EmailReceiver.receive(req) # =\u003e Got message from whoever@wherever.com with subject \"hello world\"\n```\n\n[CloudMailin API reference](http://docs.cloudmailin.com/http_post_formats/)\n\n## Mandrill Example\n\nMandrill is capable of sending multiple events in a single webhook, so\nthe Mandrill strategy works a bit differently than the others. Namely,\nthe `.receive` method returns an Array of return values from your\n`#receive` method for each inbound event in the payload. Otherwise, the\nimplementation is the same:\n\n```ruby\nclass EmailReceiver \u003c Incoming::Strategies::Mandrill\n  def receive(mail)\n    %(Got message from #{mail.to.first} with subject \"#{mail.subject}\")\n  end\nend\n\nreq = Rack::Request.new(env)\nresult = EmailReceiver.receive(req) # =\u003e Got message from whoever@wherever.com with subject \"hello world\"\n```\n\n[Mandrill API reference](http://help.mandrill.com/entries/22092308-What-is-the-format-of-inbound-email-webhooks-)\n\n## Postfix Example\n\n```ruby\nclass EmailReceiver \u003c Incoming::Strategies::HTTPPost\n  setup secret: \"6d7e5337a0cd69f52c3fcf9f5af438b1\"\n\n  def receive(mail)\n    %(Got message from #{mail.to.first} with subject \"#{mail.subject}\")\n  end\nend\n\nreq = Rack::Request.new(env)\nresult = EmailReceiver.receive(req) # =\u003e Got message from whoever@wherever.com with subject \"hello world\"\n```\n\n```\n# /etc/postfix/virtual\n@example.com http_post\n\n# /etc/mail/aliases\nhttp_post: \"|http_post -s 6d7e5337a0cd69f52c3fcf9f5af438b1 http://www.example.com/emails\"\n```\n## Qmail Example:\n\n```ruby\nclass EmailReceiver \u003c Incoming::Strategies::HTTPPost\n  setup secret: \"6d7e5337a0cd69f52c3fcf9f5af438b1\"\n\n  def receive(mail)\n    %(Got message from #{mail.to.first} with subject \"#{mail.subject}\")\n  end\nend\n\nreq = Rack::Request.new(env)\nresult = EmailReceiver.receive(req) # =\u003e Got message from whoever@wherever.com with subject \"hello world\"\n```\n\nTo setup a *global* incoming email alias:\n\n```\n# /var/qmail/alias/.qmail-whoever - mails to whoever@ will be delivered to this alias.\n|http_post -s 6d7e5337a0cd69f52c3fcf9f5af438b1 http://www.example.com/emails\n```\n\nDomain-specific incoming aliases can be set as follows:\n\n```\n#/var/qmail/control/virtualdomains\nexample.com:example\n\n#~example/.qmail-whoever\n|http_post -s 6d7e5337a0cd69f52c3fcf9f5af438b1 http://www.example.com/emails\n```\nNow mails to `whoever@example.com` will be posted to the corresponding URL above. To post all mails for `example.com`, just add the above line to `~example/.qmail-default`.\n\n## Example Rails Controller\n\n```ruby\n# app/controllers/emails_controller.rb\nclass EmailsController \u003c ActionController::Base\n  def create\n    if EmailReceiver.receive(request)\n      render json: { status: \"ok\" }\n    else\n      render json: { status: \"rejected\" }, status: 403\n    end\n  end\nend\n```\n\n```ruby\n# config/routes.rb\nRails.application.routes.draw do\n  post \"/emails\" =\u003e \"emails#create\"\nend\n```\n\n```ruby\n# spec/controllers/emails_controller_spec.rb\nrequire \"spec_helper\"\n\ndescribe EmailsController, \"#create\" do\n  it \"responds with success when request is valid\" do\n    allow(EmailReceiver).to receive(:receive).and_return(true)\n    post :create\n    expect(response.success?).to eq(true)\n    expect(response.body).to eq(%({\"status\":\"ok\"}))\n  end\n\n  it \"responds with 403 when request is invalid\" do\n    allow(EmailReceiver).to receive(:receive).and_return(false)\n    post :create\n    expect(response.status).to eq(403)\n    expect(response.body).to eq(%({\"status\":\"rejected\"}))\n  end\nend\n```\n\n## TODO\n\n1. Provide authentication for all strategies where possible (currently\n   only Mailgun requests are authenticated.)\n\n## Contributing\n\n1. Fork it.\n2. Create a topic branch `git checkout -b my_branch`\n3. Commit your changes `git commit -am \"Boom\"`\n3. Push to your branch `git push origin my_branch`\n4. Send a [pull request](https://github.com/honeybadger-io/incoming/pulls)\n\n## License\n\nIncoming! is free software, and may be redistributed under the terms specified\nin the MIT-LICENSE file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoneybadger-io%2Fincoming","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoneybadger-io%2Fincoming","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoneybadger-io%2Fincoming/lists"}