Downcity
CommandsService

city chat

Interactive chat service management and actions (status/test/reconnect/open/close/configuration/configure/list/info/send/react/context/delete/history)

city chat

Manage the chat service, configure city-level channel accounts, send messages, react to messages, inspect context, and read chat history.

Bare city chat opens an interactive manager. Scripted usage can still call the subcommands below.

Usage

city chat
city chat <subcommand> [options]

Interactive Management

Running city chat lets you:

  • inspect, start, stop, and restart the current project's chat service
  • choose "Configure channel" to manage city-level Telegram / Feishu / QQ accounts
  • add, edit, and remove channel accounts
  • choose "Configure authorization" to assign auth roles to platform users

Channel accounts and chat authorization are stored in the city-global ~/.downcity/downcity.db. Agent projects only store services.chat.channels.<channel>.channelAccountId bindings.

Subcommands

  • status: show channel link status
  • test: run channel connectivity checks
  • reconnect: reconnect channels (all by default, or one channel)
  • open: enable a channel (enabled=true in downcity.json, then try to start if configured)
  • close: disable a channel (enabled=false in downcity.json, and stop runtime channel)
  • configuration: inspect channel configuration schema (field name/type/description/source)
  • configure: update channel parameters (downcity.json patch, restart channel by default)
  • list: list conversations recorded by current agent (chatTitle/chatKey)
  • info: show one conversation info (route snapshot + local paths + context snapshot)
  • send: send message
  • react: react to message (primarily Telegram)
  • context: view conversation context snapshot
  • delete: fully delete a conversation (route mapping + chat history + context directory)
  • history: read chat history
  • auth set <platform:userId>: set a platform user's auth role, for example city chat auth set telegram:12345678

auth set key options

  • <platform:userId>: authorization principal, such as telegram:12345678, feishu:ou_xxx, or qq:123456
  • --role <roleId>: set a role directly; omit it to choose interactively

When a chat user is denied, the denial message includes a command they can forward to an admin:

city chat auth set telegram:12345678

status/test/reconnect/open/close key options

  • --channel <telegram|feishu|qq>: run against one channel only (all channels if omitted)

configure key options

  • --channel <telegram|feishu|qq>: target channel
  • --config-json <json>: config patch JSON object
  • --restart: restart the channel after config update

configuration key options

  • --channel <telegram|feishu|qq>: inspect one channel only (all channels if omitted)

list key options

  • --channel <telegram|feishu|qq>: filter by channel
  • --limit <n>: return at most N items (default 50)
  • --q <text>: keyword filter (title/chatId/sessionId/actor)

info key options

  • --chat-key <chatKey>: target conversation (fallback to DC_CTX_CHAT_KEY)
  • --session-id <sessionId>: explicit session id (higher priority)

send key options

  • --text <text>: message body
  • --stdin: read message body from stdin
  • --text-file <file>: read message body from file
  • --chat-key <chatKey>: target conversation
  • --delay <ms>: delayed send
  • --time <time>: scheduled send (unix sec/ms or ISO)
  • --reply: send as reply_to_message
  • --message-id <id>: explicitly set the reply target message ID

About --delay / --time:

  • the command returns as soon as runtime accepts the request, while actual delivery is handled by the persistent scheduler
  • scheduled jobs are written to the current agent project's .downcity/schedule.sqlite
  • unfinished delayed/scheduled sends are restored after runtime restart
  • --delay and --time cannot be used together
  • this is intended for one-shot delayed/scheduled sends; use task service for cron or longer workflows

For detailed behavior, recovery rules, and API examples, see:

send body also supports:

  • optional frontmatter metadata with the same meaning as chat send parameters (chatKey, delay, time, reply, messageId)
  • attachments via <file type="...">path</file>
  • text and <file> blocks can be interleaved; delivery preserves their actual order in the message body

react key options

  • --emoji <emoji>: emoji, default 👍
  • --message-id <id>: target message ID
  • --chat-key <chatKey>: target conversation
  • --big: Telegram large emoji (is_big)

delete key options

  • --chat-key <chatKey>
  • --session-id <sessionId>

history key options

  • --chat-key <chatKey>
  • --session-id <sessionId>
  • --limit <n>
  • --direction <all|inbound|outbound>
  • --before-ts <ts> / --after-ts <ts> (milliseconds)

Examples

city chat list --limit 20
city chat info --chat-key ctx_xxxxxxxxxxxxxxxx
city chat send --chat-key ctx_xxxxxxxxxxxxxxxx --text "done"
cat <<'EOF' | city chat send --stdin --chat-key ctx_xxxxxxxxxxxxxxxx
---
reply: true
messageId: "128"
---
Here is the opening note for today's report.

<file type="document" caption="Daily report PDF">reports/daily.pdf</file>

Please focus on page 3.

<file type="photo" caption="Chart preview">assets/chart.png</file>

Then give me a three-line conclusion.
EOF
city chat react --chat-key ctx_xxxxxxxxxxxxxxxx --emoji "✅"
city chat context --chat-key ctx_xxxxxxxxxxxxxxxx
city chat delete --chat-key ctx_xxxxxxxxxxxxxxxx
city chat history --chat-key ctx_xxxxxxxxxxxxxxxx --limit 50
city chat status
city chat test --channel telegram
city chat reconnect --channel qq
city chat open --channel qq
city chat close --channel telegram
city chat configuration --channel qq
city chat configure --channel qq --config-json '{"channelAccountId":"qq-main","enabled":true}'

Notes

This command group usually requires an active agent:

city agent start

Attachment protocol notes:

  • send now uses one unified protocol only: frontmatter metadata + <file ...>...</file>
  • @attach is no longer used
  • when the target channel supports attachments, the agent sends text and attachments in their actual interleaved order

Example Output (Based on Current Implementation)

The examples below are aligned with current command implementations in packages/downcity/src (including default output mode and field structure). Placeholder values are used for environment-specific fields.

$ city chat status
{
  "success": true,
  "data": {
    "success": true,
    "channels": {
      "telegram": {"state": "connected"}
    }
  }
}
$ city chat send --chat-key <chatKey> --text "done"
{
  "success": true,
  "data": {
    "success": true
  }
}