{"id":16674434,"url":"https://github.com/settermjd/inbound-parser","last_synced_at":"2026-04-27T13:32:39.225Z","repository":{"id":210841893,"uuid":"726025144","full_name":"settermjd/inbound-parser","owner":"settermjd","description":null,"archived":false,"fork":false,"pushed_at":"2023-12-06T00:38:37.000Z","size":143,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-19T20:30:23.239Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/settermjd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2023-12-01T11:25:32.000Z","updated_at":"2023-12-06T11:52:33.000Z","dependencies_parsed_at":"2024-11-18T22:44:57.313Z","dependency_job_id":"fb3400ad-e1c8-4852-9ba5-454c4ecd0155","html_url":"https://github.com/settermjd/inbound-parser","commit_stats":null,"previous_names":["settermjd/inbound-parser"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/settermjd%2Finbound-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/settermjd%2Finbound-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/settermjd%2Finbound-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/settermjd%2Finbound-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/settermjd","download_url":"https://codeload.github.com/settermjd/inbound-parser/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243330319,"owners_count":20274039,"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-10-12T12:43:13.085Z","updated_at":"2025-12-28T13:26:05.366Z","avatar_url":"https://github.com/settermjd.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SendGrid Inbound Email Parser\n\nThis is a small PHP application, built on top of [the Mezzio framework][mezzio-docs], that shows how to work with [SendGrid's Inbound Email Parse Webhook][email-parse-webhook-docs].\n\nIf you're not familiar with the Webhook, here's a quick excerpt from the documentation:\n\n\u003e SendGrid can parse the attachments and contents of incoming emails.\n\u003e The Parse API will (then) POST the parsed email to a URL that you specify. \n\nIn short, when emails are sent to a pre-configured domain, they are received and parsed by the Inbound Email Parse Webhook. \nThis then sends a POST request to an endpoint that you specified in the webhook configuration (which is to your application/API).\n\n## Prerequisites\n\nTo use the application, you need the following:\n\n- PHP 8.1 or 8.2 with the following extensions:\n  - [ctype][ext-ctype]\n  - [dom][ext-dom]\n  - [iconv][ext-iconv]\n  - [json][ext-json]\n  - [libxml][ext-libxml]\n  - [mbstring][ext-mbstring]\n  - [pcre][ext-pcre]\n  - [phar][ext-phar]\n  - [tokenizer][ext-tokenizer]\n  - [xml][ext-xml]\n  - [xmlwriter][ext-xmlwriter]\n  - [The required extension](https://www.doctrine-project.org/projects/doctrine-dbal/en/3.7/reference/platforms.html) for your database of choice\n- [A Twilio Account](https://www.twilio.com/try-twilio) \n- [A SendGrid account](https://signup.sendgrid.com/)\n- A domain that you can use, along with access to the DNS records\n- [ngrok][ngrok-url] and a free ngrok account\n\n## Why was the application written?\n\nThe application was inspired after recent dealings with an Australian government department.\n\nIn short, I had sent the department an application, along with the supporting documentation. \nAfter not hearing anything for nearly four weeks, I called their support centre. \n\nAs it turned out, the application required further supporting documentation, which I had to bring the documentation in to a local office or post it. \nAfter I did that, it would be added to the application, and the application would continue being processed. \n\nI would have _much_ preferred to be able to email the information and have it be included with the application automatically, saving a good amount of time and effort.\n\nSo, in my frustration, I looked around to see if there was any technology which did what I was after.\nIt was then that I learned about SendGrid's Inbound Email Parser.\n\nIt wasn't all that I needed, but allowed me to build a proof of concept, which is what this application is.\n\n## Application overview\n\nThe application creates a note on a user's account (stored in a database), based on the POST data that it receives from SendGrid.\nTo determine the account to update, the email subject has to match one of the following two (case-insensitive) patterns:\n\n- `Reference ID: \u003cReference ID\u003e`\n- `Ref ID: \u003cReference ID\u003e`\n\n`\u003cReference ID\u003e` is a 14 character string that can contain both lower and uppercase letters and any digit between 0 and 9 (inclusive).\n\nIf it does, then the message's body and any attachments are extracted and added as a note on the user's account. \nFollowing that, the user is sent an MMS confirmation that the email has been received and the note created on their account.\nThe MMS lists the names of any attachments found on the email, and includes the message's body as a text file attachment.\nThe attachment is retrieved by calling the application's second route, supplying the new note's id.\n\nIf the email subject doesn't match one of the required patterns, then a JSON response is returned stating this.\n\nThe application has two routes: \n\n- The first (the default) receives POST requests from SendGrid's Inbound Email Parser and creates a note from the email.\n- The second receives GET requests containing a note's ID in the route's path, and returns a text file containing a copy of the email body (message) stored in the note.\n\n## Usage\n\nTo use the application, first, copy _.env.local_ as _.env_.\nThen, from the Twilio Console, set your Twilio Account SID, Auth Token, and phone number as the values for the three variables in _.env_.\nAfter that, [follow the Inbound Parse Webhook setup instructions][inbound-parse-webhook-setup-docs].\n\nWhen that's done, clone the code locally, install PHP's dependencies, and run the database migrations, by running the following commands.\n\n```bash\ngit clone git@github.com:settermjd/inbound-parser.git inbound-parser\n\ncd inbound-parser\n\ncomposer install \\\n    --classmap-authoritative \\\n    --no-ansi \\\n    --no-dev \\\n    --no-interaction \\\n    --no-plugins \\\n    --no-progress \\\n    --no-scripts \\\n    --quiet\n    \ncomposer mezzio doctrine:migrations:migrate\n```\n\nYou'll also have to (manually) add at least one record to the `user` table in the database.\n\nThen, run the following command to start ngrok and have it make port 8080 publicly available on the internet.\n\n```bash\nngrok http 8080\n```\n\nThen, in _config/autoload/app.global.php_, change the value for `baseUrl` to the ngrok Forwarding URL.\n\nFinally, run the following command to run the application:\n\n```bash\nENVIRONMENT=development composer serve\n```\n\nNow, send an email to the email address that you configured with the Inbound Parse Webhook. \nShortly afterward, you should see a new record in the **note** and **attachment** tables in the database. \n\n[email-parse-webhook-docs]: https://docs.sendgrid.com/for-developers/parsing-email/inbound-email \n[inbound-parse-webhook-setup-docs]: https://docs.sendgrid.com/for-developers/parsing-email/setting-up-the-inbound-parse-webhook\n[mezzio-docs]: https://docs.mezzio.dev/\n[ext-ctype]: https://www.php.net/manual/en/intro.ctype.php\n[ext-dom]: https://www.php.net/manual/en/intro.dom.php\n[ext-iconv]: https://www.php.net/manual/en/intro.iconv.php\n[ext-json]: https://www.php.net/manual/en/intro.json.php\n[ext-libxml]: https://www.php.net/manual/en/intro.libxml.php\n[ext-mbstring]: https://www.php.net/manual/en/intro.mbstring.php\n[ext-pcre]: https://www.php.net/manual/en/intro.pcre.php\n[ext-phar]: https://www.php.net/manual/en/intro.phar.php\n[ext-tokenizer]: https://www.php.net/manual/en/intro.tokenizer.php\n[ext-xml]: https://www.php.net/manual/en/intro.xml.php\n[ext-xmlwriter]: https://www.php.net/manual/en/intro.xmlwriter.php\n[ngrok-url]: https://ngrok.com/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsettermjd%2Finbound-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsettermjd%2Finbound-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsettermjd%2Finbound-parser/lists"}