本文へ移動
cccskills
無料GitHub で公開

chatter-notification-tuning

Use when admins are reducing Chatter signal-to-noise across an org — covers org-level Chatter Email Settings, per-user Email Settings preferences, group-level email digest frequency (Daily / Weekly / Every post / Never), bell-icon Custom Notifications vs Chatter feed-post tradeoffs, automated-feed suppression on record types via Feed Tracking config, and the Chatter Settings org defaults that control whether new users start with everything-on. Triggers: 'chatter feed full of automated posts nobody reads', 'users complain about chatter email volume', 'turn off chatter notifications for a specific group', 'change default chatter digest frequency', 'stop process builder posts from filling the feed', 'NotificationFrequency invalid value', 'ChatterEmailsMD.settings will not deploy', 'custom notification recipient limit'. NOT for Custom Notifications API design (use apex/apex-custom-notifications-from-apex), NOT for Connect API / Chatter REST API integration patterns (use apex/apex-connect-api-chatter), NOT for Chatter group lifecycle, archiving, ownership and unlisted-group governance (use admin/chatter-group-governance).

インストール方法を見る

含まれるファイル(8)

  • SKILL.md22.0 KB
  • references/examples.md13.8 KB
  • references/gotchas.md17.0 KB
  • references/llm-anti-patterns.md10.7 KB
  • references/metadata-examples.md20.2 KB
  • references/well-architected.md9.4 KB
  • scripts/check_chatter_notification_tuning.py26.2 KB
  • templates/chatter-notification-tuning-template.md3.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Chatter Notification Tuning

Activate this skill when an admin needs to reduce Chatter feed noise, lower email volume, or rebalance the notification surface across Chatter feed posts, Custom Notifications (bell), and email. The skill is about governance of the notification channel — not authoring new automation.

Group lifecycle — creation policy, archiving, ownership transfer, unlisted groups — belongs to admin/chatter-group-governance. That skill governs which groups exist; this one governs what is noisy inside them.


Before Starting

Gather this context before proposing changes:

  • Where the noise comes from. Do not guess this; the answer is one query and it changes everything downstream. SELECT Type, COUNT(Id) FROM FeedItem WHERE CreatedDate = LAST_N_DAYS:30 GROUP BY Type — direct FeedItem queries need the View All Data permission (object_reference.txt L136505–136507). Three sources, three different fixes:
    • Automated feed posts — Flow chatterPost action calls (api_meta.txt L68655), Apex FeedItem inserts. These show as TextPost from a small set of CreatedById values.
    • Feed Tracking — shows as TrackedChange, "a change or group of changes to a tracked field" (object_reference.txt L136377–136378).
    • Group activity and approvals — human TextPost, and ApprovalPost when enableApprovalRequest is on (api_meta.txt L112490–112496).
  • Who can actually make the change. Two permissions gate most of this work. CollaborationGroupMember.NotificationFrequency "can only be set by the member or users with the 'Modify All Data' permission" (object_reference.txt L67510–67513) — group ownership is not enough. Direct FeedItem queries need View All Data. Confirm both before planning a bulk change.
  • What the four frequencies are. The whole design space is P (on every post), D (Daily), W (Weekly), N (Never) — object_reference.txt L67515–67518. There is no Limited. A plan built on "email me only for @mentions and threads I already joined" is built on a value the platform does not have; see references/gotchas.md gotcha 1 before you promise anyone a volume number.
  • Do you have Custom Notifications? CustomNotificationType is deployable metadata, available in API version 46.0 and later (api_meta.txt L41785), with desktop and mobile as its only delivery channels (L41802–41812). If the org has never used it, migrating high-volume automated feed posts to the bell is the most-leveraged move available.
  • Is digital experiences enabled? FeedItem.Visibility exists only "in API version 26.0 and later, if digital experiences is enabled for your org" (object_reference.txt L136412–136414). In an org without it, code that sets Visibility unconditionally breaks, and the internal/external exposure question does not arise.

Questions to Ask Before Configuring

Ask these before touching Setup, writing XML, or staging a CSV. Each one maps to a gotcha that turns a reasonable-looking tuning change into a change that fails, reverses itself, or overrides someone's deliberate choice.

AskWhy it mattersWhat a good answer adds
"Which channel is loud — the feed, the inbox, or the bell?"They are three different data stores with three different fixes; EntitySubscription (follows), CollaborationGroupMember (digests) and Messaging.CustomNotification (bell) share nothing but a complaintThe one surface to work on, instead of a plan that touches all three and cannot be measured
"Who is running the bulk change, and do they hold Modify All Data?"NotificationFrequency can only be set by the member or a Modify All Data holder (L67510–67513); a group owner's load fails per rowEither a named runner, or the decision to change only User.DefaultGroupNotificationFrequency and ask members to change their own
"Which of P / D / W / N is the intended default, and if it is P, why?"P self-disables above 10,000 members in a site and silently switches everyone to Daily (L67519–67522)A written justification the checker's CNT-POLICY-EVERYPOST will stop demanding, or a switch to D before that decision gets made for you
"Is the volume automated or human?"An 800-post Flow is not a digest problem — no frequency setting makes those posts worth readingThe routing decision between migrating a chatterPost action (examples § 3) and tuning frequency (examples § 2)
"Are we changing what new joins inherit, or rewriting existing members' choices?"User.DefaultGroupNotificationFrequency applies "when the user joins groups" (L295160–295163) and is not retroactive; rewriting CollaborationGroupMember rows overrides choices people madeTwo separate changes with two separate consent stories, rather than one that quietly does both
"Does this org have digital experiences enabled?"FeedItem.Visibility only exists if it does (L136412–136414), and for record posts it already defaults to InternalUsers (L136430–136431)Whether the external-exposure audit is real work or a wild goose chase
"What does 'quiet enough' look like, and against which number?"Without a before-measurement the change cannot be defended or reversed on evidenceThe 30-day FeedItem-by-Type baseline that step 7 re-runs against

What a proper configuration adds over just doing it: the org gets a notification policy that is written down, linted against the real group population and the real enum, deployed from source control, and measured against a before-baseline — instead of a one-off Setup change that nobody can explain in six months, built on a frequency value that does not exist, applied by someone whose permissions silently dropped half the rows.


Core Concepts

Concept 1 — Four control surfaces, and only two of them are metadata

SurfaceWhere it livesWhat it controlsSource
ChatterSettingssettings/Chatter.settings-meta.xmlenableChatter, enableApprovalRequest, feed presentationapi_meta.txt L112452–112648
ChatterEmailsMDSettingssettings/ChatterEmailsMD.settings-meta.xmlthe collaboration-email master switch, digest scheduling mode, email-to/reply-to-ChatterL112368–112445
User fieldsdata — Data Loader / DMLpersonal digest frequency, inherited group frequency, every per-event emailobject_reference.txt L295156–295207, L296132–296300
CollaborationGroupMember.NotificationFrequencydata — Data Loader / DMLone member's digest frequency in one groupL67503–67540

Two consequences follow from that table, and both are load-bearing.

There is no org-level default digest frequency. ChatterEmailsMDSettings has ten boolean elements and none of them is a frequency (L112383–112418). What new users inherit is the defaulted-on-create value of User.DefaultGroupNotificationFrequency: N, "but for Professional, Enterprise, Unlimited, and Developer Edition organizations that existed before API version 22.0, the default value remains D" (L295165–295172). In a long-lived Enterprise org, every new hire is inheriting a daily digest that nobody chose.

The only org-wide email lever is binary. enableCollaborationEmail — "whether collaboration email notifications can be sent (true) or not (false)" (L112391–112392). Setting it false makes every preference below it inert. It ends the complaint by ending the channel; treat it as a decision about whether the org uses Chatter email at all, not as a volume dial.

Concept 2 — Feed Tracking is what makes records noisy, and its failure modes are not the folklore ones

Feed Tracking is two elements that must travel together: enableFeeds on the object (api_meta.txt L42035–42039) and trackFeedHistory on each field, where "to set this field to true, the enableFeeds field on the associated CustomObject must also be true" (L43668–43672). Deploying the fields without the object is the most common failure, and the bundled checker raises CNT-TRACK-NO-FEEDS on it.

Two real failure modes, and one that gets blamed but cannot happen:

  1. Roll-up and formula fields. These recompute on dependent updates, so they generate feed activity with no human event behind it — the highest-yield removals when they are present. UNVERIFIED (2026-09-05): no supplied guide states whether roll-up summary or formula fields accept trackFeedHistory at all; the only documented eligibility restriction covers standard fields (L2164–2167). Read the retrieved *.field-meta.xml files for trackFeedHistory rather than assuming this category exists in the org in front of you.
  2. Whole-object tracking where a record type would do. recordTypeTrackFeedHistory (L42234–42241) scopes feed tracking to one record type, with the same enableFeeds prerequisite. When one integration-fed record type is the noise source, this is the surgical cut.
  3. Not LastModifiedDate. System fields "such as CreatedById or LastModifiedDate" are not eligible for feed tracking at all (L2164–2167). Anyone who reports finding it tracked is misremembering; sending an admin to look for that checkbox costs credibility.

Expect a smaller volume drop than the field-count drop suggests: a TrackedChange is "a change or group of changes to a tracked field" (object_reference.txt L136377–136378), so several fields changed in one save can collapse into one feed item.

Concept 3 — Custom Notifications (bell) vs Chatter feed posts

GoalUse
Targeted, transient alert ("your case was reassigned")Custom Notification (bell). No FeedItem written. Desktop and/or mobile channel.
Durable record of an event ("approval rejected on Opp #4567")Chatter FeedItem. Preserves the audit trail; ApprovalPost and TrackedChange types exist for exactly this.
Broadcast announcement ("system maintenance Sunday")Custom Notification with a GroupId or QueueId recipient, NOT a feed post on user records.
Process telemetry ("flow completed successfully")NEITHER. Email alert or a dashboard. Chatter is not a logging channel.

The migration is one actionType swap in the Flow — chatterPost (api_meta.txt L68655) to customNotificationAction, "available in API version 46.0 and later" (L68710) — plus a deployed CustomNotificationType. A Flow posting a feed item on every Closed Won produces thousands of FeedItem rows a year; the bell reaches the same people and writes none.

Two limits shape the recipient design. Messaging.CustomNotification.send() takes at most 500 values (apexrefguide.txt L166776–166778) — not 2,000 — but a single GroupId or QueueId counts as one value and expands to every active member (L166766–166776), which collapses most large fan-outs to a set of size one. And send() requires the Send Custom Notifications permission, failing without it (L166591–166594).

Concept 4 — Choosing among four frequencies, with N as the honest default

The design space is P / D / W / N (object_reference.txt L67515–67518). Match it to group purpose rather than reaching for one org-wide answer:

Group purposeFrequencyWhy
Broadcast / announcement (IsBroadcast = true)DLow post rate, high must-read; a daily digest is the whole point
Active project groupWA heartbeat that says "this is still moving" without an inbox per thread
Social / interest groupNPeople read these when they choose to; pushing them is what generates the complaint
Genuinely urgent, small, boundedPOnly with a written reason — and only if the group cannot grow past 10,000 members, above which P self-disables and everyone is switched to Daily (L67519–67522)

The org-wide question is a different one: what should a new member inherit? That is User.DefaultGroupNotificationFrequency, and N is both the platform's own current default (L295165–295168) and the defensible choice — it makes every noisier setting a decision somebody made rather than a default nobody noticed.


Recommended Workflow

  1. Measure before you plan. Run the 30-day FeedItem-by-Type query in references/metadata-examples.md § 8 as a View All Data holder. The dominant Type routes the rest of this workflow, and the number is the baseline step 7 re-runs against. Record both in templates/chatter-notification-tuning-template.md § 1.

  2. Retrieve the metadata baseline and lint it.

    sf project retrieve start --metadata Settings:Chatter Settings:ChatterEmailsMD --target-org prod-audit
    python3 scripts/check_chatter_notification_tuning.py --manifest-dir force-app/main/default
    

    Two findings stop everything else. CNT-SETTINGS-ELEMENT means the file in source control contains an element the guide does not document, so nothing in it will deploy. CNT-EMAIL-MASTER means enableCollaborationEmail is already false — the channel is off, and whatever people are complaining about is not Chatter email. references/metadata-examples.md §§ 1–2 carry the deployable shapes.

  3. Prune Feed Tracking, if step 1 said TrackedChange. Remove roll-up and formula fields first; consider recordTypeTrackFeedHistory before removing tracking wholesale. Package the .object-meta.xml with the field files — CNT-TRACK-NO-FEEDS fires when you forget, and so does the deploy. references/examples.md § 4 works a twelve-field Account down to four.

  4. Migrate transient automated posts, if step 1 said TextPost from automation ids. The checker's CNT-FLOW-CHATTERPOST and CNT-APEX-FEEDITEM findings are the worklist. Swap chatterPost for customNotificationAction and deploy the CustomNotificationType (references/metadata-examples.md § 3). Keep durable business events on the feed — read references/llm-anti-patterns.md anti-pattern 7 before anyone proposes a FeedItem purge instead. Run the two in parallel for two weeks before deactivating the original.

  5. Write the digest policy down, then lint it against the real group population.

    sf data query --result-format csv --target-org prod \
        --query "SELECT Id, Name, IsBroadcast, IsArchived FROM CollaborationGroup" > groups.csv
    python3 scripts/check_chatter_notification_tuning.py \
        --manifest-dir force-app/main/default \
        --policy notification-policy.json --group-inventory groups.csv
    

    CNT-POLICY-GROUP catches overrides that name a group that no longer exists; CNT-FREQ-VALUE rejects L and Limited; CNT-POLICY-EVERYPOST makes you justify P in writing. The policy shape is in references/metadata-examples.md § 7.

  6. Apply it in two separate changes. First User.DefaultGroupNotificationFrequency and User.DigestFrequency, which only affect what people inherit going forward. Then, as a Modify All Data holder and only if you decided to, the CollaborationGroupMember rows — which override choices people made. Lint the CSV before each load:

    python3 scripts/check_chatter_notification_tuning.py --member-csv members_update.csv
    

    references/examples.md § 5 covers the per-user email flags and their inverted polarity; references/gotchas.md gotcha 9 is the one that turns a suppression load into an amplification.

  7. Re-measure at two weeks and diff. Re-run step 1's query and step 2's checker invocation. The dominant Type should have changed, not just shrunk — if TrackedChange still leads after a chatterPost migration, step 3 was the work that mattered and did not happen. Commit Chatter.settings, ChatterEmailsMD.settings, the notification types and the policy JSON so the next org inherits the decision rather than rediscovering it.


Reference Files

FileRead it when
references/metadata-examples.mdWriting the deployable ChatterEmailsMD.settings, Chatter.settings, CustomNotificationType or Feed Tracking XML, the package.xml and sf project commands — or any of the data-side artefacts: the policy JSON, the member and user CSVs, the DML alternative, and the verification queries
references/gotchas.mdThe change failed, reversed itself, or did the opposite of what you intended — an invalid NotificationFrequency, a settings element that will not deploy, a per-post setting that became Daily on its own, a send() that failed above 500, a suppression load that increased volume
references/examples.mdWorking a scenario end to end before any XML exists — the new-hire default, a bulk group-frequency change, a chatterPost migration, Feed Tracking pruning, per-user preference resets, and the audit query that routes between them
references/well-architected.mdJustifying bell vs feed, W vs D vs N, inherited-default vs rewrite, or source-suppression vs frequency-tuning — and locating the official source behind any claim in this skill
references/llm-anti-patterns.mdReviewing output an AI assistant produced here, especially anything mentioning Limited, an emailOn* settings element, a 2,000-recipient batch, the Tooling API, or a FeedItem purge
templates/chatter-notification-tuning-template.mdRunning workflow steps 1–4 — the diagnosis, the questions, the policy, and the record of what you deliberately left alone
scripts/check_chatter_notification_tuning.pyWorkflow steps 2, 5, 6 and 7 — before any settings deploy, before any policy is agreed, and before every CSV load

Related Skills

  • admin/chatter-group-governance — the group population itself: creation policy, public/private/unlisted, archiving, ownership transfer (this skill tunes what is noisy inside a group; that one governs which groups exist)
  • apex/apex-custom-notifications-from-apex — Custom Notification API patterns, recipient targeting, target page navigation
  • apex/apex-connect-api-chatter — programmatic feed manipulation via Connect API
  • admin/email-deliverability-strategy — broader email volume management beyond Chatter

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use this skill when writing test-first, behavior-driven acceptance criteria in Given/When/Then format for a Salesforce user story. Covers happy path, edge cases, negative paths, permission boundaries, and data-state preconditions so the AC block can drive UAT scripts and Apex test design downstream. Trigger keywords: given when then, gherkin, behavior driven AC, test first acceptance criteria, scenario outline, BDD acceptance criteria. NOT for the user-story format itself (use admin/user-story-writing-for-salesforce). NOT for UAT script writing (use admin/uat-test-case-design). NOT for Apex test method generation (use agents/test-class-generator). NOT for high-level UAT planning (use admin/uat-and-acceptance-criteria). More triggers: acceptance criteria record, ac_id, req_id on a criterion, artefact under test, negative case for a rule-type requirement, no-match fall-through criterion, oracle for a Then clause, test type apex flow manual, criteria linter, check_ac_format.py, --manifest-dir.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Task and Event objects: polymorphic WhatId/WhoId, Activity object model, ActivityHistory vs OpenActivity, activity timeline customization, bulk task creation, Einstein Activity Capture boundaries. NOT for turning on EAC or calendar sync — use admin/einstein-activity-capture-setup. NOT for Email-to-Case — use admin/case-management-setup. Covers ActivitiesSettings metadata, enableActivities, shared Task/Event custom fields and FLS, TaskStatus value sets, Shared Activities and TaskRelation/EventRelation, recurring and child activities, and partial-success bulk DML on Task.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Design Invocable Apex actions that return deterministic, agent-friendly errors instead of surfacing raw exceptions to the LLM. NOT for authoring the action itself — @InvocableMethod schema, labels, security context — use agentforce/custom-agent-actions-apex. NOT for the Apex tests that force each error branch — use agentforce/agent-action-unit-tests.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Use when designing how an Agentforce agent extracts structured input parameters (slots) from a user's natural-language utterance to invoke an action. Triggers: 'agent extract date from user', 'agent action argument extraction', 'agentforce slot filling', 'agent invocable input mapping', 'agent fails to fill required parameter'. NOT for action authoring (use agentforce/agent-actions) or for prompt-template variable binding (use agentforce/prompt-builder-templates).

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Apex test patterns for @InvocableMethod agent actions: per-reason-code branch coverage, bulk safety, callout mocking, deterministic assertions. NOT for testing whether the agent routes to the right topic or answers well — use agentforce/agent-testing-and-evaluation. NOT for designing the error envelope the tests assert on — use agentforce/agent-action-error-handling.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Designing or reviewing Agentforce actions: Flow actions, Apex invocable actions, prompt-template actions, action naming, input and output contracts, confirmation requirements, and safe error behavior. Triggers: 'agent actions', 'build an agent that can look up an order', 'make the agent able to check order status', 'give the agent a capability', 'agent that can retrieve a record', 'flow action for agent', 'agent invocable action', 'action schema design'. NOT for writing the Apex class itself — use agentforce/custom-agent-actions-apex. NOT for the reason_code error envelope that stops an agent retry loop — use agentforce/agent-action-error-handling.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

PranavNagrecha のスキルをすべて見る

このスキルの問題を報告する