wecom

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
We drive the WeCom server-side API (
https://qyapi.weixin.qq.com
) with
curl + jq
as a self-built app (自建应用).
Setup: see WeCom authentication for how to create the self-built app, collect CorpID / Secret / AgentId, and grant it the contacts / docs / calendar / meeting permissions. The skill reads
WECOM_CORP_ID
,
WECOM_CORP_SECRET
and
WECOM_AGENT_ID
from the environment; on AceDataCloud they are injected automatically by the 企业微信 connector.
WeCom uses a two-step token flow (identical in shape to the WeChat MP API):
  1. Exchange
    CorpID + Secret
    for an
    access_token
    (TTL 7200s).
  2. Pass that
    access_token
    as a query string parameter on every other call.
Never log or echo
$WECOM_CORP_SECRET
— treat it like a password.
Responses are JSON returned with HTTP 200;
errcode == 0
means success. On any non-zero
errcode
, show the original
errmsg
to the user verbatim (see the error table in the setup doc).
我们以自建应用的身份,通过
curl + jq
调用企业微信服务端API (
https://qyapi.weixin.qq.com
)。
配置说明: 请查看企业微信认证了解如何创建自建应用、收集CorpID / Secret / AgentId,并为其授予通讯录/文档/日历/会议权限。本功能从环境变量中读取
WECOM_CORP_ID
WECOM_CORP_SECRET
WECOM_AGENT_ID
;在AceDataCloud平台上,这些变量会由企业微信连接器自动注入。
企业微信采用两步式令牌流程(与微信公众号API流程一致):
  1. 使用
    CorpID + Secret
    换取
    access_token
    (有效期7200秒)。
  2. 在后续所有调用中,将该
    access_token
    作为查询字符串参数传递。
切勿记录或输出
$WECOM_CORP_SECRET
——请将其视为密码妥善保管。
接口响应为JSON格式,返回HTTP 200状态码;
errcode == 0
表示调用成功。若
errcode
不为0,请将原始
errmsg
直接展示给用户(详见配置文档中的错误表)。

Recipes

操作示例

Step 0 — get an access_token (do this first, cache the result)

步骤0 — 获取access_token(需先执行此步骤并缓存结果)

Every recipe below assumes
$AT
holds a valid token from this step.
sh
undefined
以下所有操作示例均假设
$AT
存储了通过此步骤获取的有效令牌。
sh
undefined

Fail loudly if credentials are missing/blank. WECOM_AGENT_ID must be a plain

Fail loudly if credentials are missing/blank. WECOM_AGENT_ID must be a plain

integer because message/meeting recipes pass it to jq via --argjson (numeric JSON).

integer because message/meeting recipes pass it to jq via --argjson (numeric JSON).

: "${WECOM_CORP_ID:?WECOM_CORP_ID not set}" "${WECOM_CORP_SECRET:?WECOM_CORP_SECRET not set}" case "${WECOM_AGENT_ID:?WECOM_AGENT_ID not set}" in [!0-9]|"") echo "WECOM_AGENT_ID must be an integer" >&2; exit 1;; esac
: "${WECOM_CORP_ID:?WECOM_CORP_ID not set}" "${WECOM_CORP_SECRET:?WECOM_CORP_SECRET not set}" case "${WECOM_AGENT_ID:?WECOM_AGENT_ID not set}" in [!0-9]|"") echo "WECOM_AGENT_ID must be an integer" >&2; exit 1;; esac

Cache to $TMPDIR so subsequent calls in the same session reuse it (WeCom

Cache to $TMPDIR so subsequent calls in the same session reuse it (WeCom

rate-limits gettoken). Refresh 5 minutes early to avoid edge-of-window failures.

rate-limits gettoken). Refresh 5 minutes early to avoid edge-of-window failures.

TOKEN_CACHE="${TMPDIR:-/tmp}/wecom-token-${WECOM_CORP_ID}-${WECOM_AGENT_ID}.json" NOW=$(date +%s) if [ -f "$TOKEN_CACHE" ] && [ "$(jq -r '.exp_at // 0' "$TOKEN_CACHE")" -gt "$((NOW + 300))" ]; then AT=$(jq -r '.access_token' "$TOKEN_CACHE") else RESP=$(curl -sS "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${WECOM_CORP_ID}&corpsecret=${WECOM_CORP_SECRET}") AT=$(echo "$RESP" | jq -r 'if .errcode == 0 then .access_token else empty end') if [ -z "$AT" ]; then echo "Failed to fetch access_token: $RESP" >&2 exit 1 fi EXPIRES=$(echo "$RESP" | jq -r '.expires_in // 7200') echo "$RESP" | jq --argjson now "$NOW" --argjson ttl "$EXPIRES"
'{access_token, exp_at: ($now + $ttl)}' > "$TOKEN_CACHE" chmod 600 "$TOKEN_CACHE" fi

A tiny helper keeps the recipes short — GET with the token appended, erroring on non-zero `errcode`:

```sh
wc_get()  { curl -sS "https://qyapi.weixin.qq.com/cgi-bin/$1&access_token=${AT}" \
              | jq 'if .errcode == 0 then . else error("WeCom \(.errcode): \(.errmsg)") end'; }
wc_post() { curl -sS -X POST "https://qyapi.weixin.qq.com/cgi-bin/$1?access_token=${AT}" \
              -H 'Content-Type: application/json' -d "$2" \
              | jq 'if .errcode == 0 then . else error("WeCom \(.errcode): \(.errmsg)") end'; }
TOKEN_CACHE="${TMPDIR:-/tmp}/wecom-token-${WECOM_CORP_ID}-${WECOM_AGENT_ID}.json" NOW=$(date +%s) if [ -f "$TOKEN_CACHE" ] && [ "$(jq -r '.exp_at // 0' "$TOKEN_CACHE")" -gt "$((NOW + 300))" ]; then AT=$(jq -r '.access_token' "$TOKEN_CACHE") else RESP=$(curl -sS "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${WECOM_CORP_ID}&corpsecret=${WECOM_CORP_SECRET}") AT=$(echo "$RESP" | jq -r 'if .errcode == 0 then .access_token else empty end') if [ -z "$AT" ]; then echo "Failed to fetch access_token: $RESP" >&2 exit 1 fi EXPIRES=$(echo "$RESP" | jq -r '.expires_in // 7200') echo "$RESP" | jq --argjson now "$NOW" --argjson ttl "$EXPIRES"
'{access_token, exp_at: ($now + $ttl)}' > "$TOKEN_CACHE" chmod 600 "$TOKEN_CACHE" fi

我们编写了一个小型辅助函数来简化操作示例——自动附加令牌的GET请求,当`errcode`不为0时抛出错误:

```sh
wc_get()  { curl -sS "https://qyapi.weixin.qq.com/cgi-bin/$1&access_token=${AT}" \
              | jq 'if .errcode == 0 then . else error("WeCom \(.errcode): \(.errmsg)") end'; }
wc_post() { curl -sS -X POST "https://qyapi.weixin.qq.com/cgi-bin/$1?access_token=${AT}" \
              -H 'Content-Type: application/json' -d "$2" \
              | jq 'if .errcode == 0 then . else error("WeCom \(.errcode): \(.errmsg)") end'; }

通讯录 Contacts (read)

通讯录(读取)

Reading real names / mobiles requires the app to have 通讯录读取 privilege; otherwise names come back masked. Members outside the app's 可见范围 return
errcode 60011
/
81013
.
List the department tree (root department id is
1
):
sh
wc_get "department/list?id=1" | jq '[.department[] | {id, name, parentid}]'
Preferred enumeration —
user/list_id
(cursor).
This is the robust way to list members: it works for a self-built app with only its own Secret.
user/simplelist
/
user/list
still work within the app's 可见范围, but WeCom has been tightening those (the 2022‑08‑15 change blocks newly‑added 通讯录同步 IPs from calling them), so lead with
user/list_id
and fall back to
simplelist
only if you need names in one shot.
sh
wc_post "user/list_id" '{"cursor":"","limit":10000}' \
  | jq '{next_cursor, userids: [.dept_user[] | .userid] | unique}'
Get one member's full profile — this is how you resolve a name → userid for messaging:
sh
wc_get "user/get?userid=USERID" \
  | jq '{userid, name, department, position, mobile, email, status}'
List members of a department in one call (convenience; needs 通讯录 view on that department — if it returns
60011
, use
user/list_id
+
user/get
above instead):
sh
wc_get "user/simplelist?department_id=1&fetch_child=1" \
  | jq '[.userlist[] | {userid, name, department}]'
Search by name — robust path (enumerate ids, then read each profile and filter):
sh
for uid in $(wc_post "user/list_id" '{"cursor":"","limit":10000}' | jq -r '.dept_user[].userid' | sort -u); do
  wc_get "user/get?userid=${uid}" | jq -c '{userid, name}'
done | jq -s --arg q "张三" '[.[] | select(.name | contains($q))]'
Shortcut when
simplelist
is available to the app:
wc_get "user/simplelist?department_id=1&fetch_child=1" | jq --arg q "张三" '[.userlist[] | select(.name | contains($q)) | {userid, name}]'
.
读取真实姓名/手机号需要应用拥有通讯录读取权限;否则返回的姓名会被掩码处理。应用可见范围外的成员会返回
errcode 60011
/
81013
获取部门树(根部门ID为
1
):
sh
wc_get "department/list?id=1" | jq '[.department[] | {id, name, parentid}]'
推荐枚举方式 —
user/list_id
(游标分页)
。这是列举成员的可靠方式:适用于仅拥有自身Secret的自建应用。
user/simplelist
/
user/list
仍可在应用可见范围内使用,但企业微信已收紧相关限制(2022-08-15的更新阻止新增的通讯录同步IP调用这些接口),因此优先使用
user/list_id
,仅当需要一次性获取姓名时才回退到
simplelist
sh
wc_post "user/list_id" '{"cursor":"","limit":10000}' \
  | jq '{next_cursor, userids: [.dept_user[] | .userid] | unique}'
获取单个成员的完整信息——这是将姓名转换为userid以发送消息的方法:
sh
wc_get "user/get?userid=USERID" \
  | jq '{userid, name, department, position, mobile, email, status}'
一次性获取部门成员列表(便捷方式;需要应用拥有该部门的通讯录查看权限——若返回
60011
,请改用上述
user/list_id
+
user/get
组合):
sh
wc_get "user/simplelist?department_id=1&fetch_child=1" \
  | jq '[.userlist[] | {userid, name, department}]'
按姓名搜索(可靠方式:枚举ID,然后读取每个成员信息并过滤):
sh
for uid in $(wc_post "user/list_id" '{"cursor":"","limit":10000}' | jq -r '.dept_user[].userid' | sort -u); do
  wc_get "user/get?userid=${uid}" | jq -c '{userid, name}'
done | jq -s --arg q "张三" '[.[] | select(.name | contains($q))]'
当应用可使用
simplelist
时的快捷方式:
wc_get "user/simplelist?department_id=1&fetch_child=1" | jq --arg q "张三" '[.userlist[] | select(.name | contains($q)) | {userid, name}]'

应用消息 App messages (send) — GATED

应用消息(发送)——需确认

message/send
pushes a notification from your app to members.
agentid
is required and comes from
$WECOM_AGENT_ID
.
touser
is a
|
-joined list of userids (use
@all
for everyone in scope);
toparty
/
totag
target departments / tags.
Sending fans out to real people. Always show the exact recipients + content and get explicit user confirmation before running
message/send
/
appchat/send
, even if the instruction says "just send it".
Send a text message to one or more members:
sh
wc_post "message/send" "$(jq -nc --arg to "USERID1|USERID2" --argjson agent "${WECOM_AGENT_ID}" \
  --arg content "构建已通过,请查看。" \
  '{touser:$to, msgtype:"text", agentid:$agent, text:{content:$content}, safe:0}')" \
  | jq '{msgid, invaliduser}'
Send a Markdown card (richer formatting, members only):
sh
wc_post "message/send" "$(jq -nc --arg to "@all" --argjson agent "${WECOM_AGENT_ID}" \
  --arg md "**发布通知**\n>版本:v1.2.0\n>状态:<font color=\"info\">成功</font>" \
  '{touser:$to, msgtype:"markdown", agentid:$agent, markdown:{content:$md}}')" \
  | jq '{msgid}'
Send a clickable text-card:
sh
wc_post "message/send" "$(jq -nc --arg to "USERID1" --argjson agent "${WECOM_AGENT_ID}" \
  '{touser:$to, msgtype:"textcard", agentid:$agent,
    textcard:{title:"周报已生成", description:"点击查看本周汇总", url:"https://example.com/report", btntxt:"详情"}}')" \
  | jq '{msgid}'
message/send
接口用于从应用向成员推送通知。
agentid
为必填项,取值来自
$WECOM_AGENT_ID
touser
为用
|
分隔的userid列表(使用
@all
可发送给可见范围内的所有成员);
toparty
/
totag
用于指定目标部门/标签。
消息会发送给真实用户。在执行
message/send
/
appchat/send
前,务必展示确切的收件人+内容并获得用户明确确认
,即使用户指令为“直接发送”。
向一位或多位成员发送文本消息:
sh
wc_post "message/send" "$(jq -nc --arg to "USERID1|USERID2" --argjson agent "${WECOM_AGENT_ID}" \
  --arg content "构建已通过,请查看。" \
  '{touser:$to, msgtype:"text", agentid:$agent, text:{content:$content}, safe:0}')" \
  | jq '{msgid, invaliduser}'
发送Markdown卡片(格式更丰富,仅支持成员接收):
sh
wc_post "message/send" "$(jq -nc --arg to "@all" --argjson agent "${WECOM_AGENT_ID}" \
  --arg md "**发布通知**\n>版本:v1.2.0\n>状态:<font color=\"info\">成功</font>" \
  '{touser:$to, msgtype:"markdown", agentid:$agent, markdown:{content:$md}}')" \
  | jq '{msgid}'
发送可点击的文本卡片:
sh
wc_post "message/send" "$(jq -nc --arg to "USERID1" --argjson agent "${WECOM_AGENT_ID}" \
  '{touser:$to, msgtype:"textcard", agentid:$agent,
    textcard:{title:"周报已生成", description:"点击查看本周汇总", url:"https://example.com/report", btntxt:"详情"}}')" \
  | jq '{msgid}'

应用群聊 App group chat

应用群聊

Create a group the app owns, then push messages into it.
chatid
is a custom id you choose (reuse it later).
sh
undefined
创建应用所属的群聊,然后向群内推送消息。
chatid
为自定义ID(后续可重复使用)。
sh
undefined

Create (owner + members are userids). Omit chatid to let WeCom assign one.

创建群聊(群主和成员均为userid)。省略chatid则由企业微信自动分配。

wc_post "appchat/create" '{"name":"项目组","owner":"USERID1","userlist":["USERID1","USERID2","USERID3"],"chatid":"proj_alpha"}'
| jq '{chatid}'
wc_post "appchat/create" '{"name":"项目组","owner":"USERID1","userlist":["USERID1","USERID2","USERID3"],"chatid":"proj_alpha"}'
| jq '{chatid}'

Send into it (same GATED confirmation rule as app messages).

向群内发送消息(与应用消息遵循相同的确认规则)。

wc_post "appchat/send" '{"chatid":"proj_alpha","msgtype":"text","text":{"content":"今晚 8 点线上同步。"}}'
| jq '{errcode, errmsg}'
wc_post "appchat/send" '{"chatid":"proj_alpha","msgtype":"text","text":{"content":"今晚 8 点线上同步。"}}'
| jq '{errcode, errmsg}'

Inspect a group the app created.

查看应用创建的群聊信息。

wc_get "appchat/get?chatid=proj_alpha" | jq '.chat_info | {name, owner, userlist}'
undefined
wc_get "appchat/get?chatid=proj_alpha" | jq '.chat_info | {name, owner, userlist}'
undefined

企业微信文档 WeDoc (docs & smart sheets)

企业微信文档(文档与智能表格)

Requires the app's 文档 (WeDoc) permission.
doc_type
:
3
= 文档 (document),
4
= 表格 (spreadsheet),
10
= 智能表格 (smart sheet).
Create a document and get its edit URL:
sh
wc_post "wedoc/create_doc" "$(jq -nc --arg name "项目周报 2026-07" \
  '{doc_type:3, doc_name:$name}')" \
  | jq '{docid, url}'
Get a shareable link for an existing doc:
sh
wc_post "wedoc/doc_share" '{"docid":"DOCID"}' | jq '{share_url: .share_url}'
Read a document's structured content. WeCom returns a
document
object (keyed by
document_id
, not
doc_id
) whose body is a tree of typed blocks, not Markdown — inspect the real shape before relying on inner field names:
sh
wc_post "wedoc/document/get" '{"docid":"DOCID"}' \
  | jq '{document_id: .document.document_id, top_level_keys: (.document | keys)}'
Smart-sheet (智能表格) sub-tables, fields and records use the
wedoc/smartsheet/*
endpoints (
get_sheet
,
get_fields
,
get_records
,
add_records
, …) — same
wc_post
pattern, keyed by
docid
+
sheet_id
. Reach for them when the user asks to read/write rows of a 智能表格.
需要应用拥有**文档(WeDoc)**权限。
doc_type
取值:
3
= 文档,
4
= 表格,
10
= 智能表格。
创建文档并获取编辑链接:
sh
wc_post "wedoc/create_doc" "$(jq -nc --arg name "项目周报 2026-07" \
  '{doc_type:3, doc_name:$name}')" \
  | jq '{docid, url}'
获取现有文档的可分享链接:
sh
wc_post "wedoc/doc_share" '{"docid":"DOCID"}' | jq '{share_url: .share_url}'
读取文档的结构化内容。企业微信返回一个以
document_id
(而非
doc_id
)为键的
document
对象,其主体为类型化块组成的树结构,并非Markdown格式——在依赖内部字段名称前,请先查看实际返回结构:
sh
wc_post "wedoc/document/get" '{"docid":"DOCID"}' \
  | jq '{document_id: .document.document_id, top_level_keys: (.document | keys)}'
智能表格的子表格、字段和记录需使用
wedoc/smartsheet/*
系列接口(
get_sheet
get_fields
get_records
add_records
等)——遵循相同的
wc_post
调用模式,以
docid
+
sheet_id
为标识。当用户需要读取/写入智能表格行数据时,请使用这些接口。

日程 Schedule (日程)

日程

Requires the app's 日历/日程 permission. Times are epoch seconds; convert with GNU
date
:
sh
START=$(date -d "2026-07-10 15:00" +%s); END=$(date -d "2026-07-10 16:00" +%s)
Create a schedule (organizer + attendees are userids):
sh
wc_post "oa/schedule/add" "$(jq -nc --arg org "USERID1" --argjson s "$START" --argjson e "$END" \
  '{schedule:{organizer:$org, start_time:$s, end_time:$e, summary:"项目评审",
    description:"评审 v1.2 需求", location:"会议室 A",
    attendees:[{userid:"USERID2"},{userid:"USERID3"}],
    reminders:{is_remind:1, remind_before_event_secs:900}}}')" \
  | jq '{schedule_id}'
Read schedules by id, and cancel one:
sh
wc_post "oa/schedule/get" '{"schedule_id_list":["SCHEDULE_ID"]}' \
  | jq '[.schedule_list[] | {schedule_id, summary, start_time, end_time, organizer}]'

wc_post "oa/schedule/del" '{"schedule_id":"SCHEDULE_ID"}' | jq '{errcode, errmsg}'
To list a member's upcoming schedules you need their calendar id (
cal_id
) and
oa/schedule/get_by_calendar
— create/query calendars via the
oa/calendar/*
endpoints first.
需要应用拥有日历/日程权限。时间采用**时间戳(秒)**格式;可使用GNU
date
工具转换:
sh
START=$(date -d "2026-07-10 15:00" +%s); END=$(date -d "2026-07-10 16:00" +%s)
创建日程(组织者和参会者均为userid):
sh
wc_post "oa/schedule/add" "$(jq -nc --arg org "USERID1" --argjson s "$START" --argjson e "$END" \
  '{schedule:{organizer:$org, start_time:$s, end_time:$e, summary:"项目评审",
    description:"评审 v1.2 需求", location:"会议室 A",
    attendees:[{userid:"USERID2"},{userid:"USERID3"}],
    reminders:{is_remind:1, remind_before_event_secs:900}}}')" \
  | jq '{schedule_id}'
按ID读取日程,以及取消日程:
sh
wc_post "oa/schedule/get" '{"schedule_id_list":["SCHEDULE_ID"]}' \
  | jq '[.schedule_list[] | {schedule_id, summary, start_time, end_time, organizer}]'

wc_post "oa/schedule/del" '{"schedule_id":"SCHEDULE_ID"}' | jq '{errcode, errmsg}'
若要列举成员的即将到来的日程,需先获取其日历ID(
cal_id
)并调用
oa/schedule/get_by_calendar
接口——需先通过
oa/calendar/*
系列接口创建/查询日历。

会议 Meeting (会议)

会议

Requires the app's 会议 permission.
meeting_start
is epoch seconds,
meeting_duration
is seconds.
Create a scheduled meeting:
sh
wc_post "meeting/create" "$(jq -nc --arg admin "USERID1" --argjson start "$(date -d '2026-07-11 10:00' +%s)" \
  '{admin_userid:$admin, title:"周例会", meeting_start:$start, meeting_duration:3600,
    description:"同步本周进展", invitees:{userid:["USERID2","USERID3"]}}')" \
  | jq '{meetingid}'
List a member's meetings, read details, and cancel (
get_user_meetingid
is a POST with a cursor body, mirroring WeCom's other
get_user_*_id
list endpoints):
sh
wc_post "meeting/get_user_meetingid" '{"userid":"USERID1","cursor":"","limit":100}' \
  | jq '{meetingid_list, next_cursor}'

wc_post "meeting/get_info" '{"meetingid":"MEETINGID"}' \
  | jq '.meeting_info | {title, meeting_start, meeting_duration, state}'

wc_post "meeting/cancel" '{"meetingid":"MEETINGID"}' | jq '{errcode, errmsg}'
需要应用拥有会议权限。
meeting_start
为时间戳(秒),
meeting_duration
为会议时长(秒)。
创建预约会议:
sh
wc_post "meeting/create" "$(jq -nc --arg admin "USERID1" --argjson start "$(date -d '2026-07-11 10:00' +%s)" \
  '{admin_userid:$admin, title:"周例会", meeting_start:$start, meeting_duration:3600,
    description:"同步本周进展", invitees:{userid:["USERID2","USERID3"]}}')" \
  | jq '{meetingid}'
列举成员的会议、读取会议详情,以及取消会议(
get_user_meetingid
POST接口,需传入游标参数,与企业微信其他
get_user_*_id
列举接口逻辑一致):
sh
wc_post "meeting/get_user_meetingid" '{"userid":"USERID1","cursor":"","limit":100}' \
  | jq '{meetingid_list, next_cursor}'

wc_post "meeting/get_info" '{"meetingid":"MEETINGID"}' \
  | jq '.meeting_info | {title, meeting_start, meeting_duration, state}'

wc_post "meeting/cancel" '{"meetingid":"MEETINGID"}' | jq '{errcode, errmsg}'

Safety rules

安全规则

  • Never print
    $WECOM_CORP_SECRET
    .
    It is equivalent to full app access.
  • Confirm before anything outward-facing
    message/send
    ,
    appchat/send
    ,
    oa/schedule/add
    and
    meeting/create
    all notify real colleagues. Show the exact recipients / attendees and the content, get explicit approval, then run the call. Never infer consent from vague wording.
  • Messaging / schedules / meetings act on userids, not display names — resolve a name to a userid with the contact recipes first, and confirm the person if the name is ambiguous.
  • On
    errcode 48002
    (API forbidden) or
    60011
    /
    301002
    (no privilege), the app is missing a permission or the target is outside its 可见范围 — tell the user which capability to grant rather than retrying blindly.
  • 切勿输出
    $WECOM_CORP_SECRET
    。它等同于应用的完整访问权限。
  • 所有对外操作前需确认——
    message/send
    appchat/send
    oa/schedule/add
    meeting/create
    都会通知真实同事。请展示确切的收件人/参会者及内容,获得明确批准后再执行调用。切勿从模糊表述中推断用户同意。
  • 消息/日程/会议操作基于userid而非显示名称——请先通过通讯录操作将姓名转换为userid,若姓名存在歧义,请确认目标人员。
  • 若出现
    errcode 48002
    (API被禁止)或
    60011
    /
    301002
    (无权限),说明应用缺少对应权限或目标对象在可见范围外——请告知用户需要授予的权限,而非盲目重试。
##</think_never_used_51bce0c785ca2f68081bfa7d91973934>暂不支持的功能
  • 读取 inbound chat history(会话内容存档 / msgaudit)——这是一项独立的付费功能,需要专用Secret、RSA密钥和原生企业微信金融SDK;无法在此沙箱环境中运行。本功能仅能发送消息,无法读取成员的私人会话。
  • 通用待办(todo)增删改查——企业微信开放API未向自建应用提供此功能;若需时间绑定的提醒,请使用日程功能替代。

Not supported here

  • Reading inbound chat history (会话内容存档 / msgaudit) — a separate paid capability needing a dedicated Secret, an RSA key and the native WeCom Finance SDK; it can't run in this sandbox. The skill sends messages but can't read members' private conversations.
  • A generic todo (待办) CRUD — WeCom's open API exposes none for self-built apps; use schedules (日程) for time-bound reminders instead.