Ephemeral Messages

Send messages visible only to a specific user.

Ephemeral messages are visible only to a specific user within a thread. They're useful for confirmations, hints, and private notifications.

Send an ephemeral message

lib/bot.ts
await thread.postEphemeral(user, "Only you can see this!", {
  fallbackToDM: true,
});

The fallbackToDM option is required and controls behavior on platforms without native ephemeral support:

  • fallbackToDM: true — send as a DM if native ephemeral is not supported
  • fallbackToDM: false — return null if native ephemeral is not supported

Platform behavior

PlatformNative supportBehaviorPersistence
SlackYesEphemeral in channelSession-only (disappears on reload)
Google ChatYesPrivate message in spacePersists until deleted
DiscordNoDM fallbackPersists in DM
TeamsNoDM fallbackPersists in DM

Discord slash command responses can be made ephemeral with the Discord adapter's interactionFlags option. Outside that interaction flow, postEphemeral still follows the fallback behavior.

Check for fallback

lib/bot.ts
const result = await thread.postEphemeral(user, "Private notification", {
  fallbackToDM: true,
});

if (result?.usedFallback) {
  console.log("Sent as DM instead of ephemeral");
}

Graceful degradation

Only send if the platform supports native ephemeral:

lib/bot.ts
const result = await thread.postEphemeral(user, "Contextual hint", {
  fallbackToDM: false,
});

if (!result) {
  // Platform doesn't support native ephemeral
  // Message was not sent
}

Ephemeral cards

Cards work with ephemeral messages too:

lib/bot.tsx
await thread.postEphemeral(
  event.user,
  <Card title="Ephemeral Card">
    <CardText>Only you can see this card.</CardText>
    <Actions>
      <Button id="open_modal" style="primary">Open Modal</Button>
    </Actions>
  </Card>,
  { fallbackToDM: true }
);