Skip to content

Commit

Permalink
feat:新增Graph API 调用,更新npm包名
Browse files Browse the repository at this point in the history
  • Loading branch information
junlonghuo committed Oct 17, 2023
1 parent 4d4a2de commit 7061a3b
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 41 deletions.
41 changes: 36 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# dingtalk-stream-sdk-nodejs
# dingtalk-stream
Nodejs SDK for DingTalk Stream Mode API, Compared with the webhook mode, it is easier to access the DingTalk chatbot
钉钉支持 Stream 模式接入事件推送、机器人收消息以及卡片回调,该 SDK 实现了 Stream 模式。相比 Webhook 模式,Stream 模式可以更简单的接入各类事件和回调。

## 快速开始
npm ii
npm start

### 准备工作

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

c、启动测试case
```Shell
cd dingtalk-stream-sdk-nodejs
cd dingtalk-stream
yarn
npm run build
npm start
```

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

```Shell
npm i dingtalk-stream-sdk-nodejs
npm i dingtalk-stream
```

代码中使用
```javascript
const DWClient = require("dingtalk-stream-sdk-nodejs");
const DWClient = require("dingtalk-stream");
const config = require("./config.json");

const client = new DWClient({
Expand All @@ -69,6 +71,32 @@ client.registerCallbackListener('/v1.0/im/bot/messages/get', async (res) => {
const {messageId} = res.headers;
const { text, senderStaffId, sessionWebhook } = JSON.parse(res.data);
})
.registerCallbackListener(
'/v1.0/graph/api/invoke',
async (res: DWClientDownStream) => {
// 注册AI插件回调事件
console.log("收到ai消息");
const { messageId } = res.headers;

// 添加业务逻辑
console.log(res);
console.log(JSON.parse(res.data));

// 通过Stream返回数据
client.sendGraphAPIResponse(messageId, {
response: {
statusLine: {
code: 200,
reasonPhrase: "OK",
},
headers: {},
body: JSON.stringify({
text: "你好",
}),
},
});
}
)
.connect();
```

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

### AI 应用 - 技能插件,Graph API 类型插件使用 (可选)

配置好魔法棒应用,并在技能中使用了Graph API类型插件。

### 技术支持

Expand Down
4 changes: 2 additions & 2 deletions example/config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"clientId": "dinguvrbesopqvisruwh",
"clientSecret": "TwLmIxNSKuZW84nUkCmUWO4fs3Ws8I-CSly3Fo7l00fcnOz899D2Su2AEe8u5Vri"
"clientId": "ding2kdwyyilaknq8zj5",
"clientSecret": "vlDWox885jMZQLm5cQ6lBTtdjqQXEfK-PK5dIL29tPECYdAE0i1A_7wum76BLxzO"
}
100 changes: 70 additions & 30 deletions example/index.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,81 @@
import {DWClient, DWClientDownStream, EventAck, RobotMessage, TOPIC_ROBOT} from '../src/index.js';
import axios from 'axios';
import config from './config.json' assert {type: 'json'};
import {
DWClient,
DWClientDownStream,
EventAck,
RobotMessage,
TOPIC_ROBOT,
TOPIC_AI_GRAPH_API,
} from "../src/index.js";
import axios from "axios";
import config from "./config.json" assert { type: "json" };

console.log("开始启动");
const client = new DWClient({
clientId: config.clientId,
clientSecret: config.clientSecret,
debug: false
debug: true,
});
client.registerCallbackListener(TOPIC_ROBOT, async (res) => {
// 注册机器人回调事件
console.log("收到消息");
// const {messageId} = res.headers;
const { text, senderStaffId, sessionWebhook } = JSON.parse(res.data) as RobotMessage;
const body = {
at: {
atUserIds: [senderStaffId],
isAtAll: false,
},
text: {
content: 'nodejs-getting-started say : 收到,' + text?.content || '钉钉,让进步发生',
},
msgtype: 'text',
};
// 注册机器人回调事件
console.log("收到消息");
debugger;
// const {messageId} = res.headers;
const { text, senderStaffId, sessionWebhook } = JSON.parse(
res.data
) as RobotMessage;
const body = {
at: {
atUserIds: [senderStaffId],
isAtAll: false,
},
text: {
content:
"nodejs-getting-started say : 收到," + text?.content ||
"钉钉,让进步发生",
},
msgtype: "text",
};

const result = await axios({
url: sessionWebhook,
method: 'POST',
responseType: 'json',
data: body,
headers: {
'x-acs-dingtalk-access-token': client.getConfig().access_token,
},
});
const result = await axios({
url: sessionWebhook,
method: "POST",
responseType: "json",
data: body,
headers: {
"x-acs-dingtalk-access-token": client.getConfig().access_token,
},
});

return result.data;
})
return result.data;
});
client
.registerCallbackListener(
TOPIC_AI_GRAPH_API,
async (res: DWClientDownStream) => {
// 注册AI插件回调事件
console.log("收到ai消息");
const { messageId } = res.headers;

// 添加业务逻辑
console.log(res);
console.log(JSON.parse(res.data));

// 通过Stream返回数据
client.sendGraphAPIResponse(messageId, {
response: {
statusLine: {
code: 200,
reasonPhrase: "OK",
},
headers: {},
body: JSON.stringify({
text: "你好",
}),
},
});
}
)
.registerAllEventListener((message: DWClientDownStream) => {
return {status: EventAck.SUCCESS}
return { status: EventAck.SUCCESS };
})
.connect();
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dingtalk-stream-sdk-nodejs",
"version": "2.0.4",
"name": "dingtalk-stream",
"version": "2.1.0",
"description": "Nodejs SDK for DingTalk Stream Mode API, Compared with the webhook mode, it is easier to access the DingTalk",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
Expand Down
23 changes: 21 additions & 2 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import WebSocket from 'ws';
import axios from 'axios';
import EventEmitter from 'events';
import { GraphAPIResponse } from './constants';

export enum EventAck {
SUCCESS = "SUCCESS",
Expand Down Expand Up @@ -157,7 +158,7 @@ export class DWClient extends EventEmitter {
if (result.status === 200 && result.data.access_token) {
this.config.access_token = result.data.access_token;
const res = await axios({
url: 'https://api.dingtalk.com/v1.0/gateway/connections/open',
url: 'https://pre-api.dingtalk.com/v1.0/gateway/connections/open',
method: 'POST',
responseType: 'json',
data: {
Expand Down Expand Up @@ -289,7 +290,7 @@ export class DWClient extends EventEmitter {
this.onEvent(msg);
break;
case 'CALLBACK':
// 处理机器人回调消息
// 处理回调消息
this.onCallback(msg);
break;
}
Expand Down Expand Up @@ -366,4 +367,22 @@ export class DWClient extends EventEmitter {
};
this.socket?.send(JSON.stringify(msg));
}

sendGraphAPIResponse(messageId: string, value: GraphAPIResponse) {
if (!messageId) {
console.error('send: messageId must be defined');
throw new Error('send: messageId must be defined');
}

const msg = {
code: 200,
headers: {
contentType: 'application/json',
messageId: messageId,
},
message: 'OK',
data: JSON.stringify(value),
};
this.socket?.send(JSON.stringify(msg));
}
}
16 changes: 16 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export const TOPIC_ROBOT = '/v1.0/im/bot/messages/get';
/** 卡片回调 */
export const TOPIC_CARD = '/v1.0/card/instances/callback';

/** AI Graph API 插件消息回调 */
export const TOPIC_AI_GRAPH_API = '/v1.0/graph/api/invoke';

interface RobotMessageBase {
conversationId: string;
chatbotCorpId: string;
Expand All @@ -30,4 +33,17 @@ export interface RobotTextMessage extends RobotMessageBase {
};
}

export interface GraphAPIResponse {
response: {
statusLine: {
code?: number;
reasonPhrase?: string;
};
headers: {
[key: string]: string;
};
body: string;
};
}

export type RobotMessage = RobotTextMessage;

0 comments on commit 7061a3b

Please sign in to comment.