apex-connect-api-chatter

Use when posting to a Chatter feed, creating feed comments, @mentioning users or groups, or rendering rich-text posts from Apex via the ConnectApi namespace. Trigger keywords: ConnectApi, FeedItem, Chatter post, @mention, rich text post, FeedElementCapabilities, link post. NOT for: email notifications (see apex-email-messaging), custom bell notifications (see apex-custom-notifications-from-apex), or Experience Cloud feed embeds (see community-feed-components).

Best use case

apex-connect-api-chatter is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when posting to a Chatter feed, creating feed comments, @mentioning users or groups, or rendering rich-text posts from Apex via the ConnectApi namespace. Trigger keywords: ConnectApi, FeedItem, Chatter post, @mention, rich text post, FeedElementCapabilities, link post. NOT for: email notifications (see apex-email-messaging), custom bell notifications (see apex-custom-notifications-from-apex), or Experience Cloud feed embeds (see community-feed-components).

Teams using apex-connect-api-chatter should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/apex-connect-api-chatter/SKILL.md --create-dirs "https://raw.githubusercontent.com/PranavNagrecha/AwesomeSalesforceSkills/main/skills/apex/apex-connect-api-chatter/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/apex-connect-api-chatter/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How apex-connect-api-chatter Compares

Feature / Agentapex-connect-api-chatterStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when posting to a Chatter feed, creating feed comments, @mentioning users or groups, or rendering rich-text posts from Apex via the ConnectApi namespace. Trigger keywords: ConnectApi, FeedItem, Chatter post, @mention, rich text post, FeedElementCapabilities, link post. NOT for: email notifications (see apex-email-messaging), custom bell notifications (see apex-custom-notifications-from-apex), or Experience Cloud feed embeds (see community-feed-components).

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Apex Connect Api Chatter

Activate this skill when Apex needs to post to Chatter, reply to a feed item, or @mention a user programmatically. The `ConnectApi` namespace is the only supported way to produce rich-content posts (mentions, links, files, polls) — direct DML on `FeedItem` is limited and does NOT support mention rendering.

---

## Before Starting

Gather this context before working on anything in this domain:

- Is Chatter enabled in the org? `ConnectApi` throws `ConnectApi.ConnectApiException` if disabled.
- What's the execution context? `ConnectApi` has strict restrictions in `@future` and test methods.
- What sort of post? Plain text, text-with-mentions, link, file attachment, poll, or announcement?
- Who's the author? Running user by default; can impersonate only via `ConnectApi.ChatterFeeds.postFeedElement` parameters in limited cases.

---

## Core Concepts

### ConnectApi vs Direct DML On FeedItem

- `insert new FeedItem(...)` works but produces plain text only. No mentions, no files, no polls.
- `ConnectApi.ChatterFeeds.postFeedElement(...)` supports the full post capability set (mentions, files, links, polls, announcements).
- Rule: if the post has any rich content, use ConnectApi. Use direct DML only for the simplest text post where capabilities are not needed.

### `FeedItemInput` + `MessageBodyInput` + `MessageSegmentInput`

Rich posts are assembled from segments:

- `TextSegmentInput` — plain text
- `MentionSegmentInput` — `@user` or `@group`
- `LinkSegmentInput` — inline URL
- `HashtagSegmentInput` — `#topic`

Segments are concatenated in order into a `MessageBodyInput`, which is wrapped in a `FeedItemInput`.

### Test Context Restrictions

- `ConnectApi` methods throw in synchronous test methods unless `Test.setMock(ConnectApi.ConnectApi.class, mock)` or the `SeeAllData=true` annotation is used.
- `SeeAllData=true` is a code-smell in most orgs; prefer the mock framework.
- `@future` methods CAN call `ConnectApi`, but the calls run as the user who enqueued (or the automated user in some contexts) — test this explicitly.

### Feed Parent Id Types

Feeds hang off a parent record. Common parent types:

- User Ids (`005...`) — user's personal feed
- Group Ids (`0F9...`) — Chatter group
- Record Ids (`001...` etc.) — any object with feed tracking enabled
- `'me'` — shorthand for the running user

---

## Common Patterns

### Plain-Text Post With @Mention

**When to use:** A trigger or service needs to notify an owner by @mentioning them in a record feed.

**How it works:**

```apex
public static void postMentionToRecord(Id recordId, Id userToMention, String message) {
    ConnectApi.FeedItemInput post = new ConnectApi.FeedItemInput();
    ConnectApi.MessageBodyInput body = new ConnectApi.MessageBodyInput();
    body.messageSegments = new List<ConnectApi.MessageSegmentInput>();

    ConnectApi.MentionSegmentInput mention = new ConnectApi.MentionSegmentInput();
    mention.id = userToMention;
    body.messageSegments.add(mention);

    ConnectApi.TextSegmentInput text = new ConnectApi.TextSegmentInput();
    text.text = ' ' + message;
    body.messageSegments.add(text);

    post.body = body;

    ConnectApi.ChatterFeeds.postFeedElement(Network.getNetworkId(), recordId, post);
}
```

**Why not the alternative:** `insert new FeedItem(Body='@Jane ...')` shows literal `@Jane` text — no notification fires, no link is rendered.

### Post With File Attachment

**When to use:** Uploading a report PDF and posting it to a record feed in one go.

**How it works:**

```apex
ConnectApi.FeedItemInput input = new ConnectApi.FeedItemInput();
ConnectApi.MessageBodyInput body = new ConnectApi.MessageBodyInput();
body.messageSegments = new List<ConnectApi.MessageSegmentInput>{
    new ConnectApi.TextSegmentInput()
};
((ConnectApi.TextSegmentInput) body.messageSegments[0]).text = 'See attached report.';
input.body = body;

ConnectApi.NewFileAttachmentInput file = new ConnectApi.NewFileAttachmentInput();
file.title = 'Weekly Report';
input.capabilities = new ConnectApi.FeedElementCapabilitiesInput();
input.capabilities.content = new ConnectApi.ContentCapabilityInput();
input.capabilities.content.title = file.title;

ConnectApi.BinaryInput binary = new ConnectApi.BinaryInput(
    Blob.valueOf(pdfBytes), 'application/pdf', 'report.pdf');

ConnectApi.ChatterFeeds.postFeedElement(
    Network.getNetworkId(), recordId, input, binary);
```

---

## Decision Guidance

| Situation | Recommended Approach | Reason |
|---|---|---|
| Plain text post, no mentions | Either ConnectApi or DML | Choose by team convention |
| Text with @mention | ConnectApi `MentionSegmentInput` | DML produces literal text |
| Post + file attachment | ConnectApi with `BinaryInput` | No DML equivalent |
| Poll post | ConnectApi `PollCapabilityInput` | No DML equivalent |
| Scheduled reminder post | Queueable calling ConnectApi | Governor-safe |
| Bulk posts (100s) | Batch + ConnectApi per record | Respects limits per execution |
| Experience Cloud posts | `Network.getNetworkId()` arg | `null` posts to internal Chatter |

---

## Recommended Workflow

1. Confirm Chatter is enabled — feature check via `FeatureManagement` or an admin confirm.
2. Identify feed parent — user, group, or record with feed tracking enabled.
3. Build the `FeedItemInput` by assembling message segments; handle null/empty text explicitly.
4. Decide sync vs async — post in the current transaction unless you need isolation; if async, write a governor-bounded Queueable.
5. Write tests — `Test.setMock(ConnectApi.ConnectApi.class, ...)` to avoid real feed writes; assert the payload shape.
6. Test Experience Cloud separately if posts must appear in a partner/customer community — `Network.getNetworkId()` argument matters.

---

## Review Checklist

- [ ] No literal `@username` strings in FeedItem.Body — mentions are always `MentionSegmentInput`.
- [ ] `Network.getNetworkId()` (not hardcoded network Id) for community context.
- [ ] Tests use `Test.setMock(ConnectApi.ConnectApi.class, ...)`.
- [ ] ConnectApi call wrapped in try/catch of `ConnectApi.ConnectApiException`.
- [ ] Messages under Chatter's 10,000 char soft limit.
- [ ] File attachments under 2GB / org-specific limit.

---

## Salesforce-Specific Gotchas

1. **Chatter off means ConnectApiException** — orgs with Chatter disabled throw on every call; feature-flag the code.
2. **`FeedItem` DML cannot render mentions** — `@Jane` appears as literal text, no notification fires.
3. **`ConnectApi` in test requires mocks** — `SeeAllData=false` (the default) blocks real Chatter calls; use `Test.setMock` or the call throws.
4. **Network Id must be passed** — omitting or using the wrong community Id posts to the wrong feed silently.
5. **Mentions require feed visibility** — user must have access to the parent record; otherwise the mention is rendered but no notification fires.
6. **Feed tracking must be on** — posting to a record whose object lacks feed tracking fails with a specific ConnectApiException.
7. **Polls cannot be edited after posting** — only deleted and reposted.
8. **ConnectApi does NOT call triggers on FeedItem** — `FeedItem` triggers fire on DML, but ConnectApi writes go through a separate path; relying on FeedItem triggers for ConnectApi posts is unreliable.

---

## Output Artifacts

| Artifact | Description |
|---|---|
| `scripts/check_apex_connect_api_chatter.py` | Scans for literal `@` mentions in FeedItem DML, missing ConnectApi mocks in tests, and unsafe error handling |
| `templates/apex-connect-api-chatter-template.md` | Work template for assembling FeedItemInput with mentions and attachments |

---

## Related Skills

- `apex-custom-notifications-from-apex` — bell notifications (different system from Chatter)
- `apex-email-messaging` — email outreach (Chatter is not email)
- `apex-blob-and-content-version` — managing files attached to Chatter posts

Related Skills

connected-app-security-policies

8
from PranavNagrecha/AwesomeSalesforceSkills

Managing OAuth policies, IP relaxation, session security, PKCE, and credential rotation for Salesforce Connected Apps. Use when hardening Connected App security, rotating client secrets, configuring IP restrictions, or requiring high-assurance sessions. NOT for basic Connected App setup or creation. NOT for OAuth flow implementation (use oauth-flows-and-connected-apps).

apex-managed-sharing-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Grant row-level access programmatically via __Share records when declarative sharing rules cannot express the policy. NOT for OWD, role hierarchy, or criteria-based sharing rule design.

lwc-imperative-apex

8
from PranavNagrecha/AwesomeSalesforceSkills

Call Apex methods imperatively from LWC — on button click, lifecycle hooks, or conditional logic. Covers import syntax, cacheable vs non-cacheable, async/await patterns, error handling, loading states, and Promise.all. NOT for wire service (use wire-service-patterns) and NOT for testing Apex mocks (use lwc-testing).

tableau-salesforce-connector

8
from PranavNagrecha/AwesomeSalesforceSkills

Tableau ↔ Salesforce integration patterns: Tableau Salesforce connector, Tableau for Salesforce, CRM Analytics alternative, Data Cloud + Tableau, embedded Tableau dashboards. Choose between connector modes (live, extract, direct-to-Data-Cloud). NOT for CRM Analytics Studio (use crm-analytics-foundation). NOT for generic Tableau Server setup.

slack-connect-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when designing, governing, or troubleshooting Slack Connect channel sharing between two independent organizations. Trigger phrases: external Slack channel collaboration, cross-org Slack channel setup, Slack Connect DLP policy, Slack partner channel governance, regulated industry Slack Connect compliance. Does NOT cover Salesforce-to-Salesforce integration, Salesforce for Slack app setup, or internal single-workspace Slack channels. NOT for Salesforce-to-Salesforce integration.

salesforce-connect-external-objects

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when deciding whether Salesforce Connect and External Objects are the right fit for external data access, or when reviewing OData, cross-org, and custom adapter patterns, query limitations, and latency tradeoffs. Triggers: 'Salesforce Connect', 'External Objects', '__x', 'OData adapter', 'custom adapter'. NOT for ordinary ETL or replicated-data designs where the data should live inside Salesforce.

private-connect-setup

8
from PranavNagrecha/AwesomeSalesforceSkills

Configure Private Connect between Salesforce and AWS/Azure for traffic to stay on private networks. NOT for standard internet callouts.

oauth-flows-and-connected-apps

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when choosing or reviewing Salesforce OAuth flows and connected-app policy for integrations, including client credentials, JWT bearer, authorization code, device flow, scopes, and token lifecycle controls. Triggers: 'OAuth flow', 'connected app', 'client credentials', 'JWT bearer', 'refresh token', 'integration user'. NOT for record-level sharing design or for simple Named Credential usage when the auth-flow decision is already settled.

mulesoft-salesforce-connector

8
from PranavNagrecha/AwesomeSalesforceSkills

Designing and configuring MuleSoft Anypoint Salesforce Connector flows: API selection (SOAP/REST/Bulk/Streaming), OAuth 2.0 JWT Bearer auth, watermark-based incremental sync with Object Store, batch processing with record-level error isolation, and replay topic subscriptions. Use when building Mule 4 flows that read from or write to Salesforce, migrating from Mule 3 watermark to Mule 4 Object Store, or troubleshooting connector authentication and API limits. NOT for native Salesforce-to-Salesforce integration without MuleSoft (use platform-events-integration or change-data-capture-integration). NOT for generic REST callout patterns from Apex (use rest-api-patterns).

dataweave-for-apex

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when transforming structured data inside Apex — CSV → JSON, XML → SObject list, JSON → flattened CSV, or schema-mapping a third-party payload to a Salesforce model — and the existing options (`JSON.deserialize`, `Dom.Document`, hand-written loops) are getting unwieldy. Triggers: 'apex transform csv json xml without external library', 'system.dataweave script', 'salesforce native dataweave apex execute', 'transform xml to sobject apex no mulesoft', 'json reshape salesforce apex script'. NOT for MuleSoft Anypoint DataWeave running off-platform (use mulesoft-anypoint-architecture), NOT for Apex JSON serialization basics (use apex-json-serialization), NOT for Bulk API CSV ingest (use bulk-api-2-patterns).

connect-rest-api-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Use Connect REST API for Chatter, feeds, communities, and CMS content instead of querying underlying SObjects. NOT for custom business object CRUD.

api-led-connectivity

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when designing a multi-system integration architecture using the three-layer API-led connectivity pattern (System, Process, Experience APIs), deciding how many layers to apply, mapping Salesforce as a system-layer endpoint or experience-layer consumer, or evaluating how Agentforce and MuleSoft Agent Fabric leverage API-led patterns. Triggers: 'API-led connectivity', 'system API process API experience API', 'MuleSoft integration layers', 'application network'. NOT for configuring MuleSoft Anypoint Salesforce Connector flows (use mulesoft-salesforce-connector). NOT for Salesforce REST API CRUD patterns (use rest-api-patterns). NOT for event-driven architecture without an API layer (use event-driven-architecture-patterns).