> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myfundingmachine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Slack workspace setup

> Activate free Operator membership, automatic private channels and safe access recovery.

My Funding Machine Support is the shared Operator workspace. Operators join as full
members with free Slack accounts. They can find and message community members;
their support channels remain private. Never put private client information in
community channels.

Before enabling automatic creation for existing customers, reconcile the staff-visible
private channels and save their verified IDs. FM Bot cannot discover private channels
it has not joined. A missing bot-visible match does not prove a customer needs a new
channel. Moving existing owners from Slack Connect uses the separate
[Slack migration workflow](/slack-migration). Its assignment automation requires
the migration code to be deployed and its own enable switch to be on.

## App and credentials

Install the dedicated **FM Onboarding** app with bot name **FM Bot** in the support
workspace. The checked-in template is
`scripts/onboarding/slack-app-manifest.json`. Replace its deployment URL with the
approved Convex HTTP URL ending in `/slack/onboarding-events`. Do not point the new
app at the internal staff Slack receiver.

The app creates private channels, reads their membership and messages, invites
workspace members and posts the welcome. It reads workspace user profiles and
email addresses to match the verified onboarding contact. Its scopes are
`groups:read`, `groups:write`, `groups:history`, `users:read`,
`users:read.email` and `chat:write`. It does not request workspace administration,
public-channel history or workspace email-invitation permissions. See Slack's
[channel creation](https://docs.slack.dev/reference/methods/conversations.create/)
and [channel invitation](https://docs.slack.dev/reference/methods/conversations.invite/)
documentation.

Slack's workspace permissions must also allow **Members → Create private
channels** under **Roles & permissions → Account types**. Bot scopes alone do
not override an admins-only setting; Slack returns `restricted_action` when
creation is blocked. Enabling this permission also lets full-member Operators
create their own private channels, so obtain workspace-owner approval first.
It does not grant access to existing private support channels.

Enter credentials directly in the approved environment settings. Never put tokens,
signing secrets or shared invitation URLs in Git, screenshots or chat.

| Setting | Environment | Purpose |
| - | - | - |
| `ONBOARDING_SLACK_TEAM_ID` | Convex and Next.js | Support workspace ID; verified by the bot before any provisioning |
| `ONBOARDING_SLACK_BOT_TOKEN` | Convex and Next.js | Dedicated bot token; internal staff Slack keeps its own token |
| `ONBOARDING_SLACK_APP_ID` | Convex | Exact app ID accepted by the signed event receiver |
| `ONBOARDING_SLACK_SIGNING_SECRET` | Convex | Verify Slack event signatures and reject replays |
| `ONBOARDING_SLACK_STAFF_USER_IDS` | Convex | Comma-separated support staff IDs from this workspace, excluding the bot and clients |
| `ONBOARDING_SLACK_CHANNEL_STAFF` | Convex | Optional JSON array of approved existing staff access, scoped by exact `locationId`, `teamId`, `channelId` and `userIds`; never an invitation list |
| `ONBOARDING_SLACK_JOIN_URL` | Convex | Optional approved `https://join.slack.com/t/.../shared_invite/...` invitation shown to eligible Operators |
| `ONBOARDING_SLACK_WORKSPACE_ENABLED=true` | Convex | Select the workspace flow and its staff controls |
| `ONBOARDING_SLACK_PROVISION_ENABLED=true` | Convex | Permit channel creation, invitations and welcome messages |
| `ONBOARDING_SLACK_PAID_PROVISION_ENABLED=true` | Convex | Permit provisioning only for verified new payment enrollments; keep the general provisioning switch off for a new-paid-only rollout |
| `ONBOARDING_SLACK_PROVISION_LOCATION_IDS` | Convex | Optional comma-separated pilot Location IDs; when set, only exact listed Locations may provision. An empty value blocks all provisioning writes. |
| `ONBOARDING_ADMIN_CRM_WRITES_ENABLED=true` | Convex | Also required for provisioning and the CRM channel-ID write |

After product-account linking, the Onboarding & Setup Labs feature must also allow writes for that Location. Before an account exists, the payment flow uses the verified Operations enrollment described below.
Existing support-agent reply and AI policy gates stay in force; installing this
app does not enable automatic AI replies or retention communications.

The shared staff roster is required in every provisioned customer channel. To preserve
an existing teammate's access to only one channel, use a channel-specific entry instead
of adding them to the shared roster:

```json theme={null}
[{"locationId":"approved-product-location","teamId":"TWORKSPACE1","channelId":"CPRIVATE1","userIds":["USTAFF123"]}]
```

Approve and verify the person and all three scope IDs before saving this configuration.
It accepts existing active human members only in that exact Location, workspace and
channel. It never invites them, requires their membership, re-adds them after removal,
or treats them as the Operator. Their replies in tracked support threads count as a
human handoff. Removing the entry removes staff recognition; an active human member can
still participate as a customer teammate. Revoke Slack access separately when intended. Invalid configuration
blocks verification and denies optional staff access during message ingestion; verified
Operator messages and shared staff handoffs continue. An exception does not repair a
conflicting channel reservation.

Subscribe to `team_join`, `user_change`, `member_joined_channel`,
`member_left_channel` and `message.groups`. The dedicated endpoint checks both
workspace and app IDs after signature verification. Membership events trigger
fresh API reads; event order does not decide access. A bounded five-minute sweep
retries unfinished setup after five minutes and checks connected accounts every
30 minutes for missed membership events. Larger queues take multiple passes.

## Workspace invitations

Free Slack does not offer the Enterprise invitation API. Staff can email an
invitation from Slack, or publish a shared invitation in
[Admin → Settings → Onboarding](/staff/onboarding-settings). The Operator’s
**Join the Slack workspace** button reads the current approved link when clicked,
including on a page opened before the link was replaced. A shared link admits
anyone holding it to the community; it does not grant private support access.

Use a link explicitly set to **Never expires** in Slack. Expiring links are not
supported. Each link admits up to 400 people; the default capacity threshold is
350\. Signed workspace join events maintain an estimate, and the weekly browser
check records Slack's actual per-link usage. The app checks capacity hourly and
sends bot alerts for capacity warnings, missing verification or broken links.
Accepted alerts repeat at most daily; failed deliveries retry hourly. The browser
replaces a link only at its verified capacity threshold or when it no longer works,
then publishes another verified **Never expires** link. No age-based renewal runs.

Previously saved and deployment invitations need a one-time **Never expires**
confirmation in settings. After saving, settings are authoritative, including an
intentionally cleared or paused link. Network or sign-in failures preserve the
last confirmed availability and request staff review. See
[Onboarding settings](/staff/onboarding-settings) for counter reconciliation and recovery.
If a current invitation cannot be provided, the Join button explains that it is
being updated and directs the Operator to their onboarding team.

Use the verified onboarding email. Setup never matches names or automatically grants
private access to unrelated community members. One primary Operator account remains
the onboarding identity for each Location; do not substitute a teammate's email.

## From payment to private support

After payment-welcome activation, the Operations payment workflow finds or creates
an Onboarding opportunity and sends its authenticated payment webhook. The app verifies
the payment, order, approved product and exact contact, then queues a private channel.
The customer does not need a Slack membership or a CRM sub-account yet.

FM Bot creates the channel, saves its ID on that exact opportunity and adds the
configured support staff. The welcome email and SMS wait until the channel and current
workspace invitation are ready, then include both the onboarding form and a **Join our
free support workspace** link. The customer joins using their purchase email. Signed
membership events and the recovery sweep match that email, add the primary Operator to
the reserved channel and post one welcome. Staff can speak with them there immediately.

The welcome mentions the primary Operator, explains who to tag for support, and links
to Funding Machine inside that customer's CRM account. It is sent only after Slack
confirms channel membership. If membership arrives before account linking, the bot
welcomes them without an account URL and updates that same message once the verified
product Location is available. It never uses the Operations Location in the link.
Existing welcome messages are not rewritten; uncertain initial sends need staff review.

When the product sub-account is created and verified account linking completes, setup
attaches the same channel to that Location. It preserves membership, channel history
and welcome receipts. Until then, account-specific support ingestion and automated
account tools remain unavailable; staff can still respond directly in Slack.

This path requires send mode on the payment-welcome policy, both live-engine enable
controls, the workspace/provisioning switches, the CRM write gate and an approved
workspace invitation. For **new paid customers only**, keep
`ONBOARDING_SLACK_PROVISION_ENABLED=false` and enable
`ONBOARDING_SLACK_PAID_PROVISION_ENABLED=true`. Only payment enrollments at or after
the welcome policy's cutoff qualify. This restriction follows the reservation when
the CRM account is linked; payment and hold status are checked before provider writes.
Turning the paid switch off stops further writes without removing existing channels.
The general provisioning switch still permits the broader eligible-account rollout,
so it must remain off when limiting setup to new paid customers.
A Location pilot list blocks creation before a Location exists;
remove it only as part of the approved broader rollout. Compute mode performs no Slack
writes. Refunds, holds, changed identities and pending CRM edits stop new access grants.
The five-minute sweep handles five due payment enrollments per pass and recovers up to
five older enrollments that have not entered the Slack queue. Payment-check failures and saved jobs
back off, and signed join events can trigger an earlier check.

Before a sub-account exists, staff can pause or resume the Operations welcome enrollment
through the authorized welcome controls. Its signed links expire after thirty days;
reissue invalidates the old form and Slack links without resending messages. The Slack
link reads the current approved invitation when clicked, so rotation does not require
another email. See [Onboarding notifications](/staff/onboarding-notifications).

## Customer teammates

Customers can have additional teammates in their existing private support channel.
These people do not need individual CRM links, and their presence does not make the
connection unhealthy. The channel must still match exactly one verified Location in
the configured workspace, with FM Bot, the assigned staff and the primary Operator.

For additional participants, the signed message receiver checks Slack's current
channel membership and active human profile before creating a support signal. Their
messages and replies are customer messages. Only configured Funding Machine staff
trigger a staff handoff. Teammates cannot replace the primary Operator, complete that
person's onboarding membership check, or gain account-management permissions through
Slack membership. Public, externally shared, archived and ambiguously mapped channels
are not accepted for teammate messages. Removed members and bots are not accepted.

Do not add customer teammates to either staff roster. Invite or remove teammates
through Slack's normal private-channel controls; the engine does not invite them or
restore their membership. Paused or disconnected onboarding connections still block
customer message ingestion. If Slack cannot verify an additional participant, the
message is not ingested; existing Operator and staff processing remains available.

If staff reply while a customer message is still being verified, FM Bot preserves the staff handoff for that exact account and thread. Once verification finishes, the bot can prepare drafts but cannot automatically reply over the staff response.

## Activation and rehearsal

1. Approve app creation and installation for the named support workspace. Create the app without event subscriptions until the receiver is deployed and its app ID/signing secret are configured, then enable its subscriptions. Keep provisioning disabled during configuration.
2. Verify the bot's workspace, the staff roster and the signed receiver. Configure public community/default channels in Slack; private support channels must never be default channels.
3. Deploy the verified code through the repository's approved release process.
4. Set `ONBOARDING_SLACK_PROVISION_LOCATION_IDS` to the approved pilot Location IDs before enabling provisioning and the CRM write gate. The onboarding Labs feature must be enabled for each pilot Location too. Other Locations can keep using onboarding without gaining provisioning permission. Removing a Location from the list stops its next channel, membership, welcome, or CRM write; adding it again resumes its saved setup attempt. Keep the global provisioning switch off while preparing the pilot. Remove the Location restriction only after approving the broader rollout; omitting it preserves the existing behavior for all eligible Locations.
5. Use a named synthetic pilot contact and workspace member: confirm one private channel, exact CRM ID readback, staff membership, email match, Operator membership and a single welcome. Confirm another Location cannot claim that channel.
6. Verify pause/resume, a removed member, a deactivated member, archived channel and provider-error states. Obtain exact-target approval before any live test that changes membership, posts a message or updates CRM data.

Automatic account linking and staff contact mapping schedule the first check.
Selecting or expanding a client in Admin reads saved state only. Explicit **Refresh setup connections** checks providers and may provision a channel when all gates permit it. The Operator setup journey retains its configured refresh behavior. Account-triggered creation requires one verified
open Onboarding opportunity with this Product Location ID. Payment-triggered creation follows the separate verified enrollment below. An existing private
channel can be adopted from its exact CRM field before setup reserves a channel;
FM Bot must already be a member.

New private channels use `fm-{first-name}-{last-name}-{company-name}`
from the verified onboarding contact. For example, Alex D’Angelo at Example Funding
becomes `fm-alex-dangelo-example-funding`. Names use lowercase letters and hyphens;
apostrophes and accents are removed. If the company is not known yet, setup uses
`fm-{first-name}-{last-name}` (for example, `fm-joseph-jenkinson`). Staff can rename
the channel in Slack once the company is known, including while a fully prepared
channel is waiting for its Operator to join. Adding a company to the CRM later
does not automatically rename or replace the channel.
Missing first/last names, unusable supplied names or a name over Slack's 80-character
limit require staff review. A duplicate name also requires
review: setup does not add a random suffix or adopt another customer's channel.
Saved channel IDs and unfinished reservations keep their existing identity when
contact details change. Rename an existing channel in Slack after checking its
CRM mapping; the saved channel ID keeps its connection intact.

## Recovery

**Pause Slack setup** stops changes for this Location; **Resume Slack setup**
restarts checks. Already granted Slack memberships stay in place.

A confirmed removal is never silently undone. Restore a deactivated member or
archived channel in Slack, review the correct account, then use **Approve reconnect**.
Provider errors remain **Unable to verify** and do not trigger a lapse by themselves.

An uncertain invitation is checked against actual membership. If access is absent, staff must review it before another invitation; this also protects removals after a lost response.

The bot creates new channels under a unique temporary name, saves the channel ID,
and applies the customer name (including the company when available) before writing the CRM mapping or adding
staff and the Operator. An uncertain create is recovered only by that unique
reserved name and bot creator. A lost rename response is checked by the saved ID.
If recovery cannot confirm the original channel, escalate; do not create another.
An uncertain welcome is not posted twice: check the original channel's message
history. A changed primary contact, email or CRM mapping needs staff review.
Pause first and escalate the exact Location and reserved channel ID;
the app intentionally blocks replacing a reserved mapping from Compliance.

Channel access and the welcome wait until the saved CRM **Slack Channel ID**
reads back as the reserved channel. If a channel exists but that field is blank,
review the exact opportunity and saved attempt before retrying; keep the existing
channel rather than creating a replacement.

Free Slack shows the most recent 90 days of messages/files and deletes content older than one year; workspace retention settings can shorten that to 90 days. It also limits installations to 10 apps. See [Slack’s free-workspace limits](https://slack.com/help/articles/115002422943-Usage-limits-for-free-workspaces). Keep durable setup status, support decisions and
client records in the CRM/app. Use a pinned channel message for next steps and
training links; [canvases require a paid plan](https://slack.com/help/articles/203950418-Use-a-canvas-in-Slack).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.