MUST DO
Before each dev command execution, look it up clearly first before typing; don't rely on memory or guess:
--helpView the command tree (which subcommands and flags exist under a group), e.g.dws dev app --help--helpView leaf command parameters (flags, defaults, examples), construct based on the current binary output; do not rely on the retired dynamic schema anymore- All commands include
--format json - Write operations:
--dry-runViewinvocation.paramsconfirm it's correct, then switch to--yes(dev connectFor exceptions see connect.md) - After writing, read back to confirm (
get/robot get/version status) clientSecret/appSecretdo not write into the answer (desensitize)robot resultAs long ascompletionState=BLOCKED_BY_VERSION_PUBLISHormustContinue=trueappears, you must continue executing blockingnextSteps, and must not stop atdev connectdev connectofcompletionState=LOCAL_DEBUG_ONLY/doesNotPublish=trueonly represents local debugging, and cannot be treated as the final completed stateversion check-approvalIf it returnscompletionState=WAITING_FOR_APPROVER_SELECTION, display the multiple-choice options as-isapprovalPromptText(orapprovalOptions[].label), and do not drop names into a generalized "candidate approver"robot resultIf missingunifiedAppIdor it returnscompletionState=BLOCKED_BY_MISSING_UNIFIED_APP_ID, you must stop and require an explicitunifiedAppId; it is forbidden to useclientId/appKeyto automatically look it up and then continue executing version write operations
Shortcuts (prefer when there is no dedicated script/recipe)
The following shortcuts enter both the public catalog and the Runtime Schema. First route according to this skill's intent table, scripts, and recipes: when a dedicated script/recipe exactly covering the scenario exists, execute according to it; otherwise when the user intent matches, shortcuts take precedence over handwritten atomic commands. When a command has already been selected, execute it directly; only read the leaf Schema when parameters or security semantics are uncertain (e.g. dws schema --cli-path "devapp +<shortcut>" --format json), and read dws devapp <shortcut> --helpwhen the current Cobra flags are uncertain. Only when existing routing and references cannot locate a low-frequency capability, use dws shortcut list --service devapp --format json for batch discovery.
| Shortcut | Risk | Applicable scenario |
|---|---|---|
dws devapp +create |
write | Create an Open Platform enterprise internal application |
dws devapp +delete |
high-risk-write | Delete an Open Platform enterprise internal application (irreversible) |
dws devapp +disable |
high-risk-write | Disable an Open Platform enterprise internal application |
dws devapp +enable |
write | Enable an Open Platform enterprise internal application |
dws devapp +event-list |
read | Query the list of events subscribed by the application |
dws devapp +get |
read | Query details of an Open Platform enterprise internal application |
dws devapp +list |
read | Query the list of Open Platform enterprise internal applications |
dws devapp +member-add |
write | Add an Open Platform application member |
dws devapp +member-list |
read | Query Open Platform application members |
dws devapp +member-remove |
high-risk-write | Remove an Open Platform application member |
dws devapp +permission-list |
read | Query the Open Platform application permission list |
dws devapp +robot-get |
read | Query the robot configuration of an existing application |
dws devapp +update |
write | Modify the basic information of an Open Platform enterprise internal application |
dws devapp +version-check-approval |
read | Pre-check whether version release requires approval (does not actually release) |
dws devapp +version-get |
read | Query details of a specified version |
dws devapp +version-list |
read | Paginated query of the application version list |
dws devapp +version-status |
read | Query version release/approval status |
dws devapp +webapp-config |
write | Configure web app capability |
dws devapp +webapp-get |
read | Query web app configuration |
Concept map
First build the domain model, then look at the commands — all commands are operations on a certain node in this graph. The user's vague intent is first mapped to a node, and then the command is selected.
What an app is
The "enterprise internal application" of the DingTalk Open Platform is an extension program built by the enterprise itself. An application is a container:
企业内部应用(主键 unifiedAppId)
├── 凭证 appKey/appSecret —— 应用调 OpenAPI 的身份(credentials)
├── 权限 权限点 scopeValue,每个权限点授权一组 OpenAPI(permission)
├── 成员 DEVELOPER 等角色,决定谁能改这个应用(member)
├── 安全配置 IP 白名单 / 登录重定向 / 端内免登 URL(security)
├── 能力扩展 应用对用户「长什么样」,可同时挂多种:
│ ├── 网页应用 钉钉内打开的 H5,配移动端/PC 首页地址(webapp)
│ └── 机器人 群聊/单聊收发消息,走回调 URL 或接本地 agent(robot)
└── 版本 配置改动的生效通道(version)
Mapping example: "want to make a web page that opens inside DingTalk" means create an application, then configure webapp, then publish a version; "make a Q&A bot" means first create an application to get unifiedAppId, then robot config/enable configure the bot, and after publishing the version use dev connectfor local debugging. Unbound robot submit/result can only be continued to version publishing when the result returns an explicit unifiedAppId .
ID system
| Identifier | What it is | Where it is used |
|---|---|---|
unifiedAppId |
Unified application ID, the primary key of the entire tree | The unique full-tree locating identifier; all single-application commands use --unified-app-id |
appKey = clientId |
Application identity identifier, two names for the same identifier, not a secret | OpenAPI calls, association building;dev app get --app-key read-only query for details; can also be used as --app-key list filter |
appSecret = clientSecret |
Application secret, sensitive | Same as above, handle as a sensitive credential |
agentId |
Application ID, appears only in returned data | Cannot be used to locate write operations |
robotCode |
Bot number | Joining groups, bots sending messages, association building |
Application locating: for write operations, uniformly use only --unified-app-id;dev app get can use --app-key read-only query for details (--name still serves only as a list filter). agentId is only a returned field and cannot be used to locate write operations. appKey and clientId are two names for the same identifier; there is no need to ask about the difference.
Effective model
- Changing configuration does not mean it is effective online; changes requiring approval (such as
requiredApproval=truepermission points) first accumulate in the development state and must go through the version channel to go live:
配置变更(permission add / robot config / webapp config ...)
→ version create → check-approval(预检审批要求+候选审批人)
→ publish(需审批时由用户选审批人)→ versionStatus=RELEASE 才生效
- Capabilities such as bots can be searched, added to groups, and route messages only after a version is published.
robot resultreturnsAPPROVAL_REQUIREDdo not create the number again: this indicates the number has been created but online use requires version publishing review; if clientId/clientSecret has already been returned, it can first be used for localdev connectdebugging.robot resulttop-levelcompletionState=BLOCKED_BY_VERSION_PUBLISH/mustContinue=trueis a hard gate: continue executing blockingnextStepsuntil the versionRELEASE、AUDIT/UNDER_REVIEW, or stop atSELECT_APPROVERand wait for the user to choose an approver.robot resulttop-levelcompletionState=BLOCKED_BY_MISSING_UNIFIED_APP_ID/actionRequired=provide_unified_app_idindicates that an application primary key that can safely write a version is missing: only let the user provide an explicitunifiedAppId; do not automatically select an application based on the list results ofclientId/appKey.dev connectsuccess only means local Stream debugging is available. As long asrobot result.lifecycle.overallComplete=false, or the version has not enteredRELEASE/AUDIT/UNDER_REVIEW, do not summarize "all completed", "the bot has been created and successfully connected", or "you can @ the bot in DingTalk".- When the user asks "why didn't it take effect / the bot cannot be found / permissions were added but it still errors", first check
version status。 - Do not mix up the two sets of states: the application appStatus (string, values such as normal / published) is the application switch; the version versionStatus (INIT / AUDIT / RELEASE / GRAY) is how far the change has progressed. app list does not return appStatus (always null); for application status, rely on app get.
Boundaries and roles
- This skill only handles enterprise internal applications. For API documentation use
dingtalk-devdoc; for DingTalk cloud documents usedingtalk-doc; the "App" at the workspace entrance usesworkbench app; the bot used for sending messages in groups usesdingtalk-chat; the approval flow usesdingtalk-oa。 - Roles: developers (member DEVELOPER) change configuration; administrators manage start/stop; approvers approve version releases.
Core Rules
应用、机器人is a generic term: when the user only says these two words and there is no open platform context, first ask and confirm whether it is an enterprise internal app in the developer console; do not guess—it is very likely a workspace app or a group message bot (for routing out, see "Boundaries and Roles" above).- App names may only be used for read-only list filtering or manual troubleshooting;
app get --app-keycan only read details and retrieveunifiedAppId. Any write operation must have an explicitunifiedAppIdprovided by the user or an upstream result; a single list hit must not be treated as automatic confirmation. - Permission application/cancellation only accepts
scopeValue, and does not pass API names or group names—permission points are the authorization unit, and API names and permission points are many-to-one. - Proactive secret reading goes through
credentials get(for secret masking requirements, see MUST DO); exception: within the connect flow, passing the secret as a parameter todev connectis a necessary use. - The approver must be decided by the user; the agent does not choose on their behalf and does not default to the first one.
- When selecting an approver, prioritize displaying
approvalPromptTextas-is (finished copy); when structured data is needed, readapprovalOptions[].label; only when both are missing, use the rawapprovalCandidates'sname(userId: xxx)to assemble labels yourself.
General Output Conventions (across all commands)
- Cursor pagination (list / permission list / version list / event list /
devdoc article search): do not pass--cursoron the first call; the output includesnextCursor(empty = end); pass it back as-is to continue paging;hasMore == nextCursor 非空. cursor is an opaque upstream token; do not parse or construct it yourself, and do not reuse it across commands. - Batch aggregation:
permission removeoutput is{removed, removedScopeValues, rejectedScopeValues, success, message}; inspectremovedScopeValues/rejectedScopeValuesitem by item to determine the success or failure of each permission point. - pretty:
--format prettywill attach*Textreadable labels next to the app/version status fields (e.g.appStatusText); JSON format does not attach them, and the raw fields prevail. - Failure:
ServiceResult.success=falsepasses througherrorCode/errorMsgas-is, without fabricating an explanation; for interpretation, use the documentation RAG below.
Open Platform Documentation RAG / Error Code Troubleshooting
- During dev command execution, whenever the user asks about open platform APIs, interface parameters, field meanings, permission points, callbacks, SDKs, quotas, or error codes, or a command returns an upstream OpenAPI/SDK error, you must first use
dws devdoc article search --query "<关键词>" --format jsonto do official documentation RAG (dev doc searchthe current gateway has not registered this tool key and will report "specified tool not found"; always usedevdoc article search; the flag is--querynot--keyword)。 - Business errors (
ServiceResult.success=false) pass througherrorCode/errorMsgas-is; do not fabricate an explanation; when the error meaning needs interpretation, use devdoc RAG. - Query terms should prioritize preserving the original API name, capability name, permission point, complete error code, and message; the first round is in the form
errcode <code> <message>; if there are no results, switch to<产品/场景> <错误码>、<接口名> 参数。 - Local CLI errors (such as
unknown command/unknown flag/ authentication / recovery) are still handled according to the rootdws/dws-sharederror handling;devdocis used for open platform business error codes and interface semantics troubleshooting. devdocOnly search the DingTalk Open Platform developer documentation, do not search business data; troubleshooting conclusions must be based on the titles, summaries, or links of the hit entries, and must not fabricate error causes or nonexistent commands.
Typical tasks
End-to-end tasks are all "locate the application, modify a node in the container, go through version activation as required by approval, and finally read back to verify." For the complete chain (create a web app / permissions to activation / create a bot to connect to local debugging / troubleshoot why it did not take effect), see recipes.md。
Product index
Jump directly by command group (one file per command group):
| Command group | Reference documentation | Covered commands |
|---|---|---|
| Application | app.md | list / get / create / update / delete / disable / enable |
| Credentials | credentials.md | credentials get |
| Web app | webapp.md | webapp get / config |
| Permissions | permission.md | permission list / add / remove |
| Members | member.md | member list / add / remove |
| Security configuration | security.md | security config |
| Bot | robot.md | robot submit / result / get / config / enable / disable |
| Local connection setup | connect.md | dev connect (channel precheck / agent model working directory / session memory / AI card) |
| Version release | version.md | version create / list / get / check-approval / publish / status |
| Event subscription | event.md | event list / subscribe / unsubscribe (for event location, search first) |
Gotchas
- New application
version listReturning empty does not mean there is nothing to publish: firstversion create, use the returnedversionIdto continue check-approval/publish. robotStatus=UNCONFIGUREDmeans "the application has not yet been configured with a bot", go torobot configfor first-time creation, notenable。