Skip to content

IM bots

AICodeReviewer can push aggregated review problems to a Feishu or WeCom group via a custom-bot webhook or a Feishu custom application’s bot. These are summary channels — they receive the rolled-up review result, not per-line comments. Configure routing in outputs.routes or per-workspace outputs.summary.

  1. Open the target group → Settings → Group Bots → Add Bot → Custom Bot
  2. Set the bot name and avatar
  3. Copy the webhook URL (https://open.feishu.cn/open-apis/bot/v2/hook/...)
  4. If you enable signature verification (recommended), copy the signing secret shown in the bot settings
  5. Click Save
Terminal window
# Required
export AICR_FEISHU_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx"
# Required only if signature verification is enabled in Feishu bot settings
export AICR_FEISHU_SECRET="your-signing-secret"
outputs:
channels:
- name: feishu-code-review
kind: feishu_bot
webhook_url_env: AICR_FEISHU_WEBHOOK # env var holding the webhook URL
secret_env: AICR_FEISHU_SECRET # required if the bot has signature verification
mention_author: true # @-mention the commit author
mention_fallback: skip # "all" | "skip" when author can't be resolved
outputs:
routes:
default:
line_comments: [gitea-pr-review]
summary: [gitea-pr-review]
rules:
# Route P4 changelists to Feishu
- match:
trigger: p4-main
target_kind: commit
summary: [feishu-code-review]
# Route GitHub push reviews to Feishu. Without a summary route, runs
# with problems can be recorded as skipped (skipReason="no_output_publisher").
- match:
trigger: github
target_kind: push
summary: [feishu-code-review]

Or pin the channel at the workspace level:

workspaces:
instances:
p4-main:
source_repo:
trigger: p4-main
repo: "//depot/main"
outputs:
summary: [feishu-code-review]

When signature verification is enabled on the Feishu bot, every request must include a timestamp and sign field. AICR computes the signature automatically from the secret named by secret_env:

string_to_sign = timestamp + "\n" + secret
signature = Base64(HMAC-SHA256(key=string_to_sign, message=""))

If you see error 19021: sign match fail, verify that the secret_env value matches the signing secret shown on the Feishu bot configuration page.

AICR sends Feishu cards using the JSON 2.0 schema (card.schema = "2.0", markdown placed under card.body.elements). Under 2.0, inline code, fenced code blocks with language parsing, headings, blockquotes, and tables all render natively. AICR applies toFeishuMarkdown() before dispatch — it only runs Markdown fixing and blank-line collapse, and does not downgrade headings to bold or tables to plain text (those 1.0-era transforms break 2.0 rendering). If inline code or code highlighting ever appears as literal backticks, confirm the channel dispatcher is on the 2.0 schema path.

When the summary route also records the run on an issue-recording channel (gitea_problem_issue, github_problem_issue, or gitlab_problem_issue), the Feishu card links the created issue instead of duplicating every problem. issue_link_card on the feishu_bot/feishu_app channel selects the card content:

  • titles (default): headline, problem count, one title line per problem, and the full-report link
  • brief: headline, problem count, and the link only
  • full: headline, complete problem sections, and the link
outputs:
channels:
- name: feishu-code-review
kind: feishu_bot
webhook_url_env: AICR_FEISHU_WEBHOOK
issue_link_card: full # brief | titles (default) | full

Use feishu_app to send reports as a custom application’s bot. Enable the bot capability, publish the application, and add it to the report group and member source group. These groups may differ. A direct-message recipient must be within the application’s availability scope. This outbound integration needs no event subscription, callback server, or WebSocket connection of its own; enabling the report card’s re-review button additionally requires an IM connection with event callbacks for the same application (see Review card button).

  1. Create a custom enterprise app in the Developer Console. Under App capabilities → Add capabilities, enable Bot.
  2. Open Development configuration → Permissions → API permissions and search for the scope identifiers below. Grant application identity permissions: AICR uses tenant_access_token and needs no user OAuth authorization.
  3. For profile matching, add the source group’s users or departments under Permissions → Data permissions → Contact permission scope. Group-member access does not expand this scope; app availability is a separate setting.
  4. Create a version under App release → Version management and release, set its availability, submit it for review and confirm activation. After later permission or availability changes, complete publication and administrator approval as instructed by the console.
  5. Add the bot to the report group and, when using a directory, the group in member_directory.chat_id. Allow the bot to speak in the report group. Direct-message recipients must be within the app’s availability scope.

The following scopes cover the APIs AICR calls. Sending reports to chat_id or open_id alone needs only the first row. Directory association adds group-member access, the contact API permission and the required profile-field permissions.

Purpose Scope identifier When needed
Send reports as the app im:message:send_as_bot Required for every feishu_app channel
List source-group members im:chat.members:read A directory is configured and mention_author is enabled
Call the user-profile API contact:contact.base:readonly Enrich members through GET /contact/v3/users/:user_id
Name, English name and alias contact:user.base:readonly Read name, en_name and nickname
Email contact:user.email:readonly Recommended for matching the email field
Enterprise email contact:user.employee:readonly Read enterprise_email
Mobile number contact:user.phone:readonly Read mobile
User ID contact:user.employee_id:readonly Read user_id or use receive_id_type: user_id

API access and field access are separate checks: contact:user.base:readonly alone does not grant access to the contact API. The table selects a supported combination; existing alternative scopes listed by the official API pages do not require additional broader grants. AICR lists members and renders mentions with open_id, so mentions do not require mobile numbers or user_id. email and enterprise_email have different field permissions; enterprise email also requires the administrator to enable Feishu Mail. Grant all rows only if you need all supported profile fields, and check that users have filled in those fields.

Sources: send message, list group members, get user information and app availability. External users, users outside the contact scope and unauthorized sensitive fields may remain unavailable. AICR keeps available group data and omits uncertain mentions. For error 41050, check contact scope; for 230002, check that the bot is in the recipient group; for 230013, check the direct recipient’s app availability.

Set AICR_FEISHU_APP_SECRET in the server environment, then merge this configuration:

outputs:
channels:
- name: feishu-app-review
kind: feishu_app
app_id: cli_replace_me
app_secret_env: AICR_FEISHU_APP_SECRET
receive_id_type: chat_id
receive_id: oc_report_group
mention_author: true
mention_fallback: skip
guess_author: true
member_directory:
chat_id: oc_member_source_group
cache_ttl_seconds: 300
user_mappings:
"[email protected]": ou_replace_with_app_open_id
"alice-dev-workspace": ou_replace_with_app_open_id
routes:
default:
summary: [feishu-app-review]

app_id and receive_id are required. Choose exactly one of app_secret_env or literal app_secret; database-backed literals use the existing sealing and masked-edit workflow. receive_id_type defaults to chat_id; open_id, user_id, union_id and email target individual users. base_url defaults to https://open.feishu.cn; the only alternative is https://open.larksuite.com. Do not append /open-apis. Open IDs are application-specific.

Both Feishu channels share built-in feishu-summary.hbs, problem rendering, JSON 2.0 cards and publish_if_summary as the default zero-problem policy. Named templates.summary / templates.problem references take precedence. Workspace lookup checks the channel name, then feishu_app.*, then feishu_bot.*, then generic templates. A webhook workspace template can therefore also render application reports. Application sends wrap the card as a JSON string in the message API’s content field.

With mention_author: true, AICR pages through member_directory.chat_id and enriches each member with the fields the app may read: name, en_name, nickname, email, enterprise_email, mobile, open_id, user_id and union_id. Only these fields are kept in memory. The cache lasts 12 hours by default; cache_ttl_seconds accepts 0–604800 (7 days), with 0 disabling reuse. The channel value overrides the global outputs.author_resolution.directory_cache_ttl_seconds. A new configuration generation has a separate cache. Both TTL fields support static files and database configuration, under the usual file ownership rules. Temporary transport, HTTP 429 or HTTP 5xx failures may use an expired snapshot with a diagnostic; the next call retries. Permission rejections and incomplete member lists invalidate the snapshot. Zero TTL keeps no snapshot for fallback. Without a usable snapshot the report sends without mentions. Directory data stays in the host’s publication path and the dedicated identity call; review MCP tools do not expose the member list. Profiles use at most four concurrent requests; each request has a 15-second timeout and the refresh has a 60-second work budget.

Matching uses case-insensitive, Unicode-normalized values in this order:

  1. Channel-local user_mappings: exact author email, username, display name or complete P4 submitter workspace to the same app’s open_id. If a directory is configured, the mapped user must be in that directory.
  2. P4 submitterWorkspace against complete identifier segments separated by punctuation or spaces. For example, build_alice_PC matches alias alice; malice_PC does not. Short aliases below three characters are excluded here, except Chinese names with at least two characters. A unique workspace match takes precedence over a shared account such as admin, even if that login matches another member’s email local part. Other providers skip this step.
  3. Full author email against personal or enterprise email.
  4. Exact username/display name against names, aliases, email local parts, phone numbers or IDs.
  5. If all rules have no match and guess_author is enabled, a dedicated LLM call may associate the submitter with one directory candidate or abstain.

A tier with multiple candidates suppresses the mention without trying weaker tiers or the model; this includes ambiguous P4 workspaces, even with mention_fallback: all. The global email blacklist also suppresses it. AICR does not use the push delivery actor or the analysis service’s P4 workspace. mention_author defaults to false. Without a directory, only explicit user_mappings resolve users; global Git login mappings are not Feishu IDs. Use mention_fallback: skip to avoid notifying everyone on an unmatched author.

guess_author defaults to true for feishu_app. Setting it to false disables workspace heuristics and the model fallback while retaining explicit mappings and exact email/name/alias matches. mention_author remains the switch for actual notifications; when false, neither the directory nor the model is called. Git output channels retain their platform-native author resolution. Webhook Feishu and WeCom bots have no member-directory capability and never run this model association.

For alias owent and work email [email protected], P4 workspace owent_myrion-pc_6689, independent P4 username owent, or GitHub/Gitea username owent and that email already match through rules. No model call is needed. For otherwise unmatched evidence, configure an independent model group:

llm:
model_chain:
default:
- provider: your-existing-provider
model: your-review-model
role: heavy
directory-identity:
- provider: your-existing-provider
model: your-identity-model
role: light
author_resolution_model_chain: directory-identity
workspaces:
defaults:
author_resolution_model_chain: directory-identity
instances:
your-workspace:
author_resolution_model_chain: directory-identity

Merge the group into your existing configuration. Selection is workspace instance → workspace defaults → llm.author_resolution_model_chain → llm.default_model_chain; it does not inherit the workspace review group. All three fields support static files and database management. In the dashboard, use Model groups → Model chains for the global setting and Workspaces for defaults or instance overrides. Normal database priority/reset and model-group reference validation apply. Each running task keeps its admitted configuration generation even if settings are published before its report is sent.

The dedicated identity prompt sends only submitter identity hints and candidate names, aliases and emails to the selected model provider. Phone numbers, native directory IDs, credentials, review code and reports are excluded. Candidate keys are temporary; the host validates membership and renders the mention. Directory records never enter the main code-review prompt or persistent report state. Only an allowed candidate with high model confidence is accepted. Ambiguity, abstention, invalid output, model failure or a 15-second deadline suppresses @ without suppressing the report, including with mention_fallback: all. The call uses the configured fallback/retry chain, provider limits and shared run/daily budgets. More than 500 candidates or a serialized input over 64,000 characters skips model analysis entirely; candidates are never silently truncated. See the configuration reference for field paths.

Directory failures or security-limited membership lists send the report without mentions. Contact lookup failures retain only the available group fields and emit a diagnostic without personal data. A source-group match may not be a member of the report group; actual mention delivery still depends on Feishu’s membership and notification rules. Validate that boundary in your tenant.

The client caches tenant access tokens and refreshes an explicitly rejected token once. HTTP errors, nonzero API codes and missing message receipts fail publication. Delivery may already have occurred after a transport failure. Automatic commit batches persist the send identity and reuse its UUID for up to 59 minutes after the first attempt; SQLite or Redis retains it across restarts. An expired UUID or changed uncertain request blocks resending. Other review paths reuse an in-memory UUID only for the token retry, without restart recovery.

  1. Open the target group → Group Settings → Group Bots → Add Bot
  2. Set the bot name and avatar
  3. Copy the webhook URL (https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=...)
  4. Click Save
Terminal window
# Required
export AICR_WECOM_WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx"

WeCom group-bot webhooks do not use HMAC signature verification; no secret env var is needed.

outputs:
channels:
- name: wecom-ops
kind: wecom_bot
webhook_url_env: AICR_WECOM_WEBHOOK
mention_author: false # @-mention the commit author
mention_fallback: skip # "all" | "skip" when author can't be resolved
no_problems: { action: suppress }
# mentioned_mobile_list: ["+86-13800138000"] # optional: sends one bounded text
# reminder; mobile mentions only exist on the text message type
outputs:
routes:
default:
line_comments: [gitea-pr-review]
summary: [gitea-pr-review]
rules:
# Route P4 changelists to WeCom
- match:
trigger: p4-main
target_kind: commit
summary: [wecom-ops]

WeCom group-bot messages support a subset of Markdown: headings, bold, links, inline code, and blockquotes render natively. Tables are flattened to plain-text rows. Code fences are preserved. AICR applies toWeComMarkdown() automatically before dispatch.

Reports keep every problem’s complete message, suggestion and code reference. WeCom webhook Markdown has a 4096-byte UTF-8 limit. Only excess text is truncated, with a notice; the native mention remains. Feishu webhook requests are bounded at 20 KiB and application card requests at 30 KiB, including JSON escaping and request fields. Report links, mentions and card buttons remain. WeCom application reports split into 2048-byte parts.

IM channels without a directory API (wecom_bot, feishu_bot, wecom_app) can resolve commit authors against a strict YAML/JSON member file and emit native typed mentions instead of plain @username text:

outputs:
channels:
- name: wecom-group
kind: wecom_bot
webhook_url_env: AICR_WECOM_WEBHOOK
mention_author: true
member_directory:
source: file
path: ./private/im-members.yaml
directory_id: engineering-wecom
identity_scope: { kind: wecom_corp, id: ww_example }
watch: true # parent-directory watch, default on

Keep member files owned by the runtime user, with directory mode 0700 and file mode 0600. In deploy.sh deployments, /app/data/private maps to the host’s data/db/private; permission repair preserves this subtree and task backups under data/db/build.

The member file format is documented in the configuration reference; highlights:

Without a directory, native webhook mentions require explicit outputs.author_resolution.email_mappings. A VCS login or a Feishu ID does not identify a WeCom member. For shared P4 accounts, map the complete submitter workspace through author_mappings, or enable guess_author for unambiguous workspace matching. File-directory results replace fallback mentions and populate custom atMentions before rendering. mention_author: false disables directory matching and dynamic mobile reminders.

  • Matching order: exact scoped vcs_accounts (trigger-isolated), explicit author_mappings, then deterministic names/emails — guessing stays OFF unless the channel opts in via guess_author: true.
  • wecom_userid members render <@userid> inline; wecom_mobile members get one bounded text reminder (mobiles only work in text messages); Feishu members render typed <at> tags.
  • The whole file validates or the report ships without mentions — broken directories never fall back to @all. One directory snapshot is pinned per report, including every split part.
  • The file path is relative to the main config directory. It must remain under allowed_root (the config directory by default) after resolving .. and symlinks; an absolute path outside that root requires an explicit trusted root.
  • Names, aliases and emails from the file never enter payloads, prompts or logs beyond the typed mention id.

The wecom_app channel sends the aggregated report through a self-built application (message/send) to explicit members, departments or tags, or to one appchat group (appchat/send). Credentials live in an im.connections entry (literal secrets are sealed in database config; app_secret_env is preferred):

im:
connections:
corp-review:
kind: wecom_app
corp_id: ww_example
agent_id: 1000002
app_secret_env: AICR_WECOM_APP_SECRET
outputs:
channels:
- name: wecom-app
kind: wecom_app
connection: corp-review
target:
kind: recipients # members/departments/tags
users: [alice_zhang]
- name: wecom-group
kind: wecom_app
connection: corp-review
target:
kind: appchat # one group created by this application
chat_id: exampleChat123

Behavior notes:

  • The report is WeCom Markdown, split into UTF-8-safe parts of at most 2048 bytes; every part carries its own delivery receipt, and a delivered part is never resent. Business rejections (errcode != 0) fail the channel instead of reporting success.
  • Only the explicit token error codes 40014/42001 trigger one token refresh and one retry; timeouts keep the outcome unknown and never resend.
  • appchat targets require the group to be created by the same application and its visible scope to include the root department — appchat stays unverified when your environment forbids that scope; use recipients.
  • Message commands and review buttons for IM connections are configured separately (see Managing IM connections).

Review card button (Feishu and WeCom apps)

Section titled “Review card button (Feishu and WeCom apps)”

A feishu_app or wecom_app output channel attaches a re-review button to its report when all of the following hold:

  • Feishu: the channel’s app_id maps to a im.connections Feishu connection with event callbacks enabled and the destination is a group (receive_id_type: chat_id);
  • WeCom: the channel’s connection has callbacks enabled and the target is explicit recipients (target.kind: recipients — only callback-configured apps may send callback cards, and appchat group messages have no card type). The card is sent as one extra message after the Markdown report parts; its task_id and button key carry only the action id;
  • both platforms require an enabled command binding allowing the review command, covering the report conversation (the receiving group on Feishu, the direct conversation on WeCom) and registering the reviewed repository under repositories.

The button carries only a server-issued opaque action id (valid for 24 hours). On click the server verifies the real operator, the platform message/task identity, the conversation and the binding authorization before creating a new review request; repeated clicks on the same button return the original request id, while cards forwarded to another conversation, revoked bindings and expired actions are rejected. An action whose send acknowledgement never became durable stays pending and is never activated by a callback’s self-reported source. Channels without a callback surface (WeCom webhook, appchat, …) show no button.

Publication recovery reuses the original action id and acknowledged message; it does not issue a new button for a confirmed send. The action retains its issuance snapshot for audit until consumption or expiry; a click creates its new request under the current configuration snapshot. Without a durable click-time snapshot, the action remains unconsumed.

Receiving message commands (callback and long connection)

Section titled “Receiving message commands (callback and long connection)”

Besides sending reports, IM connections can receive @-mention message commands in groups. Three receive modes are supported today, selected per connection in im.connections:

im:
connections:
# WeCom smart robot — event-callback mode
wecom-airobot:
kind: wecom_aibot
corp_id: ww_example
callback:
enabled: true
token_env: AICR_WECOM_AIBOT_TOKEN # callback Token
encoding_aes_key_env: AICR_WECOM_AIBOT_AES # callback EncodingAESKey
# WeCom smart robot — long-connection mode (no public callback URL needed)
wecom-airobot-lc:
kind: wecom_aibot
corp_id: ww_example
aibot_id: "https://open.work.weixin.qq.com/..." # the robot's bot_id
secret_env: AICR_WECOM_AIBOT_LC_SECRET # the robot's Secret
# Feishu custom application — event-callback mode
# (platform side: "send events to the developer server")
feishu-app:
kind: feishu_app
app_id: cli_example
app_secret_env: AICR_FEISHU_APP_SECRET
tenant_key: "xxxx"
callback:
enabled: true
verification_token_env: AICR_FEISHU_VERIFY_TOKEN
encrypt_key_env: AICR_FEISHU_ENCRYPT_KEY
# Feishu custom application — long-connection mode
# (platform side: "receive events over a long connection"): no callback
# configured (or enabled: false); the server dials with app_id+app_secret
feishu-app-lc:
kind: feishu_app
app_id: cli_example
app_secret_env: AICR_FEISHU_APP_SECRET

Platform-side callback URLs follow https://<server-address>/callbacks/im/<connection-id>, for example https://aicr.example.com/callbacks/im/wecom-airobot. When you save the URL the platform sends a verification challenge and the server answers per protocol; afterwards every @-mention message is signature-verified, decrypted, persisted to the inbox, and only then processed.

Supported command grammar (the aicr prefix, sent after @-mentioning the bot):

  • aicr help — every receive mode answers immediately with the command help. The WeCom callback mode answers with an encrypted finished stream message in the callback response body (msgtype: "stream" with finish: true; a plain markdown body is ignored by the platform), the WeCom long connection replies via aibot_respond_msg, and Feishu replies through its message API.
  • Query commands (read-only, same binding authorization; lists include only repositories in the authorized binding unless it enables allow_all_repositories): aicr projects, aicr reviews [alias], aicr commits <alias> [branch] / aicr prs <alias> [branch] (recently trigger-eligible commits / PRs-MRs), aicr detail <alias> <revision> / aicr prdetail <alias> <pr-id> (run detail: status, model, input/output/cache-hit tokens, request count, cost, duration — recent records only), aicr queue (pending tasks with scheduled starts), aicr running (in-flight reviews). For registered repositories, queries match the binding’s workspace, source trigger, and repo reference. Another trigger for the same workspace and repo is outside that binding.
  • aicr chat-id / aicr review <repo> <revision> / aicr status <id> / the cancel commands — require an enabled im.command_bindings entry. Authorization checks four dimensions — actor, conversation, connection and command — and the actor matches either an exact principal ({type, id}) or a scope matcher: departments (recursive), tags (the role/user-group carrier), positions, custom fields, Feishu chat membership / departments / job titles, and any (any authenticated actor). Every matcher accepts an optional expires_at for time-boxed temporary authorization. Scope matching resolves against server-side directory snapshots (WeCom needs an enabled wecom_app connection for the corporate directory; the smart robot’s encrypted userids convert automatically). A missing directory fails that dimension closed; exact principals keep working. Bindings may enable allow_all_repositories: repo aliases then also resolve by workspace id or full repo name against the integrated projects (the ones aicr projects lists), without per-repo registration. Rejected commands echo the actor and conversation identity back to the sender (visible only inside that conversation) — that closes the group whitelist bootstrap loop: @-mention the bot in a group once, take the group id from the rejection reply, and add it to the binding’s conversations (WeCom smart-robot groups have no query API).

Cancel commands (a write operation; the binding’s commands must explicitly list cancel):

  • aicr cancel <repo> <revision> — cancels the in-flight/queued tasks of that repository matching a commit-hash prefix or an exact numeric revision.
  • aicr cancel <repo> before <duration> — cancels that repository’s tasks enqueued before now minus the duration; durations are <n><m|h|d> (minutes/hours/days), e.g. 2h, 30m, 3d. An ISO timestamp with an explicit timezone also works, e.g. 2026-09-01T00:00:00+08:00.
  • aicr cancel before <duration> — repo-unrestricted, cancels the tasks enqueued before the bound within the binding’s authorized repositories (all repositories when the binding enables allow_all_repositories).

Cancellation covers queued auto-commit batches (terminally closed, stream released), running batches (persisted as cancelled before aborting — output already published stays published), IM review requests (terminal rejected, with a notification to the requesting conversation), and leftover in-flight run rows (marked cancelled). Alias forms require the alias to be registered on the binding (or resolved via allow_all_repositories); the cancellation scope never exceeds the binding’s authorized repositories. An explicit alias always limits cancellation to that repository, even when allow_all_repositories is enabled. Active webhook and admin reviews can also be aborted through their live run registry. Cancellation prevents subsequent publication; it cannot undo delivered output. Reviews deferred outside their execution window are also removed durably.

aicr review stores the request and its configuration snapshot. The server worker validates the fixed revision and runs the review under the shared workspace concurrency limit. Git requires a full commit hash reachable from the configured repository; SVN and P4 require a positive revision number. A repeated request for the same active workspace, repository and revision reuses the existing review without consuming the quota for a new request. aicr status reveals a request only to its original actor on the original connection and conversation, while its repository remains allowed by the status binding. An interrupted review recovers per phase: a crash during analysis retries with persisted backoff (currently at most three recovery attempts by default before the request fails); a publication interrupted after the analysis completed resumes publication only from its durable checkpoint without calling the model again; a publication whose delivery outcome cannot be proven is reported as publication_unknown and is never automatically published again. Malformed publication checkpoints cannot authorize a resend. A checkpoint over 1 MiB or a failed checkpoint write stops further sends and preserves the last durable recovery state. Git commit authors come from stored VCS metadata; the chat operator is recorded separately. Terminal notifications use the requesting conversation. In WeCom long connection mode, they use the existing subscribed socket and wait for the platform send acknowledgement. A request fails when all publication operations fail or no publisher is configured; it is partial when some operations publish and others fail. Transport failures and unprovable delivery remain publication_unknown; explicit recipient rejection is a failure, and known partial delivery is partial.

Long-connection modes are initiated by the server: aicr serve dials per the connection table (auto-reconnecting on drops), needing neither a callback URL nor any callback configuration — WeCom smart robots use the official WebSocket protocol (aibot_id+secret), Feishu uses the official SDK long connection (app_id+app_secret). The two WeCom modes are separate robot entities (each with its own bot_id/credentials) and can coexist; Feishu’s callback and long-connection modes are mutually exclusive on the platform side — configure the connection to match the event-receive method chosen in the developer console.

The IM channel kinds share the common output-channel fields documented in Output channels config. The fields most relevant to IM bots:

Field Meaning
webhook_url_env Webhook channels: env var name holding the bot webhook URL
secret_env feishu_bot: env var name holding the signing secret
mention_author true to @-mention the commit author when resolvable
mention_fallback all (mention @all) or skip when the author can’t be resolved
no_problems Zero-problem policy for this channel (publish / suppress / publish_if_summary)

For routing, target-kind matching, and the zero-problem policy, see Output channels and Output channels config.

Managing IM connections and command bindings

Section titled “Managing IM connections and command bindings”

The dashboard Configuration tab includes two entity pages for the IM integrations: IM connections and IM command bindings. Connections hold the protocol identity and credentials (wecom_app, wecom_aibot or feishu_app); command bindings reference a connection and define which typed actors, conversations and commands may request reviews. Literal credentials entered in the drawer are sealed at persistence boundaries and never displayed again; deleting or renaming a connection that a binding or channel references is rejected atomically by the publish boundary.

These pages manage draft configuration: report sending and all three receive modes (WeCom smart-robot event callback / long connection, Feishu application event callback) are live — aicr help answers immediately; the review commands (review/status) only run once a command binding is enabled, and bindings stay disabled by default. See Configuration field reference for the im.* field contracts.