Stream group updates with XMTP
Stream group metadata changes (name, description, members) in real-time using the group_updated
native content type. Group updates allow you to monitor changes to group conversations including member additions/removals, name changes, and description updates.
Listen for group updates
on('group-update', async (ctx) => {
// handle the group update
console.log(`Group updated: ${JSON.stringify(ctx.message.content)}`);
});
Group update message structure
{
conversationId: string,
contentType: { typeId: "group_updated" },
content: {
metadataFieldChanges?: Array<{
fieldName: string, // "group_name", "group_description", etc.
oldValue: string,
newValue: string
}>,
addedInboxes?: Array<{ // New members added
inboxId: string
}>,
initiatedByInboxId?: string // Who triggered the update
}
}
Usage examples
Monitor group name changes
on('group-update', async (ctx) => {
const content = ctx.message.content as any;
const nameChange = content.metadataFieldChanges?.find(
(change) => change.fieldName === 'group_name'
);
if (nameChange) {
console.log(
`Group renamed: ${nameChange.oldValue} → ${nameChange.newValue}`
);
}
});
Monitor member additions
on('group-update', async (ctx) => {
const content = ctx.message.content as any;
if (content.addedInboxes?.length > 0) {
console.log(`New members added: ${JSON.stringify(content.addedInboxes)}`);
}
});
Monitor member removals
on('group-update', async (ctx) => {
const content = ctx.message.content as any;
if (content.removedInboxes?.length > 0) {
console.log(`Members removed: ${JSON.stringify(content.removedInboxes)}`);
}
});
Filter by specific group
const targetGroupId = 'your-group-conversation-id';
on('group-update', async (ctx) => {
if (ctx.message.conversationId === targetGroupId) {
console.log(`Target group updated: ${JSON.stringify(ctx.message.content)}`);
}
});