Skip to content

Commit

Permalink
feat: 完成 Node.js 订阅事件推送的教程
Browse files Browse the repository at this point in the history
Signed-off-by: Ke Jie <[email protected]>
  • Loading branch information
chzealot committed Sep 18, 2023
1 parent 6ec4da9 commit 2bdcfcb
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 67 deletions.
128 changes: 61 additions & 67 deletions docs/explore/tutorials/stream/event/nodejs/build-listener.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,103 +4,97 @@ sidebar_position: 3

# 3. 开发事件订阅服务

在本章节中,将会介绍如何用 Go 开发一个事件订阅服务,接收钉钉平台推送的变更通知。
在本章节中,将会介绍如何用 Node.js 开发一个事件订阅服务,接收钉钉平台推送的变更通知。

本教程的完整代码可以在 [GitHub 仓库](https://github.com/open-dingtalk/dingtalk-tutorial-go)中获取。
本教程的完整代码可以在 [GitHub 仓库](https://github.com/open-dingtalk/dingtalk-tutorial-nodejs)中获取。

## 创建 Go 模块
## 创建 Node.js 应用

```shell
mkdir event_chat_update
cd event_chat_update
npm init -y
npm install dingtalk-stream-sdk-nodejs commander
npm install --save-dev typescript ts-node
```

## 安装依赖

```shell
go get github.com/open-dingtalk/dingtalk-stream-sdk-go
npm install dingtalk-stream-sdk-nodejs commander
npm install --save-dev typescript ts-node
npm install
```

## 开发事件订阅服务
提醒:对于精通 TypeScript 和 JavaScript 的开发者来说,以上依赖项中,仅 dingtalk-stream-sdk-nodejs 是必须的。其他依赖项可以根据实际项目需要决定是否引入。

在 go.mod 相同的目录下,创建 `event_handler.go` 文件,文件内容如下:

```go title="event_handler.go" {13-32} showLineNumbers
package main

import (
"context"
"flag"
"github.com/open-dingtalk/dingtalk-stream-sdk-go/client"
"github.com/open-dingtalk/dingtalk-stream-sdk-go/event"
"github.com/open-dingtalk/dingtalk-stream-sdk-go/logger"
"github.com/open-dingtalk/dingtalk-stream-sdk-go/payload"
"time"
)

func OnEventReceived(_ context.Context, df *payload.DataFrame) (*payload.DataFrameResponse, error) {
eventHeader := event.NewEventHeaderFromDataFrame(df)
if eventHeader.EventType != "chat_update_title" {
// ignore events not equals `chat_update_title`; 忽略`chat_update_title`之外的其他事件;
// 该示例仅演示 chat_update_title 类型的事件订阅;
return event.NewSuccessResponse()
}

logger.GetLogger().Infof("received event, delay=%s, eventType=%s, eventId=%s, eventBornTime=%d, eventCorpId=%s, eventUnifiedAppId=%s, data=%s",
time.Duration(time.Now().UnixMilli()-eventHeader.EventBornTime)*time.Millisecond,
eventHeader.EventType,
eventHeader.EventId,
eventHeader.EventBornTime,
eventHeader.EventCorpId,
eventHeader.EventUnifiedAppId,
df.Data)
// put your code here; 可以在这里添加你的业务代码,处理事件订阅的业务逻辑;

return event.NewSuccessResponse()
}

func main() {
var clientId, clientSecret string
flag.StringVar(&clientId, "client_id", "", "your-client-id, AppKey or SuiteKey")
flag.StringVar(&clientSecret, "client_secret", "", "your-client-secret, AppSecret or SuiteSecret")
flag.Parse()
if len(clientId) == 0 || len(clientSecret) == 0 {
panic("command line options --client_id and --client_secret required")
}

logger.SetLogger(logger.NewStdTestLogger())
## 开发事件订阅服务

cli := client.NewStreamClient(client.WithAppCredential(client.NewAppCredentialConfig(clientId, clientSecret)))
cli.RegisterAllEventRouter(OnEventReceived)
一、修改 event_chat_update 目录下的 `package.json` 文件:

err := cli.Start(context.Background())
if err != nil {
panic(err)
}
1. 将 index.js 修改为 index.ts
2. 在 scripts 中添加命令:`"start": "npx ts-node --esm ./index.ts"`

defer cli.Close()
相关代码如下:
```text {2,4}
...
"main": "index.ts",
"scripts": {
"start": "npx ts-node --esm ./index.ts",
...
```

select {}
二、在 event_chat_update 目录下,创建 `index.ts` 文件,文件内容如下:

```typescript title="index.ts" {15-31} showLineNumbers
import {DWClient, DWClientDownStream, EventAck} from 'dingtalk-stream-sdk-nodejs';
const { program } = require('commander');

program
.requiredOption('--clientId <Client ID>', 'your client id, AppKey or SuiteKey')
.requiredOption('--clientSecret <Client Secret>', 'your client secret, AppSecret or SuiteSecret')
.parse();
const options = program.opts();

const client = new DWClient({
clientId: options.clientId,
clientSecret: options.clientSecret,
});

const onEventReceived = (event: DWClientDownStream) => {
if (event.headers?.eventType !== 'chat_update_title') {
// ignore events not equals `chat_update_title`; 忽略`chat_update_title`之外的其他事件;
// 该示例仅演示 chat_update_title 类型的事件订阅;
return {status: EventAck.SUCCESS};
}
const now = new Date();
console.log(`received event,
delay=${now.getTime() - parseInt(event.headers?.eventBornTime || '0')}ms,
eventType=${event.headers?.eventType},
eventId=${event.headers?.eventId},
eventBornTime=${event.headers?.eventBornTime},
eventCorpId=${event.headers?.eventCorpId},
eventUnifiedAppId=${event.headers?.eventUnifiedAppId},
data=${event.data}`)
return {status: EventAck.SUCCESS, message: 'OK'}; // message 属性可以是任意字符串;
}

client
.registerAllEventListener(onEventReceived)
.connect();
```

以上不超过 60 行的代码实现了这些能力:
以上不超过 40 行的代码实现了这些能力:
1. 通过命令行参数读取 Client ID 和 Client Secret 选项
2. 通过 Client ID 和 Client Secret 创建 Stream Client
2. 通过 Client ID 和 Client Secret 创建 Stream Client (DWClient)
3. 在 Stream Client 中注册事件推送的监听服务,实现变更通知的接收能力
4. 在事件回调方法中,通过日志记录变更通知的消息内容,你可以可以改造这段代码,将变更通知写入自己的数据库中

## 运行事件订阅服务

通过以下命令可以运行你的事件订阅服务,当看到这样的日志输出时候表示运行成功 `[INFO] connect success, sessionId=[...]`
通过以下命令可以运行你的事件订阅服务,当看到这样的日志输出时候表示运行成功 `Socket open`

```shell
go mod tidy
go run event_handler.go --client_id="your-client-id" --client_secret="your-client-secret"
npm run start -- --clientId="your-client-id" --clientSecret="your-client-secret"
```

:::caution 注意事项
Expand All @@ -116,4 +110,4 @@ go run event_handler.go --client_id="your-client-id" --client_secret="your-clien

## 相关链接

* [GitHub 上示例代码](https://github.com/open-dingtalk/dingtalk-tutorial-go)
* [GitHub 上示例代码](https://github.com/open-dingtalk/dingtalk-tutorial-nodejs)
13 changes: 13 additions & 0 deletions docs/explore/tutorials/stream/event/nodejs/congrats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
sidebar_position: 6
---

# 6. 恭喜你!

至此,你已经完成了从零开始创建、开发和部署一个应用,并成功完成变更通知接收能力。

除了 Node.js 之外,钉钉 Stream 模式的机器人的 SDK 还支持其他主流编程语言,可以移步[钉钉 SDK 概述](/docs/develop/sdk/overview)查看所有的 SDK。

## 相关链接

* [GitHub 上完整教程代码](https://github.com/open-dingtalk/dingtalk-stream-sdk-nodejs)
27 changes: 27 additions & 0 deletions docs/explore/tutorials/stream/event/nodejs/subscribe-topic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
sidebar_position: 4
---

# 4. 订阅事件类型

本文将介绍如何找到想要订阅的事件类型(Topic),并开启相应类型的事件订阅。

## 步骤说明

1. **进入应用**:进入钉钉[开发者后台](https://open-dev.dingtalk.com),找到[步骤2:创建应用](create-app)中创建的应用,然后点击进入应用详情页
2. **通道验证**:依次点击【事件与回调】-【已完成接入,验证连接通道】-【保存】,即可完成通道验证<br />
![通道验证](/img/explore/stream/event/stream-validate.png)<br />
:::caution 注意事项
在操作通道验证之前,务必完成[步骤3:开发事件订阅服务](build-listener),并成功启动事件订阅的服务,否则会导致“验证连接通道”异常。
:::
3. **选择类型**:继续保持在当前页面,下拉到页面底部,可以找到所有的事件列表。根据需要勾选以开启对应的事件类型(Topic)变更通知。<br />
在当前教程中,我们选择了“群会话更换群名称”,请勾选以顺利进行下一步功能体验。<br />
你可以在[官方文档:配置事件订阅的推送](https://open.dingtalk.com/document/orgapp/stream)文档中,点击左侧导航栏找到所有的事件类型。例如通过[群会话更换群名称](https://open.dingtalk.com/document/orgapp/group-session-change-group-name-stream)文档,可以知道“群会话更换群名称”事件对应的英文名称(Topic)是“chat_update_title”。<br />
示意图如下:<br />
![选择 Topic](/img/explore/stream/event/select-topic.png)

至此,已完成代码开发以及事件订阅的配置,接下来可以体验一下订阅变更通知的实际效果。

## 相关链接

* [官方文档:配置事件订阅的推送](https://open.dingtalk.com/document/orgapp/stream)
32 changes: 32 additions & 0 deletions docs/explore/tutorials/stream/event/nodejs/test-event.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
sidebar_position: 5
---

# 5. 体验事件通知

本文将介绍如何体验事件变更通知的接收效果。

## 触发一个变更通知

[步骤3:开发事件订阅服务](build-listener)中,我们在代码里记录了“群会话更换群名称”(Topic:chat_update_title)事件的消息数据。可以通过修改一个群名称,查看事件订阅的效果。

步骤如下:
1. 找到一个内部群,而且确认这个内部群归属的组织与[步骤2:创建应用](create-app)所采用的是同一个组织;
2. 修改群名称,任意名称即可

## 查看日志

查看[步骤3:开发事件订阅服务](build-listener)`index.ts` 服务运行的日志,可以看到这样一条日志表示成功接收到服务端推送的群名称变更事件。

```text wordWrap=true
received event,
delay=165ms,
eventType=chat_update_title,
eventId=44c****be0,
eventBornTime=1695057173479,
eventCorpId=ding****741,
eventUnifiedAppId=fce39****bad,
data={"timeStamp":1695057173477,"chatId":"chat****a45d","operatorUnionId":"RC****iE","title":"SDK 测试,请忽略","openConversationId":"cid9****HQ==","operator":"042****297"}
```

备注:为了方便展示,手动对日志做了换行和格式优化。

0 comments on commit 2bdcfcb

Please sign in to comment.