Groups & Admin
For bots in groups and supergroups, chat_info queries chat data and chat_admin performs moderation actions. The admin actions are written with the chat.* keyword (e.g. chat.ban, chat.invite_link).
Your bot must be an administrator in the chat with the relevant permissions for these actions to succeed. Wrap them in try/catch or on error — they can fail.
chat_info
Query chat information, administrators, member count, or a specific member.
let { count } = chat.info(chat_id: shared.group_chat_id, mode: "member_count")
send.text(`This group has ${count} members.`)
| Param | Type | Notes |
|---|---|---|
chat_id | Number | Target chat (default: current) |
mode! | String | What to fetch (chat, admins, member count, member) |
user_id | Number | For member lookups |
chat_admin actions
All variants are written as chat.<action>(...) and take a chat_id (defaults to the current chat) and usually a user_id.
Membership control
chat.ban(user_id: flow.uid, revoke_messages: true)
chat.unban(user_id: flow.uid, only_if_banned: true)
chat.mute(user_id: flow.uid, until_date: flow.until)
chat.unmute(user_id: flow.uid)
chat.restrict(user_id: flow.uid, permissions: { can_send_messages: false }, until_date: flow.until)
| Action | Params |
|---|---|
chat.ban | user_id, revoke_messages, until_date |
chat.unban | user_id, only_if_banned |
chat.mute | user_id, until_date |
chat.unmute | user_id |
chat.restrict | user_id, permissions, until_date |
chat.set_permissions | permissions (chat-wide) |
Promotion
chat.promote(user_id: flow.uid, can_delete_messages: true, can_restrict_members: true, custom_title: "Mod")
chat.demote(user_id: flow.uid)
chat.promote accepts the full set of admin permission flags: can_change_info, can_delete_messages, can_invite_users, can_manage_chat, can_manage_topics, can_manage_video_chats, can_pin_messages, can_promote_members, can_restrict_members, is_anonymous, plus custom_title. chat.demote removes admin rights.
Join requests
chat.approve(user_id: flow.uid) // approve a pending join request
chat.decline(user_id: flow.uid) // decline it
Invite links
lk = chat.invite_link(
chat_id: shared.group_chat_id,
name: "Paid Members",
creates_join_request: true,
expire_date: flow.expire,
member_limit: 100
)
send.text(`🔗 Invite link: ${lk}`)
chat.revoke_invite(invite_link: flow.old_link)
| Action | Params | Returns |
|---|---|---|
chat.invite_link (create) | name, creates_join_request, expire_date, member_limit | the link string |
chat.revoke_invite | invite_link | — |
All 12 actions
ban, unban, mute, unmute, restrict, set_permissions, promote, demote, approve_join (chat.approve), decline_join (chat.decline), create_invite (chat.invite_link), revoke_invite.
Deleting messages and reacting
To remove an offending message, use the delete node (there is no chat.delete_message):
delete(message) // delete the triggering message
For moderation feedback you can also pin notices and react to messages:
msg.pin/msg.unpin— pin rules or a "watch" notice; unpin when resolved.react— set the bot's emoji reaction (e.g. ⚠️ on a flagged message).- The
on reactiontrigger lets members report or react; theon inline_querytrigger powers@yourbot-style lookups inside the group.
chat.mute and chat.restrict take until_date — a unix timestamp (e.g. time.timestamp() + 3600), not a duration string.
A complete moderation snippet
flow on_join_request on join_request {
set { flow.uid = request.from.id }
set { flow.name = request.from.first_name }
when !types.isNil(array.find(shared.paid_uids, "uid", flow.uid)) {
try {
chat.approve(user_id: flow.uid)
send.text(`✅ ${flow.name} was auto-approved.`)
} catch err {
send.text(`⚠️ Approve failed: ${err}`)
}
} else {
send.text(`🔔 Unpaid join request from ${flow.name}.`, chat_id: global.admin_id)
}
}
See also
- Triggers — group event triggers
- Groups & moderation patterns