messaging

SKILL.md

Messaging & IM Gateway

Channel Types

Type Direction Capabilities
telegram Bidirectional Send/receive messages, bot commands, inline replies
webhook Outbound only Send messages to Slack, DingTalk, WeChat Work, custom endpoints

Bidirectional channels can trigger AI CLI sessions when users send messages. Outbound-only channels can receive messages from the agent but cannot trigger sessions.


Channel Management

Add a Telegram channel (bidirectional)

aiter message add-channel \
  --type telegram \
  --name "Dev Team Bot" \
  --token "$TELEGRAM_BOT_TOKEN"

To get a Telegram bot token:

  1. Message @BotFather on Telegram
  2. Send /newbot and follow prompts
  3. Copy the token provided

Add a Webhook channel (Slack, DingTalk, etc.)

# Slack incoming webhook
aiter message add-channel \
  --type webhook \
  --name "Slack Alerts" \
  --url "https://hooks.slack.com/services/T00/B00/xxx"

# DingTalk webhook
aiter message add-channel \
  --type webhook \
  --name "DingTalk Team" \
  --url "https://oapi.dingtalk.com/robot/send?access_token=xxx"

# WeChat Work webhook
aiter message add-channel \
  --type webhook \
  --name "WeChat Work" \
  --url "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"

# Custom webhook (any endpoint accepting POST JSON)
aiter message add-channel \
  --type webhook \
  --name "Custom" \
  --url "https://my-api.com/webhook"

List channels

aiter message channels

Response:

{
  "success": true,
  "data": [
    {
      "id": "channel-abc123",
      "name": "Dev Team Bot",
      "type": "telegram",
      "connected": true,
      "projectId": null
    },
    {
      "id": "channel-def456",
      "name": "Slack Alerts",
      "type": "webhook",
      "connected": false,
      "projectId": null
    }
  ]
}

Connect / Disconnect

# Start listening for incoming messages (bidirectional channels)
aiter message connect --id channel-abc123

# Stop listening
aiter message disconnect --id channel-abc123

Remove a channel

aiter message remove-channel --id channel-abc123

Sending Messages

Send to a specific channel

# Plain text
aiter message send --channel channel-abc123 --text "Build completed successfully!"

# Markdown formatted
aiter message send --channel channel-abc123 --text "**Build Status**\n- Frontend: OK\n- Backend: OK\n- Tests: 42/42 passed" --format markdown

Reply to IM-triggered session

When a session is triggered by an incoming IM message, reply directly:

# Uses $AITER_REPLY_CHANNEL and $AITER_REPLY_CONTEXT automatically
aiter message reply --text "Here's the information you requested..."

# Or specify channel explicitly
aiter message reply --text "Status update..." --channel channel-abc123 --format markdown

Important: Always use aiter message reply (not send) when responding to IM-triggered sessions. The reply command preserves the conversation context.


Message Routing

Routes determine how incoming IM messages are forwarded to project terminals.

Create a route

# Route all messages from a channel to a project
aiter message add-route \
  --channelId channel-abc123 \
  --projectId project-789

# Route with command prefix (only messages starting with /ask)
aiter message add-route \
  --channelId channel-abc123 \
  --projectId project-789 \
  --commandPrefix "/ask"

# Route to a specific terminal
aiter message add-route \
  --channelId channel-abc123 \
  --projectId project-789 \
  --terminalId terminal-456

How routing works

User sends message in Telegram: "/ask What's the build status?"
AiTer IMGateway receives message
Route matches: channel-abc123 → project-789, prefix "/ask"
AiTer strips prefix, writes message to project terminal
Sets environment variables:
  AITER_REPLY_CHANNEL=channel-abc123
  AITER_REPLY_CONTEXT="What's the build status?"
AI CLI (if running) processes the message
SessionStart hook detects $AITER_REPLY_CHANNEL
support-responder agent handles the request
Agent replies via: aiter message reply --text "..."
User receives reply in Telegram

List routes

aiter message routes

Remove a route

aiter message remove-route --id route-xyz

IM-Triggered Session Pattern

When $AITER_REPLY_CHANNEL is set, this session was triggered by an incoming IM message.

Detection

# Check if this is an IM-triggered session
if [ -n "$AITER_REPLY_CHANNEL" ]; then
  echo "IM-triggered session from channel: $AITER_REPLY_CHANNEL"
  echo "User message: $AITER_REPLY_CONTEXT"
fi

Response flow

  1. Read $AITER_REPLY_CONTEXT for the user's message
  2. Search .aiter/memory/knowledge.md for relevant context
  3. Process the request (answer question, run command, check status, etc.)
  4. Reply via aiter message reply --text "..." --format markdown
  5. Log interaction in .aiter/memory/journal.md

Best practices for IM responses

  • Keep replies concise — IM is not a document format
  • Use markdown formatting for structure (bullets, bold, code blocks)
  • For long outputs, summarize and offer to share full details via tunnel
  • Always acknowledge the request before starting long-running tasks
  • Include relevant numbers and metrics in replies (not just "it worked")

Multi-Channel Broadcasting

Send the same message to multiple channels:

# Get all channel IDs
CHANNELS=$(aiter message channels | jq -r '.data[].id')

# Send to each
for CHANNEL in $CHANNELS; do
  aiter message send --channel $CHANNEL --text "System maintenance in 30 minutes" --format markdown
done

Rate Limits and Constraints

Constraint Limit
Message length 4096 characters per message
Messages per minute 20 per channel
Channels per project 10 max
Active connections 5 concurrent
Message storage Last 1000 messages per channel

If a message exceeds the length limit, split it into multiple messages or share via tunnel URL.

Weekly Installs
1
Repository
within-7/aiter
First Seen
14 days ago
Installed on
amp1
cline1
openclaw1
opencode1
cursor1
kimi-cli1