Skip to content

fix(notifications): personal webhooks ignore the email switch and include your own changes - #3955

Merged
marcelfolaron merged 2 commits into
masterfrom
fix/personal-webhook-recipients
Oct 20, 2026
Merged

marcelfolaron merged 2 commits into
masterfrom
fix/personal-webhook-recipients

Conversation

@marcelfolaron

Copy link
Copy Markdown
Collaborator

Why

A customer on cloud set up a personal webhook (Profile → Webhooks) and saw nothing arrive. Two rules in the recipient selection could each cause that:

  1. The email checkbox also switched off webhooks. Both the recipient list (Projects::getUsersToNotify) and the delivery check (Webhooks::mayReceiveProjectNotifications) required zp_user.notifications = 1. In the UI that field is "Receive email notifications". So anyone who moved their notifications to a webhook and unticked email got nothing, with no message.
  2. The author was always left out. notifyProjectUsers drops the author before anything is queued. That is right for email, but it means testing a webhook by making changes yourself never fires it. An integration that keeps a record of your work also misses everything you do.

What changes

  • Recipients: webhook recipients now start from the active team plus the author (Projects::personalWebhookCandidates()). They then go through the same relevance, category, mention and collaborator rules as email. Muting a project or switching off a category still stops the webhook, including for your own changes.
  • Email list: unchanged. It still requires the email switch and still excludes the author. It now comes from the same single team query, and preferences are loaded once for the candidates of both channels.
  • Delivery check: Webhooks::mayReceiveProjectNotifications no longer checks the email switch. It still checks that the account exists and is active and that the user has project access.
  • Help text: the webhook help text now says the email switch doesn't affect the webhook and that your own changes are sent. This is updated in all 44 languages.
  • Checkbox label: in 18 translations the "Receive email notifications" label had lost the word "email". It now says email in all of them.

Testing

  • New tests in ProjectsServiceTest:
    • A team member and a mentioned user who both switched email off still get the webhook (and the team member gets no email).
    • The author gets their own change on the webhook but not by email.
    • An author who muted the project gets nothing.
  • Updated tests: the existing dispatch, revocation and service tests now expect the email switch to have no effect on webhooks, and expect the author to be queued.
  • Results: the full unit suite passes (2004 tests). PHPStan and Pint report no errors on the changed files.

Not verified on cloud: I couldn't read the customer's tenant, so I don't know which of the two rules hit them. Both are fixed here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DqVeL6FWt71mr3sFBw3eSQ

…lude your own changes

Personal webhooks only went to users with "Receive email notifications" on, so a user
who moved their notifications to a webhook and switched email off got nothing. The
author of a change was also left out, so testing a webhook with your own edits never
fired it.

Webhook recipients now come from the active team plus the author, filtered by the same
relevance, category, mention and collaborator rules as email. The email switch governs
email only, at queue time and at delivery time. The webhook help text says so in every
language, and the checkbox label now says "email" where translations had dropped it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DqVeL6FWt71mr3sFBw3eSQ
@marcelfolaron
marcelfolaron requested a review from a team as a code owner October 20, 2026 16:40
@marcelfolaron
marcelfolaron requested review from broskees and a balanced review from Copilot and removed request for a team October 20, 2026 16:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The collaborator bypass re-adds authors despite their project mute or category opt-out.

1 open issue
What changed in this PR

This PR separates Leantime’s personal webhooks from email preferences and includes authors’ own changes.

Changes:

  • Separates webhook and email recipient selection while sharing preference loading.
  • Updates delivery and regression tests for email opt-out and author notifications.
  • Clarifies webhook help across 44 languages and email labels in 18 translations.
File Description
tests/​Unit/​app/​Domain/​Projects/​Services/​ProjectsServiceTest.php Tests recipient selection and author delivery.
tests/​Unit/​app/​Domain/​Notifications/​Services/​WebhooksServiceTest.php Updates email opt-out expectations.
tests/​Unit/​app/​Domain/​Notifications/​Services/​WebhookRevocationTest.php Verifies email opt-out preserves delivery.
app/​Language/​zh-TW.ini Clarifies webhook help and email label.
app/​Language/​zh-CN.ini Clarifies webhook help and email label.
app/​Language/​vi-VN.ini Updates webhook help.
app/​Language/​uk-UA.ini Clarifies webhook help and email label.
app/​Language/​tr-TR.ini Updates webhook help.
app/​Language/​sv-SE.ini Updates webhook help.
app/​Language/​sr-SP.ini Updates webhook help.
app/​Language/​sl-SI.ini Updates webhook help.
app/​Language/​sk-SK.ini Updates webhook help.
app/​Language/​ru-RU.ini Clarifies webhook help and email label.
app/​Language/​ro-RO.ini Updates webhook help.
app/​Language/​pt-PT.ini Clarifies webhook help and email label.
app/​Language/​pt-BR.ini Clarifies webhook help and email label.
app/​Language/​pl-PL.ini Updates webhook help.
app/​Language/​no-NO.ini Updates webhook help.
app/​Language/​nl-NL.ini Clarifies webhook help and email label.
app/​Language/​lv-LV.ini Updates webhook help.
app/​Language/​ks-IN.ini Updates webhook help.
app/​Language/​ko-KR.ini Updates webhook help.
app/​Language/​km-KH.ini Updates webhook help.
app/​Language/​kaa.ini Updates webhook help.
app/​Language/​ja-JP.ini Clarifies webhook help and email label.
app/​Language/​it-IT.ini Clarifies webhook help and email label.
app/​Language/​is-IS.ini Updates webhook help.
app/​Language/​id-ID.ini Updates webhook help.
app/​Language/​hu-HU.ini Updates webhook help.
app/​Language/​hr-HR.ini Updates webhook help.
app/​Language/​he-IL.ini Clarifies webhook help and email label.
app/​Language/​fr-FR.ini Clarifies webhook help and email label.
app/​Language/​fr-CH.ini Clarifies webhook help and email label.
app/​Language/​fa-IR.ini Updates webhook help.
app/​Language/​et-EE.ini Updates webhook help.
app/​Language/​es-MX.ini Updates webhook help.
app/​Language/​es-ES.ini Clarifies webhook help and email label.
app/​Language/​es-419.ini Updates webhook help.
app/​Language/​en-US.ini Updates webhook help.
app/​Language/​en-GB.ini Clarifies webhook help and email label.
app/​Language/​el-GR.ini Updates webhook help.
app/​Language/​de-DE.ini Clarifies webhook help and email label.
app/​Language/​de-DE-inf.ini Clarifies webhook help and email label.
app/​Language/​de-CH.ini Clarifies webhook help and email label.
app/​Language/​da-DK.ini Clarifies webhook help and email label.
app/​Language/​cs-CZ.ini Updates webhook help.
app/​Language/​ar-SA.ini Updates webhook help.
app/​Domain/​Projects/​Services/​Projects.php Separates webhook candidates from email recipients.
app/​Domain/​Notifications/​Services/​Webhooks.php Removes email preference from delivery eligibility.

Review effort: Balanced

Comment thread app/Domain/Projects/Services/Projects.php Outdated
…ebhook filters

The collaborator and mention bypasses were given no author, so an author who
collaborates on the to-do came back after their project mute or category opt-out
removed them. Pass the real author: they are a webhook candidate already, and
other collaborators keep the bypass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DqVeL6FWt71mr3sFBw3eSQ
Copilot AI balanced review requested due to automatic review settings October 20, 2026 20:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No unresolved blocking issues remain, and regression coverage addresses channel separation and author-filter enforcement.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@marcelfolaron
marcelfolaron merged commit f6b3f42 into master Oct 20, 2026
13 checks passed
@marcelfolaron
marcelfolaron deleted the fix/personal-webhook-recipients branch October 20, 2026 20:46
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.

2 participants