mirror of
https://github.com/hanzoai/bot.git
synced 2026-10-30 17:24:26 +00:00
Three coordinated things:
1. Resolve the committed upstream/main merge conflicts. 94 files were
sitting with raw <<<<<<< HEAD ... >>>>>>> upstream/main blocks. Every
conflict had HanzoBot/Bot on HEAD and OpenClaw on upstream. Resolved
by keeping HEAD everywhere — 540 conflict blocks.
2. Rewrite remaining OpenClaw text refs.
OPENCLAW → HANZO_BOT
OpenClaw → HanzoBot (PascalCase type identifiers)
openclaw → bot (codebase convention — botToken,
botUsername etc.; avoids invalid
hyphenated JS identifiers)
openclaw[_]/openclaw[A-Z] → bot[_]/bot[A-Z] (compound)
ai.openclaw.x → ai.hanzo.bot.x (JVM package path)
3. Delete or rename openclaw-named file paths (116 of them). Dead
duplicates with a Bot-named canonical from the partial migration:
deleted. Otherwise renamed.
ai/openclaw/** → deleted (ai/hanzo/bot/** canonical)
Sources/OpenClaw*/ → deleted (Sources/Bot* canonical)
Tests/OpenClawIPCTests/ → deleted (Tests/BotIPCTests canonical)
OpenClawKit/ → deleted (BotKit canonical)
openclaw-tools.*.ts → deleted (bot-tools.*.ts canonical)
openclaw-root.ts etc. → deleted (bot-root.ts canonical)
types.openclaw.ts → deleted (types.bot.ts canonical)
extensions/*/openclaw.plugin.json → renamed hanzo-bot.plugin.json
docs/start/openclaw.md → renamed hanzo-bot.md (+ zh-CN)
docs/assets/openclaw-*.png, whatsapp-openclaw*.jpg → deleted
scripts/.../openclaw-* → deleted (bot/hanzo-bot parallels)
openclaw.mjs → deleted (hanzo-bot.mjs is package.bin)
Then patched 65 broken JS/TS import strings where hanzo-bot had ended
up inside an import path ('./types.hanzo-bot.js' → './types.bot.js'
etc., since the on-disk filename uses the brand-neutral bot- prefix).
Pre-existing lint debt cleaned up to get oxlint --type-aware to 0/0:
removed the dead i18n test that referenced a path no longer existing;
defined the missing DIDConfig and WalletConfig types in types.base.ts
(they were imported but never declared); dropped unused imports;
collapsed redundant type assertion and a tautological meta.bot lookup
that the openclaw→bot rename made redundant.
The a2ui.bundle.js generated artifact is kept at its pre-rebrand
contents — it gets regenerated by 'pnpm canvas:a2ui:bundle' from
sources I cannot rebuild in this commit; the source side is clean.
Verified: 0 occurrences of openclaw (case-insensitive) in tree source
content, 0 file or directory paths with openclaw in the name; oxlint
--type-aware src test reports 0/0.
7.7 KiB
7.7 KiB
summary, read_when, title
| summary | read_when | title | ||
|---|---|---|---|---|
| CLI reference for `hanzo-bot message` (send + channel actions) |
|
message |
hanzo-bot message
Single outbound command for sending messages and channel actions (Discord/Google Chat/Slack/Mattermost (plugin)/Telegram/WhatsApp/Signal/iMessage/MS Teams).
Usage
hanzo-bot message <subcommand> [flags]
Channel selection:
--channelrequired if more than one channel is configured.- If exactly one channel is configured, it becomes the default.
- Values:
whatsapp|telegram|discord|googlechat|slack|mattermost|signal|imessage|msteams(Mattermost requires plugin)
Target formats (--target):
- WhatsApp: E.164 or group JID
- Telegram: chat id or
@username - Discord:
channel:<id>oruser:<id>(or<@id>mention; raw numeric ids are treated as channels) - Google Chat:
spaces/<spaceId>orusers/<userId> - Slack:
channel:<id>oruser:<id>(raw channel id is accepted) - Mattermost (plugin):
channel:<id>,user:<id>, or@username(bare ids are treated as channels) - Signal:
+E.164,group:<id>,signal:+E.164,signal:group:<id>, orusername:<name>/u:<name> - iMessage: handle,
chat_id:<id>,chat_guid:<guid>, orchat_identifier:<id> - MS Teams: conversation id (
19:[email protected]) orconversation:<id>oruser:<aad-object-id>
Name lookup:
- For supported providers (Discord/Slack/etc), channel names like
Helpor#helpare resolved via the directory cache. - On cache miss, HanzoBot will attempt a live directory lookup when the provider supports it.
Common flags
--channel <name>--account <id>--target <dest>(target channel or user for send/poll/read/etc)--targets <name>(repeat; broadcast only)--json--dry-run--verbose
Actions
Core
-
send- Channels: WhatsApp/Telegram/Discord/Google Chat/Slack/Mattermost (plugin)/Signal/iMessage/MS Teams
- Required:
--target, plus--messageor--media - Optional:
--media,--reply-to,--thread-id,--gif-playback - Telegram only:
--buttons(requireschannels.telegram.capabilities.inlineButtonsto allow it) - Telegram only:
--thread-id(forum topic id) - Slack only:
--thread-id(thread timestamp;--reply-touses the same field) - WhatsApp only:
--gif-playback
-
poll- Channels: WhatsApp/Telegram/Discord/Matrix/MS Teams
- Required:
--target,--poll-question,--poll-option(repeat) - Optional:
--poll-multi - Discord only:
--poll-duration-hours,--silent,--message - Telegram only:
--poll-duration-seconds(5-600),--silent,--poll-anonymous/--poll-public,--thread-id
-
react- Channels: Discord/Google Chat/Slack/Telegram/WhatsApp/Signal
- Required:
--message-id,--target - Optional:
--emoji,--remove,--participant,--from-me,--target-author,--target-author-uuid - Note:
--removerequires--emoji(omit--emojito clear own reactions where supported; see /tools/reactions) - WhatsApp only:
--participant,--from-me - Signal group reactions:
--target-authoror--target-author-uuidrequired
-
reactions- Channels: Discord/Google Chat/Slack
- Required:
--message-id,--target - Optional:
--limit
-
read- Channels: Discord/Slack
- Required:
--target - Optional:
--limit,--before,--after - Discord only:
--around
-
edit- Channels: Discord/Slack
- Required:
--message-id,--message,--target
-
delete- Channels: Discord/Slack/Telegram
- Required:
--message-id,--target
-
pin/unpin- Channels: Discord/Slack
- Required:
--message-id,--target
-
pins(list)- Channels: Discord/Slack
- Required:
--target
-
permissions- Channels: Discord
- Required:
--target
-
search- Channels: Discord
- Required:
--guild-id,--query - Optional:
--channel-id,--channel-ids(repeat),--author-id,--author-ids(repeat),--limit
Threads
-
thread create- Channels: Discord
- Required:
--thread-name,--target(channel id) - Optional:
--message-id,--message,--auto-archive-min
-
thread list- Channels: Discord
- Required:
--guild-id - Optional:
--channel-id,--include-archived,--before,--limit
-
thread reply- Channels: Discord
- Required:
--target(thread id),--message - Optional:
--media,--reply-to
Emojis
-
emoji list- Discord:
--guild-id - Slack: no extra flags
- Discord:
-
emoji upload- Channels: Discord
- Required:
--guild-id,--emoji-name,--media - Optional:
--role-ids(repeat)
Stickers
-
sticker send- Channels: Discord
- Required:
--target,--sticker-id(repeat) - Optional:
--message
-
sticker upload- Channels: Discord
- Required:
--guild-id,--sticker-name,--sticker-desc,--sticker-tags,--media
Roles / Channels / Members / Voice
role info(Discord):--guild-idrole add/role remove(Discord):--guild-id,--user-id,--role-idchannel info(Discord):--targetchannel list(Discord):--guild-idmember info(Discord/Slack):--user-id(+--guild-idfor Discord)voice status(Discord):--guild-id,--user-id
Events
event list(Discord):--guild-idevent create(Discord):--guild-id,--event-name,--start-time- Optional:
--end-time,--desc,--channel-id,--location,--event-type
- Optional:
Moderation (Discord)
timeout:--guild-id,--user-id(optional--duration-minor--until; omit both to clear timeout)kick:--guild-id,--user-id(+--reason)ban:--guild-id,--user-id(+--delete-days,--reason)timeoutalso supports--reason
Broadcast
broadcast- Channels: any configured channel; use
--channel allto target all providers - Required:
--targets(repeat) - Optional:
--message,--media,--dry-run
- Channels: any configured channel; use
Examples
Send a Discord reply:
hanzo-bot message send --channel discord \
--target channel:123 --message "hi" --reply-to 456
Send a Discord message with components:
hanzo-bot message send --channel discord \
--target channel:123 --message "Choose:" \
--components '{"text":"Choose a path","blocks":[{"type":"actions","buttons":[{"label":"Approve","style":"success"},{"label":"Decline","style":"danger"}]}]}'
See Discord components for the full schema.
Create a Discord poll:
hanzo-bot message poll --channel discord \
--target channel:123 \
--poll-question "Snack?" \
--poll-option Pizza --poll-option Sushi \
--poll-multi --poll-duration-hours 48
Create a Telegram poll (auto-close in 2 minutes):
hanzo-bot message poll --channel telegram \
--target @mychat \
--poll-question "Lunch?" \
--poll-option Pizza --poll-option Sushi \
--poll-duration-seconds 120 --silent
Send a Teams proactive message:
hanzo-bot message send --channel msteams \
--target conversation:19:[email protected] --message "hi"
Create a Teams poll:
hanzo-bot message poll --channel msteams \
--target conversation:19:[email protected] \
--poll-question "Lunch?" \
--poll-option Pizza --poll-option Sushi
React in Slack:
hanzo-bot message react --channel slack \
--target C123 --message-id 456 --emoji "✅"
React in a Signal group:
hanzo-bot message react --channel signal \
--target signal:group:abc123 --message-id 1737630212345 \
--emoji "✅" --target-author-uuid 123e4567-e89b-12d3-a456-426614174000
Send Telegram inline buttons:
hanzo-bot message send --channel telegram --target @mychat --message "Choose:" \
--buttons '[ [{"text":"Yes","callback_data":"cmd:yes"}], [{"text":"No","callback_data":"cmd:no"}] ]'