Docs / built-apps / useMessages

useMessages

hooksince 0.2.2

Read and send private messages within one DM thread in a built app.

import { useMessages } from 'flowstack-sdk'

Reads and sends private messages in a single thread with withUserKey. Mirrors useCollection's ergonomics but is backed by the server-owned, ACL'd DM endpoints instead of a Mongo collection. The backend pins the sender to the caller's identity and only delivers into a mutually-consented (open) thread, so send() to a not-yet-open thread returns an error.

Private messaging is a built-app capability: it requires an appScope on the FlowstackProvider config. Treat the type signatures in packages/flowstack-sdk/src/hooks/useMessages.ts as the source of truth.

Signature

const { messages, send, isLoading, error, refresh } = useMessages(withUserKey, options?)

Parameters

ParamTypeNotesDescription
withUserKeystring | null | undefinedrequired, since 0.2.2The counterpart's user key. When null/undefined the hook stays idle (no fetch).
options.limitnumberdefault 50, since 0.2.2Max messages to load (max 200).
options.refreshIntervalnumbersince 0.2.2Auto-poll interval in ms. No polling by default.
options.enabledbooleandefault true, since 0.2.2Set false to skip the initial fetch (e.g. before a counterpart is selected).

Returns

FieldTypeDescription
messagesDmMessage[]Messages in the thread — each { message_id, from, to, body, created_at, read_at }.
send(body: string) => Promise<void>Send a message to the counterpart. Refetches on success; throws if the thread is not yet mutually open.
isLoadingbooleanTrue while a fetch is in flight.
errorstring | nullError message from the last failed load or send.
refresh() => Promise<void>Refetch the message list.

Examples

Read and send
const { messages, send } = useMessages(counterpartUserKey, { refreshInterval: 4000 });

await send('hey there');

messages.map((m) => (
  <Bubble key={m.message_id} mine={m.from === myKey}>{m.body}</Bubble>
));
CriticalMessage bodies are UNTRUSTED user input. Render them as plain text or sanitized markdown — never as raw HTML (no dangerouslySetInnerHTML). If a body is ever passed to an agent, treat it as data, not instructions.
Warningsend() throws if the thread is not mutually open. Call openThread() (from useThreads) first and wait until both parties consent.

See also

useThreads · sendMessage · listMessages · DmMessage

Source: README.md#private-messaging-dms · Also available in llms-full.txt and registry.json.