PHPackages                             brianhenryie/bh-wp-mailboxes - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. brianhenryie/bh-wp-mailboxes

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

brianhenryie/bh-wp-mailboxes
============================

A library for importing emails into WordPress for further processing.

0187[2 issues](https://github.com/BrianHenryIE/bh-wp-mailboxes/issues)[10 PRs](https://github.com/BrianHenryIE/bh-wp-mailboxes/pulls)PHPCI failing

Since Jun 11Pushed 6d ago2 watchersCompare

[ Source](https://github.com/BrianHenryIE/bh-wp-mailboxes)[ Packagist](https://packagist.org/packages/brianhenryie/bh-wp-mailboxes)[ RSS](/packages/brianhenryie-bh-wp-mailboxes/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependenciesVersions (7)Used By (0)

[![WordPress tested 7.0](https://camo.githubusercontent.com/34d00aad7f7158bc581f8855dbc78463801cff881dfbb2f160e352855a7ca09c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f576f726450726573732d76372e302532307465737465642d3030373361612e737667)](https://wordpress.org/plugins/bh-wp-mailboxes) [![PHPCS WPCS](https://camo.githubusercontent.com/504dce428567aedf1d05384c9eac46dcc8a728aa30c7e4c11b8dfc1334883549/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f50485043532d576f72645072657373253230436f64696e672532305374616e64617264732d3838393242462e737667)](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards) [![PHPUnit ](.github/coverage.svg)](https://brianhenryie.github.io/bh-wp-mailboxes/)

BH WP Mailboxes
===============

[](#bh-wp-mailboxes)

A library to download emails into WordPress plugins.

e.g.

- Order payment receipts (Zelle, Venmo etc.)
- Newsletter unsubscribe emails
- Helpdesk
- Post by email

A plugin user should be able to configure an inbox in the plugin settings, the library will download emails on a cron schedule, the library will filter emails to a predicate (e.g. only emails sent by @venmo.com, or a negative filter excluding known irrelevant subjects), the emails are saved to log, then the library fires an action for each new email downloaded. The parent plugin listens for that and acts appropriately, e.g. processes an unsubscribe request, creates a helpdesk ticket, etc.

[![WP List Table of emails](.github/wp-list-table-inbox.png)](.github/wp-list-table-inbox.png)

[![Single Email View](.github/example-email.png)](.github/example-email.png)

The core library this is built around is [zbateson/mail-mime-parser](https://github.com/zbateson/mail-mime-parser) – [mail-mime-parser.org](https://mail-mime-parser.org/).

Goals
-----

[](#goals)

- Handle bad credentials – servers block IPs that have too many bad login attempts, so delay a few hours after each failed attempt, admin\_notice to alert admins of problem (warning -&gt; error)
- Support multiple mailboxes
- Save emails to cpt after filtering
- Autodelete email cpts locally.
- Optionally delete emails from the server after downloading (some email services are still size limited).
- Handle delayed emails. Maybe emails would only be delayed if the IMAP server is down. I just know email has an auto-retry mechanism to keep trying until delivered / 48 hours.

It's almost supposed to be a log of emails fetched whose data is used in plugins, for debugging when downloaded emails don't trigger plugins as expected, e.g. regex no longer matches after email body changes.

### Anti-goals:

[](#anti-goals)

- User-facing UI – the WP\_List\_Table (conventional, extensible) UI is intended for debugging, to allow site admins (shop managers etc.) to see the original emails and to test account settings etc.
- Sending email – use WP core functions for that, i.e. `wp_mail()` with an SMTP plugin. I recommend sending via AWS SES using WP SES plugin

Implementation
--------------

[](#implementation)

Your implementation first needs the `BH_WP_Mailboxes_Settings_Interface` configuration which sets the custom post type names that mailboxes and emails are saved to, and the cron schedules mailboxes will be checked on.

`$mailboxes = BH_WP_Mailboxes::make( $mailboxes_settings, $this->logger );`

Somewhere in your plugin's settings you'll want to add a section for email account settings, e.g. IMAP server, username, password, etc. Some settings will probably be configured by you as a plugin developer, e.g. the number of days before emails are deleted.

Using `API::save_new_mailbox()`, save the account configuration to a `wp_post`. When saving you will set the `connection_type_class`, e.g. `ImapEngine_Imap_Email_Connection`

Add a filter on `bh_wp_mailboxes_credentials` to provide the credentials (this allows abstracting credential storage from the library)

Saved mailboxes are checked on a cron job for new emails. When a new email is downloaded, the library fires `bh_wp_mailboxes_new_email` for you to listen for.
Use the methods on `New_Email_Interface` to read the email, log any action taken, and maybe mark it to be saved

Connection Types
----------------

[](#connection-types)

### IMAP

[](#imap)

`IMAP_Credentials_Interface` requires the server, username, password, and encryption type. Port defaults to 143 or 993 depending on encryption and can be overridden by specifying it with the server name. An `Imap_Credentials_Env` class exists that reads from environmental variables `IMAP_SERVER`, `IMAP_USERNAME`, `IMAP_PASSWORD`, `IMAP_ENCRYPTION`, and those env variable names can be specified in the constructor.

### Cloudflare Email Routing

[](#cloudflare-email-routing)

A Cloudflare Worker is available that forwards all mail received to a WordPress REST endpoint (`example.com/wp-json/.../email-cpt/new`). Enable the REST endpoint by setting `BH_WP_Mailboxes_Settings_Interface::get_rest_namespace()`. Install the Worker with:

[![Deploy to Cloudflare](https://camo.githubusercontent.com/aa3de9a0130879a84691a2286f5302105d5f3554c5d0af4e3f2f24174eeeea25/68747470733a2f2f6465706c6f792e776f726b6572732e636c6f7564666c6172652e636f6d2f627574746f6e)](https://deploy.workers.cloudflare.com/?url=https://github.com/BrianHenryIE/bh-wp-mailboxes-cloudflare-worker)

Then visit the Worker URL provided when Cloudflare finishes installing. There you will:

1. Set a password for the Worker config page for future access
2. Enter the website URL for WordPress and "Continue to WordPress authorization" to grant the Worker an [Application Password](https://developer.wordpress.org/advanced-administration/security/application-passwords/).
3. Set a Cloudflare API token (unsaved) to configure a domain to forward emails to the Worker
4. Optionally set an email address to receive failure alerts

The main limit is that Cloudflare Email Routing must be enabled on the entire domain.

### Gmail

[](#gmail)

Gmail can use regular IMAP via application passwords when the account has 2FA enabled.

To use the Gmail API, see includes/connections/gmail-api/README-GMAIL.md for configuring a Google Developer Console project. I think supporting this in distributed plugins is probably too much work!

WP-CLI
------

[](#wp-cli)

The library registers WP-CLI commands for each mailbox it's used to create. They are namespaced under that mailbox's *CLI base* — `BH_WP_Mailboxes_Settings_Interface::get_cli_base()`, which defaults to the plugin slug. Return `null` from `get_cli_base()` to disable registering CLI commands. Replace `` below with that value.

### `wp  mailboxes list`

[](#wp-cli-base-mailboxes-list)

List every configured mailbox. A "mailbox" is one instance of the library — an emails post type plus its accounts post type — and may contain many email accounts. The row shows the slug, post-type names, friendly name, and account count. Unlike `accounts list` (which is scoped to one mailbox), this spans every registered mailbox.

```
wp  mailboxes list [--format=]
```

### `wp  accounts list`

[](#wp-cli-base-accounts-list)

List the email accounts configured for this mailbox — id, email, display name, connection, active state, and last-checked time.

```
wp  accounts list [--format=]
```

Privacy / GDPR
--------------

[](#privacy--gdpr)

The default setting is to delete emails after 7 days. NB: if you're using a shared inbox for your plugin's purpose (e.g. Venmo receipt emails go to  rather than ) this library will download and save *all* emails (that match the `Email_Account_Settings_Interface::get_from_email_regex()` and `::get_body_identifier_regex()`). You can immediately delete each emails that you know is not relevant, but that is not the default. Emails that are downloaded are saved for debugging, e.g. the format of the Venmo emails changes and regexes that used to work to extract the relevant data no longer work, so you can see the original email in the WP List Table UI. Be aware of this and inform your company's data controller. I am not a lawyer, but I think this is ok!

Extensibility
-------------

[](#extensibility)

// TODO: implement and document filters.

// TODO: find a tool that documents filters and actions in the codebase. Then create a github action that updates the README with that output.

Contributing
------------

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md) for details on contributing to the project. It's easy.

TODO:
-----

[](#todo)

- AWS SES inbound SMTP via SNS
- All exceptions should be caught and displayed as admin\_notices, never thrown (never expect the plugin developer to handle exceptions from the library).

### More Information

[](#more-information)

See [github.com/BrianHenryIE/WordPress-Plugin-Boilerplate](https://github.com/BrianHenryIE/WordPress-Plugin-Boilerplate) for initial setup rationale.

Acknowledgements
================

[](#acknowledgements)

###  Health Score

28

—

LowBetter than 51% of packages

Maintenance65

Regular maintenance activity

Popularity15

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity18

Early-stage or recently created project

 Bus Factor1

Top contributor holds 97.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/4720401?v=4)[Brian Henry](/maintainers/BrianHenryIE)[@BrianHenryIE](https://github.com/BrianHenryIE)

---

Top Contributors

[![BrianHenryIE](https://avatars.githubusercontent.com/u/4720401?v=4)](https://github.com/BrianHenryIE "BrianHenryIE (379 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (9 commits)")

### Embed Badge

![Health badge](/badges/brianhenryie-bh-wp-mailboxes/health.svg)

```
[![Health](https://phpackages.com/badges/brianhenryie-bh-wp-mailboxes/health.svg)](https://phpackages.com/packages/brianhenryie-bh-wp-mailboxes)
```

###  Alternatives

[kx1000/kwota-slownie

Kwota słownie

1019.9k1](/packages/kx1000-kwota-slownie)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
