Skip to content

Add opt-in email digest for newly approved plugins - #480

Open
lessevv wants to merge 1 commit into
NativePHP:mainfrom
lessevv:plugin-approval-email-digest
Open

Add opt-in email digest for newly approved plugins#480
lessevv wants to merge 1 commit into
NativePHP:mainfrom
lessevv:plugin-approval-email-digest

Conversation

@lessevv

@lessevv lessevv commented Aug 21, 2026

Copy link
Copy Markdown

What

Adds an admin-triggered way to email subscribers about newly approved plugins as a single combined digest, instead of one email per plugin.

  • New new_plugin_notified_at column on plugins tracks which approved plugins haven't been included in an email digest yet (Plugin::pendingNewPluginNotification() scope).
  • New NewPluginsAvailable notification (mail + database) that covers one or many plugins in a single message.
  • New SendPendingPluginEmailDigest job: batches everything pending into one email per subscriber, excluding each recipient's own plugins from their own digest.
  • New "Email Subscribers (N)" header action on the admin Plugins list, visible only when there's something pending, that dispatches the job.
  • plugins:resend-new-plugin-notifications now sends the same batched notification, so resending for named plugins is one combined email instead of one per plugin — signature, validation, and --dry-run behaviour are unchanged.

Why

#476 moved automatic new-plugin announcements to in-app only, so nobody gets emailed on every single approval anymore — which fixed the spam problem, but also removed any way to email people about new plugins at all. That PR's own description flagged this as a follow-up:

If we want to keep a manual "email people about a batch of new plugins" escape hatch, it needs its own notification class; it can't share this one any more.

This PR is that escape hatch: an admin can review what's piled up (the action label shows the count) and send one email covering everything at once, rather than either spamming per-approval or having no email option at all.

What this does not change

  • Plugin::approve() — untouched. It still dispatches SendNewPluginNotifications for the automatic in-app notification, same as after Stop emailing everyone on every plugin approval #476.
  • NewPluginAvailable / SendNewPluginNotifications — untouched. They remain the automatic, in-app-only, per-approval path.
  • PluginApproved (the author's own "your plugin was approved" email) — untouched.

Tests

  • tests/Feature/Jobs/SendPendingPluginEmailDigestTest.php — digest content, opt-out/unverified exclusion, own-plugin exclusion per recipient, marks plugins notified, idempotent on already-notified plugins, no-op when nothing pending.
  • tests/Feature/Notifications/NewPluginsAvailableTest.php — via(), mail subject/content for one vs many plugins, database payload, unsubscribe link.
  • tests/Feature/Filament/SendPendingNewPluginNotificationsActionTest.php — action visibility and job dispatch.
  • tests/Feature/ResendNewPluginNotificationsTest.php — updated for the new notification class; added coverage for the combined-digest behaviour and for marking plugins as notified.

🤖 Generated with Claude Code

Plugin approvals now announce in-app only (NativePHP#476), so subscribers no
longer get flooded with mail on every single approval. This adds back
an explicit, admin-triggered way to email people about new plugins
without returning to one-email-per-approval.

A `new_plugin_notified_at` column on plugins tracks which approved
plugins haven't been included in an email digest yet. A new
`NewPluginsAvailable` notification (mail + database) covers one or
many plugins in a single message. `SendPendingPluginEmailDigest`
batches everything pending into one email per subscriber, excluding
each recipient's own plugins from their own digest.

An "Email Subscribers (N)" action on the admin Plugins list dispatches
the job manually. `plugins:resend-new-plugin-notifications` is
switched to the same batched notification so resending for named
plugins also sends one combined email instead of one per plugin,
keeping its existing signature, validation, and dry-run behaviour.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant