Skip to content

Commit 7061a3b

Browse files
committed
feat:新增Graph API 调用,更新npm包名
1 parent 4d4a2de commit 7061a3b

File tree

6 files changed

+147
-41
lines changed

6 files changed

+147
-41
lines changed

README.md

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
# dingtalk-stream-sdk-nodejs
1+
# dingtalk-stream
22
Nodejs SDK for DingTalk Stream Mode API, Compared with the webhook mode, it is easier to access the DingTalk chatbot
33
钉钉支持 Stream 模式接入事件推送、机器人收消息以及卡片回调,该 SDK 实现了 Stream 模式。相比 Webhook 模式,Stream 模式可以更简单的接入各类事件和回调。
44

55
## 快速开始
6+
npm ii
7+
npm start
68

79
### 准备工作
810

@@ -41,21 +43,21 @@ b、在example/config.json里配置应用信息。
4143

4244
c、启动测试case
4345
```Shell
44-
cd dingtalk-stream-sdk-nodejs
46+
cd dingtalk-stream
4547
yarn
4648
npm run build
4749
npm start
4850
```
4951

50-
4、在项目中引用sdk,安装 dingtalk-stream-sdk-nodejs
52+
4、在项目中引用sdk,安装 dingtalk-stream
5153

5254
```Shell
53-
npm i dingtalk-stream-sdk-nodejs
55+
npm i dingtalk-stream
5456
```
5557

5658
代码中使用
5759
```javascript
58-
const DWClient = require("dingtalk-stream-sdk-nodejs");
60+
const DWClient = require("dingtalk-stream");
5961
const config = require("./config.json");
6062

6163
const client = new DWClient({
@@ -69,6 +71,32 @@ client.registerCallbackListener('/v1.0/im/bot/messages/get', async (res) => {
6971
const {messageId} = res.headers;
7072
const { text, senderStaffId, sessionWebhook } = JSON.parse(res.data);
7173
})
74+
.registerCallbackListener(
75+
'/v1.0/graph/api/invoke',
76+
async (res: DWClientDownStream) => {
77+
// 注册AI插件回调事件
78+
console.log("收到ai消息");
79+
const { messageId } = res.headers;
80+
81+
// 添加业务逻辑
82+
console.log(res);
83+
console.log(JSON.parse(res.data));
84+
85+
// 通过Stream返回数据
86+
client.sendGraphAPIResponse(messageId, {
87+
response: {
88+
statusLine: {
89+
code: 200,
90+
reasonPhrase: "OK",
91+
},
92+
headers: {},
93+
body: JSON.stringify({
94+
text: "你好",
95+
}),
96+
},
97+
});
98+
}
99+
)
72100
.connect();
73101
```
74102

@@ -77,6 +105,9 @@ client.registerCallbackListener('/v1.0/im/bot/messages/get', async (res) => {
77105
进入钉钉开发者后台,选择企业内部应用,在应用管理的左侧导航中,选择“事件与回调”。
78106
“订阅管理”中,“推送方式”选项中,选择 “Stream 模式”,并保存
79107

108+
### AI 应用 - 技能插件,Graph API 类型插件使用 (可选)
109+
110+
配置好魔法棒应用,并在技能中使用了Graph API类型插件。
80111

81112
### 技术支持
82113

example/config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"clientId": "dinguvrbesopqvisruwh",
3-
"clientSecret": "TwLmIxNSKuZW84nUkCmUWO4fs3Ws8I-CSly3Fo7l00fcnOz899D2Su2AEe8u5Vri"
2+
"clientId": "ding2kdwyyilaknq8zj5",
3+
"clientSecret": "vlDWox885jMZQLm5cQ6lBTtdjqQXEfK-PK5dIL29tPECYdAE0i1A_7wum76BLxzO"
44
}

example/index.ts

Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,81 @@
1-
import {DWClient, DWClientDownStream, EventAck, RobotMessage, TOPIC_ROBOT} from '../src/index.js';
2-
import axios from 'axios';
3-
import config from './config.json' assert {type: 'json'};
1+
import {
2+
DWClient,
3+
DWClientDownStream,
4+
EventAck,
5+
RobotMessage,
6+
TOPIC_ROBOT,
7+
TOPIC_AI_GRAPH_API,
8+
} from "../src/index.js";
9+
import axios from "axios";
10+
import config from "./config.json" assert { type: "json" };
411

12+
console.log("开始启动");
513
const client = new DWClient({
614
clientId: config.clientId,
715
clientSecret: config.clientSecret,
8-
debug: false
16+
debug: true,
917
});
1018
client.registerCallbackListener(TOPIC_ROBOT, async (res) => {
11-
// 注册机器人回调事件
12-
console.log("收到消息");
13-
// const {messageId} = res.headers;
14-
const { text, senderStaffId, sessionWebhook } = JSON.parse(res.data) as RobotMessage;
15-
const body = {
16-
at: {
17-
atUserIds: [senderStaffId],
18-
isAtAll: false,
19-
},
20-
text: {
21-
content: 'nodejs-getting-started say : 收到,' + text?.content || '钉钉,让进步发生',
22-
},
23-
msgtype: 'text',
24-
};
19+
// 注册机器人回调事件
20+
console.log("收到消息");
21+
debugger;
22+
// const {messageId} = res.headers;
23+
const { text, senderStaffId, sessionWebhook } = JSON.parse(
24+
res.data
25+
) as RobotMessage;
26+
const body = {
27+
at: {
28+
atUserIds: [senderStaffId],
29+
isAtAll: false,
30+
},
31+
text: {
32+
content:
33+
"nodejs-getting-started say : 收到," + text?.content ||
34+
"钉钉,让进步发生",
35+
},
36+
msgtype: "text",
37+
};
2538

26-
const result = await axios({
27-
url: sessionWebhook,
28-
method: 'POST',
29-
responseType: 'json',
30-
data: body,
31-
headers: {
32-
'x-acs-dingtalk-access-token': client.getConfig().access_token,
33-
},
34-
});
39+
const result = await axios({
40+
url: sessionWebhook,
41+
method: "POST",
42+
responseType: "json",
43+
data: body,
44+
headers: {
45+
"x-acs-dingtalk-access-token": client.getConfig().access_token,
46+
},
47+
});
3548

36-
return result.data;
37-
})
49+
return result.data;
50+
});
51+
client
52+
.registerCallbackListener(
53+
TOPIC_AI_GRAPH_API,
54+
async (res: DWClientDownStream) => {
55+
// 注册AI插件回调事件
56+
console.log("收到ai消息");
57+
const { messageId } = res.headers;
58+
59+
// 添加业务逻辑
60+
console.log(res);
61+
console.log(JSON.parse(res.data));
62+
63+
// 通过Stream返回数据
64+
client.sendGraphAPIResponse(messageId, {
65+
response: {
66+
statusLine: {
67+
code: 200,
68+
reasonPhrase: "OK",
69+
},
70+
headers: {},
71+
body: JSON.stringify({
72+
text: "你好",
73+
}),
74+
},
75+
});
76+
}
77+
)
3878
.registerAllEventListener((message: DWClientDownStream) => {
39-
return {status: EventAck.SUCCESS}
79+
return { status: EventAck.SUCCESS };
4080
})
4181
.connect();

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "dingtalk-stream-sdk-nodejs",
3-
"version": "2.0.4",
2+
"name": "dingtalk-stream",
3+
"version": "2.1.0",
44
"description": "Nodejs SDK for DingTalk Stream Mode API, Compared with the webhook mode, it is easier to access the DingTalk",
55
"main": "./dist/index.js",
66
"module": "./dist/index.mjs",

src/client.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import WebSocket from 'ws';
22
import axios from 'axios';
33
import EventEmitter from 'events';
4+
import { GraphAPIResponse } from './constants';
45

56
export enum EventAck {
67
SUCCESS = "SUCCESS",
@@ -157,7 +158,7 @@ export class DWClient extends EventEmitter {
157158
if (result.status === 200 && result.data.access_token) {
158159
this.config.access_token = result.data.access_token;
159160
const res = await axios({
160-
url: 'https://api.dingtalk.com/v1.0/gateway/connections/open',
161+
url: 'https://pre-api.dingtalk.com/v1.0/gateway/connections/open',
161162
method: 'POST',
162163
responseType: 'json',
163164
data: {
@@ -289,7 +290,7 @@ export class DWClient extends EventEmitter {
289290
this.onEvent(msg);
290291
break;
291292
case 'CALLBACK':
292-
// 处理机器人回调消息
293+
// 处理回调消息
293294
this.onCallback(msg);
294295
break;
295296
}
@@ -366,4 +367,22 @@ export class DWClient extends EventEmitter {
366367
};
367368
this.socket?.send(JSON.stringify(msg));
368369
}
370+
371+
sendGraphAPIResponse(messageId: string, value: GraphAPIResponse) {
372+
if (!messageId) {
373+
console.error('send: messageId must be defined');
374+
throw new Error('send: messageId must be defined');
375+
}
376+
377+
const msg = {
378+
code: 200,
379+
headers: {
380+
contentType: 'application/json',
381+
messageId: messageId,
382+
},
383+
message: 'OK',
384+
data: JSON.stringify(value),
385+
};
386+
this.socket?.send(JSON.stringify(msg));
387+
}
369388
}

src/constants.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ export const TOPIC_ROBOT = '/v1.0/im/bot/messages/get';
55
/** 卡片回调 */
66
export const TOPIC_CARD = '/v1.0/card/instances/callback';
77

8+
/** AI Graph API 插件消息回调 */
9+
export const TOPIC_AI_GRAPH_API = '/v1.0/graph/api/invoke';
10+
811
interface RobotMessageBase {
912
conversationId: string;
1013
chatbotCorpId: string;
@@ -30,4 +33,17 @@ export interface RobotTextMessage extends RobotMessageBase {
3033
};
3134
}
3235

36+
export interface GraphAPIResponse {
37+
response: {
38+
statusLine: {
39+
code?: number;
40+
reasonPhrase?: string;
41+
};
42+
headers: {
43+
[key: string]: string;
44+
};
45+
body: string;
46+
};
47+
}
48+
3349
export type RobotMessage = RobotTextMessage;

0 commit comments

Comments
 (0)