{"id":13462984,"url":"https://github.com/thoughtbot/griddler","last_synced_at":"2025-09-29T02:32:35.354Z","repository":{"id":5228467,"uuid":"6405017","full_name":"thoughtbot/griddler","owner":"thoughtbot","description":"Simplify receiving email in Rails (deprecated)","archived":true,"fork":false,"pushed_at":"2024-07-12T18:58:16.000Z","size":592,"stargazers_count":1375,"open_issues_count":0,"forks_count":199,"subscribers_count":56,"default_branch":"main","last_synced_at":"2025-01-01T04:50:09.448Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://griddler.io/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"Ultimaker/CuraEngine","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thoughtbot.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":"CONTRIBUTING.md","funding":null,"license":"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":"2012-10-26T14:27:49.000Z","updated_at":"2024-10-28T16:03:54.000Z","dependencies_parsed_at":"2024-01-08T17:13:34.286Z","dependency_job_id":"354eb437-b5fa-4925-9f4d-88cea63686da","html_url":"https://github.com/thoughtbot/griddler","commit_stats":{"total_commits":304,"total_committers":76,"mean_commits":4.0,"dds":0.875,"last_synced_commit":"2ae3a99b8c59d8c68adffd6e109b1b83fd32f26e"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fgriddler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fgriddler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fgriddler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fgriddler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thoughtbot","download_url":"https://codeload.github.com/thoughtbot/griddler/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234583683,"owners_count":18856280,"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-31T13:00:43.371Z","updated_at":"2025-09-29T02:32:34.966Z","avatar_url":"https://github.com/thoughtbot.png","language":"Ruby","readme":"## Deprecated as of June 6, 2024\n\nGriddler has been deprecated in favor of [ActionMailbox](https://guides.rubyonrails.org/action_mailbox_basics.html) since this is built into Rails now.\n\nGriddler\n========\n\n### Receive emails in your Rails app\n\nGriddler is a Rails engine that provides an endpoint for services that convert\nincoming emails to HTTP POST requests. It parses these POSTs and hands off a\nbuilt email object to a class implemented by you.\n\nTutorials\n---------\n\n* SendGrid wrote a\n  [great tutorial](https://sendgrid.com/blog/receiving-email-in-your-rails-app-with-griddler/)\n  on integrating Griddler with your application.\n* We have our own blog post on the subject over at\n  [Giant Robots](https://robots.thoughtbot.com/griddler-is-better-than-ever).\n\nInstallation\n------------\n\n1. Add `griddler` and an [adapter] gem to your application's Gemfile\n   and run `bundle install`.\n\n   [adapter]: #adapters\n\n2. A route is needed for the endpoint which receives `POST` messages. To add the\n   route, in `config/routes.rb` you may either use the provided routing method\n   `mount_griddler` or set the route explicitly. Examples:\n\n   ```ruby\n   # config/routes.rb\n\n   # mount using default path: /email_processor\n   mount_griddler\n\n   # mount using a custom path\n   mount_griddler('/email/incoming')\n\n   # the DIY approach:\n   post '/email_processor' =\u003e 'griddler/emails#create'\n   ```\n\n### Configuration Options\n\nAn initializer can be created to control some of the options in Griddler.\nDefaults are shown below with sample overrides following. In\n`config/initializers/griddler.rb`:\n\n```ruby\nGriddler.configure do |config|\n  config.processor_class = EmailProcessor # CommentViaEmail\n  config.email_class = Griddler::Email # MyEmail\n  config.processor_method = :process # :create_comment (A method on CommentViaEmail)\n  config.reply_delimiter = '-- REPLY ABOVE THIS LINE --'\n  config.email_service = :sendgrid # :cloudmailin, :postmark, :mandrill, :mailgun\nend\n```\n\n| Option             | Meaning\n| ------             | -------\n| `processor_class`  | The class Griddler will use to handle your incoming emails.\n| `email_class`      | The class Griddler will use to represent an incoming e-mail. It must support an initializer that receives a hash as the only argument. We recommend inheriting it from Griddler::Email or checking this class to see all the methods it responds to.\n| `processor_method` | The method Griddler will call on the processor class when handling your incoming emails.\n| `reply_delimiter`  | The string searched for that will split your body. You can also supply an array of string - useful if you need translated versions of the delimiter\n| `email_service`    | Tells Griddler which email service you are using. The supported email service options are `:sendgrid` (the default), `:cloudmailin` (expects multipart format), `:postmark`, `:mandrill` and `:mailgun`. You will also need to have an appropriate [adapter] gem included in your Gemfile.\n\nBy default Griddler will look for a class named `EmailProcessor`. The class is\ninitialized with a `Griddler::Email` instance representing the incoming\nemail, and has a `process` method to actually process the email.\nFor example, in `./lib/email_processor.rb`:\n\n```ruby\nclass EmailProcessor\n  def initialize(email)\n    @email = email\n  end\n\n  def process\n    # all of your application-specific code here - creating models,\n    # processing reports, etc\n\n    # here's an example of model creation\n    user = User.find_by_email(@email.from[:email])\n    user.posts.create!(\n      subject: @email.subject,\n      body: @email.body\n    )\n  end\nend\n```\n\nGriddler::Email attributes\n--------------------------\n\n| Attribute      | Description\n| -------------- | -----------\n| `#to`          | An array of hashes containing recipient address information.  See [Email Addresses](#email-addresses) for more information.\n| `#from`        | A hash containing the sender address information.\n| `#cc`          | An array of hashes containing cc email address information.\n| `#subject`     | The subject of the email message.\n| `#body`        | The full contents of the email body **unless** there is a line in the email containing the string `-- REPLY ABOVE THIS LINE --`. In that case `.body` will contain everything before that line.\n| `#raw_text`    | The raw text part of the body.\n| `#raw_html`    | The raw html part of the body.\n| `#raw_body`    | The raw body information provided by the email service.\n| `#attachments` | An array of `File` objects containing any attachments.\n| `#headers`     | A hash of headers parsed by `Mail::Header`, unless they are already formatted as a hash when received from the adapter in which case the original hash is returned.\n| `#raw_headers` | The raw headers included in the message.\n| `#to_h`        | A hash of the above attributes.\n\n### Email Addresses\n\nGridder::Email provides email addresses as hashes. Each hash will have the following\ninformation of each recipient:\n\n| Key | Value\n| --- | -----\n| `:token` | All the text before the email's \"@\". We've found that this is the most often used portion of the email address and consider it to be the token we'll key off of for interaction with our application.\n| `:host` | All the text after the email's \"@\". This is important to filter the recipients sent to the application vs emails to other domains. More info below on the Upgrading to 0.5.0 section.\n| `:email` | The email address of the recipient.\n| `:full` | The whole recipient field (e.g., `Some User \u003chello@example.com\u003e`).\n| `:name` | The name of the recipient (e.g., `Some User`).\n\nTesting In Your App\n-------------------\n\nYou may want to create a factory for when testing the integration of Griddler\ninto your application. If you're using factory\\_girl this can be accomplished\nwith the following sample factory:\n\n```ruby\nfactory :email, class: OpenStruct do\n  # Assumes Griddler.configure.to is :hash (default)\n  to { [{ full: 'to_user@email.com', email: 'to_user@email.com', token: 'to_user', host: 'email.com', name: nil }] }\n  from { { token: 'from_user', host: 'email.com', email: 'from_email@email.com', full: 'From User \u003cfrom_user@email.com\u003e', name: 'From User' } }\n  subject { 'email subject' }\n  body { 'Hello!' }\n  attachments { '0' }\n\n  trait :with_attachment do\n    attachments {[\n      ActionDispatch::Http::UploadedFile.new({\n        filename: 'img.png',\n        type: 'image/png',\n        tempfile: File.new(\"#{File.expand_path(File.dirname(__FILE__))}/fixtures/img.png\")\n      })\n    ]}\n  end\nend\n```\n\nBear in mind, if you plan on using the `:with_attachment` trait, that this\nexample assumes your factories are in `spec/factories.rb` and you have\nan image file in `spec/fixtures/`.\n\nTo use it in your tests, build with `email = build(:email)`\nor `email = build(:email, :with_attachment)`.\n\nAdapters\n--------\n\nDepending on the service you want to use Griddler with, you'll need to add an\nadapter gem in addition to `griddler`.\n\n| Service     | Adapter\n| -------     | -------\n| sendgrid    | [griddler-sendgrid]\n| cloudmailin | [griddler-cloudmailin]\n| mandrill    | [griddler-mandrill]\n| mailgun     | [griddler-mailgun]\n| postmark    | [griddler-postmark]\n| sparkpost   | [griddler-sparkpost]\n| ses (amazon)| [griddler-amazon_ses]\n\n[griddler-sendgrid]: https://github.com/thoughtbot/griddler-sendgrid\n[griddler-cloudmailin]: https://github.com/thoughtbot/griddler-cloudmailin\n[griddler-mandrill]: https://github.com/wingrunr21/griddler-mandrill\n[griddler-mailgun]: https://github.com/bradpauly/griddler-mailgun\n[griddler-postmark]: https://github.com/r38y/griddler-postmark\n[griddler-sparkpost]: https://github.com/PrestoDoctor/griddler-sparkpost\n[griddler-amazon_ses]: https://github.com/ccallebs/griddler-amazon_ses\n\nWriting an Adapter\n------------------\n\nGriddler can theoretically work with any email =\u003e POST service. In order to work\ncorrectly, adapters need to have their POST parameters restructured.\n\n`Griddler::Email` expects certain parameters to be in place for proper parsing\nto occur. When writing an adapter, ensure that the `normalized_params` method of\nyour adapter returns a hash with these keys:\n\n| Parameter      | Contents\n| ---------      | --------\n| `:to`          | The recipient field\n| `:from`        | The sender field\n| `:subject`     | Email subject\n| `:text`        | The text body of the email\n| `:html`        | The html body of the email, or an empty string\n| `:attachments` | Array of attachments to the email. Can be an empty array.\n| `:headers`     | The raw headers of the email. **Optional**.\n| `:charsets`    | A JSON string containing the character sets of the fields extracted from the message. **Optional**.\n\nAll keys are required unless otherwise stated.\n\nAdapters should be provided as gems. If you write an adapter, let us know and we\nwill add it to this README. See [griddler-sendgrid] for an example\nimplementation.\n\nCredits\n-------\n\nGriddler was written by Caleb Hearth and Joel Oliveira.\n\nThanks to our [contributors](https://github.com/thoughtbot/griddler/contributors)!\n\n\u003c!-- START /templates/footer.md --\u003e\n## About thoughtbot\n\n![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)\n\nThis repo is maintained and funded by thoughtbot, inc.\nThe names and logos for thoughtbot are trademarks of thoughtbot, inc.\n\nWe love open source software!\nSee [our other projects][community].\nWe are [available for hire][hire].\n\n[community]: https://thoughtbot.com/community?utm_source=github\n[hire]: https://thoughtbot.com/hire-us?utm_source=github\n\n\u003c!-- END /templates/footer.md --\u003e\n","funding_links":[],"categories":["Communication","Ruby","Email"],"sub_categories":["E-Mail Processing"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtbot%2Fgriddler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthoughtbot%2Fgriddler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtbot%2Fgriddler/lists"}