Agent filters
Import built-in filters as filter or f from @xmtp/agent-sdk.
| Filter | Checks |
|---|---|
fromSelf(message, client) | Sender is the current client |
hasContent(message) | Content is known, with a decoded value for custom content |
isDM(conversation) | Conversation is a direct message |
isGroup(conversation) | Conversation is a group |
isGroupAdminAsync(conversation, message) | Sender is a group admin |
isGroupSuperAdminAsync(conversation, message) | Sender is a group super admin |
usesCodec(message, Codec) | Codec authority, type name, and major version match; content is decoded |
import { const filter: { fromSelf: (message: Message, client: Client) => boolean; hasContent: (message: Message) => message is DecodedMessageWithContent; isDM: (conversation: Group | Dm) => conversation is Dm; isGroup: (conversation: Group | Dm) => conversation is Group; isGroupAdminAsync: (conversation: Group | Dm, message: Message) => Promise<boolean>; isGroupSuperAdminAsync: (conversation: Group | Dm, message: Message) => Promise<boolean>; usesCodec: <T extends AnyContentCodec>(message: Message, codecClass: new () => T) => message is DecodedMessageWithContent<ReturnType<T["decode"]>>;}
Message and conversation tests for agent middleware.
filter } from "@xmtp/agent-sdk";
const agent: Agent<unknown>
agent.NodeJS.EventEmitter<EventHandlerMap<unknown>>.on<"message">(eventName: keyof EventEmitterEventMap | "actions" | "attachment" | "conversation" | "group-update" | "dm" | "group" | "inline-attachment" | "intent" | "leave-request" | "markdown" | "message" | "multi-attachment" | "reaction" | "read-receipt" | "reply" | "start" | "stop" | "text" | "transaction-reference" | "unhandledError" | "unknownMessage" | "wallet-send-calls", listener: (ctx: MessageContext<unknown, unknown>) => void): Agent<unknown>
Adds the listener function to the end of the listeners array for the
event named eventName. No checks are made to see if the listener has
already been added. Multiple calls passing the same combination of eventName
and listener will result in the listener being added, and called, multiple
times.
server.on('connection', (stream) => { console.log('someone connected!');});
Returns a reference to the EventEmitter, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The
emitter.prependListener() method can be used as an alternative to add the
event listener to the beginning of the listeners array.
import { EventEmitter } from 'node:events';const myEE = new EventEmitter();myEE.on('foo', () => console.log('a'));myEE.prependListener('foo', () => console.log('b'));myEE.emit('foo');// Prints:// b// a
on("message", async (ctx: MessageContext<unknown, unknown>
ctx) => { if (const filter: { fromSelf: (message: Message, client: Client) => boolean; hasContent: (message: Message) => message is DecodedMessageWithContent; isDM: (conversation: Group | Dm) => conversation is Dm; isGroup: (conversation: Group | Dm) => conversation is Group; isGroupAdminAsync: (conversation: Group | Dm, message: Message) => Promise<boolean>; isGroupSuperAdminAsync: (conversation: Group | Dm, message: Message) => Promise<boolean>; usesCodec: <T extends AnyContentCodec>(message: Message, codecClass: new () => T) => message is DecodedMessageWithContent<ReturnType<T["decode"]>>;}
Message and conversation tests for agent middleware.
filter.fromSelf: (message: Message, client: Client) => boolean
Check whether the client sent the message.
fromSelf(ctx: MessageContext<unknown, unknown>
ctx.MessageContext<unknown, unknown>.message: Message
The SDK message, including its tagged content and retained bytes.
message, ctx: MessageContext<unknown, unknown>
ctx.ClientContext<unknown>.client: Client
Return the wrapped XMTP client.
client)) return; if ( const filter: { fromSelf: (message: Message, client: Client) => boolean; hasContent: (message: Message) => message is DecodedMessageWithContent; isDM: (conversation: Group | Dm) => conversation is Dm; isGroup: (conversation: Group | Dm) => conversation is Group; isGroupAdminAsync: (conversation: Group | Dm, message: Message) => Promise<boolean>; isGroupSuperAdminAsync: (conversation: Group | Dm, message: Message) => Promise<boolean>; usesCodec: <T extends AnyContentCodec>(message: Message, codecClass: new () => T) => message is DecodedMessageWithContent<ReturnType<T["decode"]>>;}
Message and conversation tests for agent middleware.
filter.hasContent: (message: Message) => message is DecodedMessageWithContent
Check whether the content type is known and has decoded custom content.
hasContent(ctx: MessageContext<unknown, unknown>
ctx.MessageContext<unknown, unknown>.message: Message
The SDK message, including its tagged content and retained bytes.
message) && ctx: MessageContext<unknown, unknown>
ctx.MessageContext<unknown, unknown>.isText(): this is MessageContext<string, unknown>
Narrow this context to a text message.
isText() && (await const filter: { fromSelf: (message: Message, client: Client) => boolean; hasContent: (message: Message) => message is DecodedMessageWithContent; isDM: (conversation: Group | Dm) => conversation is Dm; isGroup: (conversation: Group | Dm) => conversation is Group; isGroupAdminAsync: (conversation: Group | Dm, message: Message) => Promise<boolean>; isGroupSuperAdminAsync: (conversation: Group | Dm, message: Message) => Promise<boolean>; usesCodec: <T extends AnyContentCodec>(message: Message, codecClass: new () => T) => message is DecodedMessageWithContent<ReturnType<T["decode"]>>;}
Message and conversation tests for agent middleware.
filter.isGroupAdminAsync: (conversation: Group | Dm, message: Message) => Promise<boolean>
Await this check before granting group admin access.
isGroupAdminAsync(ctx: MessageContext<string, unknown>
ctx.ConversationContext<unknown, Conversation>.conversation: Conversation
Return the conversation that triggered this context.
conversation, ctx: MessageContext<string, unknown>
ctx.MessageContext<Content = unknown, ContentTypes = unknown>.message: DecodedMessageWithContent<unknown>
The SDK message, including its tagged content and retained bytes.
message)) ) { await ctx: MessageContext<string, unknown>
ctx.MessageContext<string, unknown>.sendTextReply(text: string): Promise<void>
Send a text reply to this message with push disabled.
sendTextReply("Received text"); }});
await const agent: Agent<unknown>
agent.Agent<unknown>.start(options?: AgentStreamingOptions): Promise<void>
Start conversation and message streams. Calling this while running is a no-op.
start();
Await isGroupAdminAsync and isGroupSuperAdminAsync before an access check.
The examples use the async name to make this requirement clear.
MessageContext also supplies type guards for Markdown, text, replies, reactions, read receipts, remote attachments, transaction references, and wallet send calls.
usesCodec does not compare the minor version. hasContent accepts built-in content, including read receipts. It rejects unknown content and custom content that has no decoded value. After a context guard, read its decoded value from ctx.content.