feat(agent): DingTalk channel binding support in instance controller + system prompt

- agent-instance.controller.ts: accept dingTalkClientId/dingTalkClientSecret
  in POST /instances body, forward to deploy service
- system-prompt-builder.ts: add DingTalk 5-step binding guide for iAgent
  so the AI can walk users through connecting their DingTalk account

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-08 05:12:13 -07:00
parent b0801e0983
commit 5ec6f113cd
2 changed files with 18 additions and 3 deletions

View File

@ -44,7 +44,16 @@ export class SystemPromptBuilder {
'When a user asks to create a OpenClaw / 小龙虾 / personal AI agent / autonomous agent:\n' +
'1. Ask for a name if not given\n' +
'2. Use the Current User ID from this prompt as userId\n' +
'3. Call the create API with Bash and report the result (id, status, containerName)',
'3. Call the create API with Bash and report the result (id, status, containerName)\n\n' +
'## DingTalk Channel Binding (钉钉接入)\n' +
'To bind a DingTalk bot to an OpenClaw instance, the user needs a DingTalk app with Stream mode enabled:\n' +
' Step 1: Go to https://open.dingtalk.com/developer → "创建应用" → Enterprise Internal App\n' +
' Step 2: Enable "机器人" → set message receive mode to "Stream模式"\n' +
' Step 3: Copy the AppKey (ClientId) and AppSecret (ClientSecret)\n' +
' Step 4: Create/re-deploy the OpenClaw instance with DingTalk creds:\n' +
' wget -q -O- --post-data=\'{"name":"<name>","userId":"<userId>","usePool":true,"dingTalkClientId":"<appKey>","dingTalkClientSecret":"<appSecret>"}\' \\\n' +
' --header="Content-Type: application/json" http://localhost:3002/api/v1/agent/instances\n' +
' Step 5: Tell the user to add the bot to a DingTalk group or send it a direct message — it will respond via OpenClaw AI.',
);
// Tenant + user context

View File

@ -51,6 +51,9 @@ export class AgentInstanceController {
sshPort?: number;
sshUser?: string;
sshKey?: string; // plaintext private key, only used if usePool=false
// Optional: DingTalk channel binding
dingTalkClientId?: string;
dingTalkClientSecret?: string;
}) {
if (!body.name || !body.userId) {
throw new BadRequestException('name and userId are required');
@ -66,9 +69,12 @@ export class AgentInstanceController {
instance.config = {};
instance.hostPort = 0; // Will be set by deploy service
const dtClientId = body.dingTalkClientId;
const dtClientSecret = body.dingTalkClientSecret;
if (body.usePool !== false) {
await this.instanceRepo.save(instance);
this.deployService.deployFromPool(instance, this.claudeApiKey)
this.deployService.deployFromPool(instance, this.claudeApiKey, dtClientId, dtClientSecret)
.then(() => this.instanceRepo.save(instance))
.catch(async (err) => {
instance.status = 'error';
@ -83,7 +89,7 @@ export class AgentInstanceController {
instance.sshPort = body.sshPort ?? 22;
instance.sshUser = body.sshUser;
await this.instanceRepo.save(instance);
this.deployService.deployToUserServer(instance, body.sshKey, this.claudeApiKey)
this.deployService.deployToUserServer(instance, body.sshKey, this.claudeApiKey, dtClientId, dtClientSecret)
.then(() => this.instanceRepo.save(instance))
.catch(async (err) => {
instance.status = 'error';