Home

Awesome

<p align='center'> <br> 🚀 ChatGPT DingTalk 🚀 </p> <p align='center'>🌉 基于GO语言实现的钉钉集成ChatGPT机器人 🌉</p> <div align="center">

Auth Go Version GitHub Pull Requests GitHub Pull Requests HitCount Docker Image Size (latest by date) Docker Pulls GitHub license

</div>

<img src="https://cdn.jsdelivr.net/gh/eryajf/tu@main/img/image_20240420_214408.gif" width="800" height="3">

</div><br> <a href='https://wiki.eryajf.net' target="_blank" rel="noopener noreferrer"> <img src='https://user-images.githubusercontent.com/33259379/223607306-2ac836a2-7ce5-4a12-a16e-bec40b22d8d6.png' alt='' /> </a>
<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

目录

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

前言

本项目可以助你将 GPT 机器人集成到钉钉群聊当中。当前默认模型为gpt-3.5,支持gpt-4以及gpt-4o-mini。同时支持 Azure-OpenAI。

🥳 欢迎关注我的其他开源项目:

🚜 我还创建了一个项目 awesome-chatgpt-answer :记录那些问得好,答得妙的时刻,欢迎提交你与 ChatGPT 交互过程中遇到的那些精妙对话。

⚗️ openai 官方提供了一个 状态页 来呈现当前 openAI 服务的状态,同时如果有问题发布公告也会在这个页面,如果你感觉它有问题了,可以在这个页面看看。

赞助商

302.AI 是一个按需付费的一站式AI应用平台,开放平台,开源生态。

功能介绍

使用前提

使用教程

第一步,部署应用

docker 部署

推荐你使用 docker 快速运行本项目。

第一种:基于环境变量运行
# 运行项目
$ docker run -itd --name chatgpt -p 8090:8090 \
  -v ./data:/app/data --add-host="host.docker.internal:host-gateway" \
  -e LOG_LEVEL="info" -e APIKEY=换成你的key -e BASE_URL="" \
  -e MODEL="gpt-3.5-turbo" -e SESSION_TIMEOUT=600 \
  -e MAX_QUESTION_LENL=2048 -e MAX_ANSWER_LEN=2048 -e MAX_TEXT=4096 \
  -e HTTP_PROXY="http://host.docker.internal:15732" \
  -e DEFAULT_MODE="单聊" -e MAX_REQUEST=0 -e PORT=8090 \
  -e SERVICE_URL="你当前服务外网可访问的URL" -e CHAT_TYPE="0" \
  -e ALLOW_GROUPS=a,b -e ALLOW_OUTGOING_GROUPS=a,b -e ALLOW_USERS=a,b -e DENY_USERS=a,b -e VIP_USERS=a,b -e ADMIN_USERS=a,b -e APP_SECRETS="xxx,yyy" \
  -e SENSITIVE_WORDS="aa,bb" -e RUN_MODE="http" \
  -e AZURE_ON="false" -e AZURE_API_VERSION="" -e AZURE_RESOURCE_NAME="" \
  -e AZURE_DEPLOYMENT_NAME="" -e AZURE_OPENAI_TOKEN="" \
  -e DINGTALK_CREDENTIALS="your_client_id1:secret1,your_client_id2:secret2" \
  -e HELP="欢迎使用本工具\n\n你可以查看:[用户指南](https://github.com/eryajf/chatgpt-dingtalk/blob/main/docs/userGuide.md)\n\n这是一个[开源项目](https://github.com/eryajf/chatgpt-dingtalk/)
  ,觉得不错你可以来波素质三连."  \
  --restart=always  registry.cn-hangzhou.aliyuncs.com/eryajf/chatgpt-dingtalk

运行命令中映射的配置文件参考下边的配置文件说明

第二种:基于配置文件挂载运行
# 复制配置文件,根据自己实际情况,调整配置里的内容
$ cp config.example.yml config.yml  # 其中 config.example.yml 从项目的根目录获取

# 运行项目
$ docker run -itd --name chatgpt -p 8090:8090  -v `pwd`/config.yml:/app/config.yml --restart=always  registry.cn-hangzhou.aliyuncs.com/eryajf/chatgpt-dingtalk

其中配置文件参考下边的配置文件说明。

第三种:使用 docker compose 运行
$ wget https://raw.githubusercontent.com/eryajf/chatgpt-dingtalk/main/docker-compose.yml

$ vim docker-compose.yml # 编辑 APIKEY 等信息

$ docker compose up -d

之前部署完成之后还有一个配置 Nginx 的步骤,现在将模式默认指定为 stream 模式,因此不再需要配置 Nginx。

二进制部署

如果你想通过命令行直接部署,可以直接下载 release 中的压缩包 ,请根据自己系统以及架构选择合适的压缩包,下载之后直接解压运行。

下载之后,在本地解压,即可看到可执行程序,与配置文件:

$ tar xf chatgpt-dingtalk-v0.0.4-darwin-arm64.tar.gz
$ cd chatgpt-dingtalk-v0.0.4-darwin-arm64
$ cp config.example.yml  config.yml
$ ./chatgpt-dingtalk  # 直接运行

# 如果要守护在后台运行
$ nohup ./chatgpt-dingtalk &> run.log &
$ tail -f run.log

第二步,添加应用

钉钉官方在 2023 年 5 月份全面推出了 stream 模式,因此这里也推荐大家直接使用这个模式,其他 HTTP 的仍旧支持,只不过不再深入研究,因此下边的文档也以 stream 模式的配置流程来介绍。

创建步骤参考文档:企业内部应用,或者根据如下步骤进行配置。

  1. 创建应用。

    <details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230604_192719.png"> </details>

    📢 注意:可能现在创建机器人的时候名字为chatgpt会被钉钉限制,请用其他名字命名。

    基础信息 --> 应用信息当中能够获取到机器人的AppKeyAppSecret

  2. 配置机器人。

<details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230604_193103.png"> </details>
  1. 发布机器人。

    <details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230604_193314.png"> </details>

    点击版本管理与发布,然后点击上线,这个时候就能在钉钉的群里中添加这个机器人了。

  2. 群聊添加机器人。

<details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20221209_163724.png"> </details>

亮点特色

与机器人私聊

2023-03-08补充,我发现也可以不在群里艾特机器人聊天,还可点击机器人,然后点击发消息,通过与机器人直接对话进行聊天:

@Raytow 同学发现,在机器人自动生成的测试群里无法直接私聊机器人,在其他群里单独添加这个机器人,然后再点击就可以跟它私聊了。

<details> <summary>🖼 点我查看示例图</summary> <img src="https://user-images.githubusercontent.com/33259379/223607306-2ac836a2-7ce5-4a12-a16e-bec40b22d8d6.png"> </details>

帮助列表

艾特机器人发送空内容或者帮助,会返回帮助列表。

<details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230216_221253.png"> </details>

切换模式

发送指定关键字,可以切换不同的模式。

<details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230215_184655.png"> </details>

📢 注意:串聊模式下,群里每个人的聊天上下文是独立的。 📢 注意:默认对话模式为单聊,因此不必发送单聊即可进入单聊模式,而要进入串聊,则需要发送串聊关键字进行切换,当串聊内容超过最大限制的时候,你可以发送重置,然后再次进入串聊模式。

查询余额

艾特机器人发送 余额 二字,会返回当前 key 对应的账号的剩余额度以及可用日期。

<details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230304_222522.jpg"> </details>

日常问题

<details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20221209_163739.png"> </details>

通过内置 prompt 聊天

发送模板两个字,会返回当前内置支持的 prompt 列表。

<details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230323_152703.jpg"> </details>

如果你发现有比较优秀的 prompt,欢迎 PR。注意:一些与钉钉使用场景不是很匹配的,就不要提交了。

生成图片

发送以 #图片开头的内容,将会触发绘画能力,图片生成之后,将会保存在程序根目录下的images目录下。

如果你绘图没有思路,可以在这里以及这里找到一些不错的 prompt。

<details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230323_150547.jpg"> </details>

支持 gpt-4

如果你的账号通过了官方的白名单,那么可以将模型配置为:gpt-4-0314gpt-4gpt-4o-mini,目前 gpt-4 的余额查询以及图片生成功能暂不可用,可能是接口限制,也可能是其他原因,等我有条件的时候,会对这些功能进行测试验证。

以下是 gpt-3.5 与 gpt-4 对数学计算方面的区别。

<details> <summary>🖼 点我查看示例图</summary> <img src="https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230330_180308.jpg"> </details>

感谢@PIRANHACHAN同学提供的 gpt-4 的 key,使得项目在 gpt-4 的对接上能够进行验证测试,达到了可用状态。

本地开发

# 获取项目
$ git clone https://github.com/eryajf/chatgpt-dingtalk.git

# 进入项目目录
$ cd chatgpt-dingtalk

# 复制配置文件,根据个人实际情况进行配置
$ cp config.example.yml config.yml

# 启动项目
$ go run main.go

配置文件说明

# 应用的日志级别,info or debug
log_level: "info"
# 运行模式,http 或者 stream ,强烈建议你使用stream模式,通过此链接了解:https://open.dingtalk.com/document/isvapp/stream
run_mode: "stream"
# openai api_key,如果你是用的是azure,则该配置项可以留空或者直接忽略
api_key: "xxxxxxxxx"
# 如果你使用官方的接口地址 https://api.openai.com,则留空即可,如果你想指定请求url的地址,可通过这个参数进行配置,注意需要带上 http 协议,如果你是用的是azure,则该配置项可以留空或者直接忽略
base_url: ""
# 指定模型,默认为 gpt-3.5-turbo , 可选参数有: "gpt-4-32k-0613", "gpt-4-32k-0314", "gpt-4-32k", "gpt-4-0613", "gpt-4-0314", "gpt-4", "gpt-3.5-turbo-16k-0613", "gpt-3.5-turbo-16k", "gpt-3.5-turbo-0613", "gpt-3.5-turbo-0301", "gpt-3.5-turbo",如果使用gpt-4,请确认自己是否有接口调用白名单,如果你是用的是azure,则该配置项可以留空或者直接忽略
model: "gpt-3.5-turbo"
# 指定绘画模型,默认为 dall-e-2 , 可选参数有:"dall-e-2", "dall-e-3"
image_model: "dall-e-2"
# 会话超时时间,默认600秒,在会话时间内所有发送给机器人的信息会作为上下文
session_timeout: 600
# 最大问题长度
max_question_len: 2048
# 最大回答长度
max_answer_len: 2048
# 最大上下文文本长度,通常该参数可设置为与模型Token限制相同
max_text: 4096
# 指定请求时使用的代理,如果为空,则不使用代理,注意需要带上 http 协议 或 socks5 协议,如果你是用的是azure,则该配置项可以留空或者直接忽略
http_proxy: ""
# 指定默认的对话模式,可根据实际需求进行自定义,如果不设置,默认为单聊,即无上下文关联的对话模式
default_mode: "单聊"
# 单人单日请求次数上限,默认为0,即不限制
max_request: 0
# 指定服务启动端口,默认为 8090,一般在二进制宿主机部署时,遇到端口冲突时使用,如果run_mode为stream模式,则可以忽略该配置项
port: "8090"
# 指定服务的地址,就是当前服务可供外网访问的地址(或者直接理解为你配置在钉钉回调那里的地址),用于生成图片时给钉钉做渲染,最新版本中将图片上传到了钉钉服务器,理论上你可以忽略该配置项,如果run_mode为stream模式,则可以忽略该配置项
service_url: "http://xxxxxx"
# 限定对话类型 0:不限 1:只能单聊 2:只能群聊
chat_type: "0"
# 哪些群组可以进行对话(仅在chat_type为0、2时有效),如果留空,则表示允许所有群组,如果要限制,则列表中写群ID(ConversationID)
# 群ID,可在群组中 @机器人 群ID 来查看日志获取,例如日志会输出:[🙋 企业内部机器人 在『测试』群的ConversationID为: "cidrabcdefgh1234567890AAAAA"],获取后可填写该参数并重启程序
allow_groups: []
# 哪些普通群(使用outgoing机器人)可以进行对话,如果留空,则表示允许所有群组,如果要限制,则列表中写群ID(ConversationID)
# 群ID,可在群组中 @机器人 群ID 来查看日志获取,例如日志会输出:[🙋 outgoing机器人 在『测试』群的ConversationID为: "cidrabcdefgh1234567890AAAAA"],获取后可填写该参数并重启程序
# 如果不想支持outgoing机器人功能,这里可以随意设置一个内部群组,例如:cidrabcdefgh1234567890AAAAA;或随意一个字符串,例如:disabled
# 建议该功能默认关闭:除非你必须要用到outgoing机器人
allow_outgoing_groups: []
# 以下 allow_users、deny_users、vip_users、admin_users 配置中填写的是用户的userid,outgoing机器人模式下不适用这些配置
# 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts
# 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid
allow_users: []
# 哪些用户不可以进行对话,如果留空,则表示允许所有用户(如allow_user有配置,需满足相应条件),如果要限制,则列表中写用户的userid,黑名单优先级高于白名单
deny_users: []
# 哪些用户可以进行无限对话,如果留空,则表示只允许管理员(如max_request配置为0,则允许所有人)
# 如果要针对指定VIP用户放开限制(如max_request配置不为0),则列表中写用户的userid
vip_users: []
# 指定哪些人为此系统的管理员,如果留空,则表示没有人是管理员,如果要限制,则列表中写用户的userid
# 注意:如果下边的app_secrets为空,以及使用outgoing的方式配置机器人,这两种情况下,都表示没有人是管理员
admin_users: []
# 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果留空,将会忽略校验,则该接口将会存在其他人也能随意调用的安全隐患,因此强烈建议配置正确的secret,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret
app_secrets: []
# 敏感词,提问时触发,则不允许提问,回答的内容中触发,则以 🚫 代替
sensitive_words: []
# 帮助信息,放在配置文件,可供自定义
help: "### 发送信息\n\n若您想给机器人发送信息,有如下两种方式:\n\n1. **群聊:** 在机器人所在群里 **@机器人** 后边跟着要提问的内容。\n\n2. **私聊:** 点击机器人的 **头像** 后,再点击 **发消息。** \n\n### 系统指令\n\n系统指令是一些特殊的词语,当您向机器人发送这些词语时,会触发对应的功能。\n\n**📢 注意:系统指令,即只发指令,没有特殊标识,也没有内容。**\n\n以下是系统指令详情:\n\n|    指令    |                     描述                     |                             示例                             |\n| :--------: | :------------------------------------------: | :----------------------------------------------------------: |\n|  **单聊**  | 每次对话都是一次新的对话,没有聊天上下文联系 | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_193608.jpg'><br /></details> |\n|  **串聊**  |            带上下文联系的对话模式            | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_193608.jpg'><br /></details> |\n|  **重置**  |        重置上下文模式,回归到默认模式        | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_193608.jpg'><br /></details> |\n|  **余额**  |        查询机器人所用OpenAI账号的余额        | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230304_222522.jpg'><br /></details> |\n|  **模板**  |           查看应用内置的prompt模板           | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_193827.jpg'><br /></details> |\n|  **图片**  |           查看如何根据提示生成图片           | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_194125.jpg'><br /></details> |\n| **查对话** |            获取指定人员的对话历史            | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_193938.jpg'><br /></details> |\n|  **帮助**  |                 获取帮助信息                 | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_202336.jpg'><br /></details> |\n\n\n### 功能指令\n\n除去系统指令,还有一些功能指令,功能指令是直接与应用交互,达到交互目的的一种指令。\n\n**📢 注意:功能指令,一律以 #+关键字 为开头,通常需要在关键字后边加个空格,然后再写描述或参数。**\n\n以下是功能指令详情\n\n| 指令 | 说明 | 示例 |\n| :--: | :--: | :--: |\n|  **#图片**  |          根据提示咒语生成对应图片          | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230323_150547.jpg'><br /></details> |\n| **#域名**     | 查询域名相关信息     |  <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_202620.jpg'><br /></details>    |\n| **#证书**     | 查询域名证书相关信息     | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_202706.jpg'><br /></details>    |\n| **#Linux命令**     | 根据自然语言描述生成对应命令     | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_214947.jpg'><br /></details>    |\n| **#解释代码**     | 分析一段代码的功能或含义     | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_215242.jpg'><br /></details>    |\n| **#正则**     | 根据自然语言描述生成正则     | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_220222.jpg'><br /></details>    |\n| **#周报**     | 应用周报的prompt     | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_214335.jpg'><br /></details>    |\n| **#生成sql**     | 根据自然语言描述生成sql语句     | <details><br /><summary>预览</summary><br /><img src='https://cdn.jsdelivr.net/gh/eryajf/tu/img/image_20230404_221325.jpg'><br /></details>    |\n\n如上大多数能力,都是依赖prompt模板实现,如果你有更好的prompt,欢迎提交PR。\n\n### 友情提示\n\n使用 **串聊模式** 会显著加快机器人所用账号的余额消耗速度,因此,若无保留上下文的需求,建议使用 **单聊模式。** \n\n即使有保留上下文的需求,也应适时使用 **重置** 指令来重置上下文。\n\n### 项目地址\n\n本项目已在GitHub开源,[查看源代码](https://github.com/eryajf/chatgpt-dingtalk)。"

# Azure OpenAI 配置
# 例如你的示例请求为: curl https://eryajf.openai.azure.com/openai/deployments/gpt-35-turbo/chat/completions?api-version=2023-03-15-preview 那么对应配置如下,如果配置完成之后还是无法正常使用,请新建应用,重新配置回调试试看
azure_on: false # 如果是true,则会走azure的openai接口
azure_resource_name: "eryajf" # 对应你的主个性域名
azure_deployment_name: "gpt-35-turbo" # 对应的是 /deployments/ 后边跟着的这个值
azure_api_version: "2023-03-15-preview" # 对应的是请求中的 api-version 后边的值
azure_openai_token: "xxxxxxx"

# 钉钉应用鉴权凭据信息,支持多个应用。通过请求时候鉴权来识别是来自哪个机器人应用的消息
# 设置credentials 之后,即具备了访问钉钉平台绝大部分 OpenAPI 的能力;例如上传图片到钉钉平台,提升图片体验,结合 Stream 模式简化服务部署
# client_id 对应钉钉平台 AppKey/SuiteKey;client_secret 对应 AppSecret/SuiteSecret
credentials:
  - client_id: "put-your-client-id-here"
    client_secret: "put-your-client-secret-here"

常见问题

如何更好地使用 ChatGPT:这里有许多案例可供参考。

🗣 重要重要 一些常见的问题,我单独开 issue 放在这里:👉 点我 👈,可以查看这里辅助你解决问题,如果里边没有,请对历史 issue 进行搜索(不要提交重复的 issue),也欢迎大家补充。

进群交流

我创建了一个钉钉的交流群,欢迎进群交流。

感谢

这个项目能够成立,离不开这些开源项目:

赞赏

如果觉得这个项目对你有帮助,你可以请作者喝杯咖啡 ☕️

高光时刻

本项目曾在 | 2022-12-12 | 2022-12-18 | 2022-12-19 | 2022-12-20 | 2023-02-09 | 2023-02-10 | 2023-02-11 | 2023-02-12 | 2023-02-13 | 2023-02-14 | 2023-02-15 | 2023-03-04 | 2023-03-05 | 2023-03-19 | 2023-03-22 | 2023-03-25 | 2023-03-26 | 2023-03-27 | 2023-03-29, 这些天里,登上 GitHub Trending。而且还在持续登榜中,可见最近 openai 的热度。 image_20230316_114915

Star 历史

Star History Chart

贡献者列表

<div align="center"> <!-- readme: collaborators,contributors -start --> <table> <tr> <td align="center"> <a href="https://github.com/eryajf"> <img src="https://avatars.githubusercontent.com/u/33259379?v=4" width="75;" alt="eryajf"/> <br /> <sub><b>二丫讲梵</b></sub> </a> </td> <td align="center"> <a href="https://github.com/Leizhenpeng"> <img src="https://avatars.githubusercontent.com/u/50035229?v=4" width="75;" alt="Leizhenpeng"/> <br /> <sub><b>RiverRay</b></sub> </a> </td> <td align="center"> <a href="https://github.com/DDMeaqua"> <img src="https://avatars.githubusercontent.com/u/110169811?v=4" width="75;" alt="DDMeaqua"/> <br /> <sub><b>Null</b></sub> </a> </td> <td align="center"> <a href="https://github.com/ffinly"> <img src="https://avatars.githubusercontent.com/u/29793346?v=4" width="75;" alt="ffinly"/> <br /> <sub><b>Finly</b></sub> </a> </td> <td align="center"> <a href="https://github.com/FrankCheungDev"> <img src="https://avatars.githubusercontent.com/u/22819074?v=4" width="75;" alt="FrankCheungDev"/> <br /> <sub><b>Frank Cheung</b></sub> </a> </td> <td align="center"> <a href="https://github.com/ronething"> <img src="https://avatars.githubusercontent.com/u/28869910?v=4" width="75;" alt="ronething"/> <br /> <sub><b>Ashing Zheng</b></sub> </a> </td> <td align="center"> <a href="https://github.com/b3nguang"> <img src="https://avatars.githubusercontent.com/u/121670274?v=4" width="75;" alt="b3nguang"/> <br /> <sub><b>本光</b></sub> </a> </td> <td align="center"> <a href="https://github.com/laorange"> <img src="https://avatars.githubusercontent.com/u/68316902?v=4" width="75;" alt="laorange"/> <br /> <sub><b>辣橙</b></sub> </a> </td></tr> <tr> <td align="center"> <a href="https://github.com/chzealot"> <img src="https://avatars.githubusercontent.com/u/22822?v=4" width="75;" alt="chzealot"/> <br /> <sub><b>金喜@DingTalk</b></sub> </a> </td> <td align="center"> <a href="https://github.com/WinMin"> <img src="https://avatars.githubusercontent.com/u/18380453?v=4" width="75;" alt="WinMin"/> <br /> <sub><b>Swing</b></sub> </a> </td> <td align="center"> <a href="https://github.com/suyunkai"> <img src="https://avatars.githubusercontent.com/u/82149368?v=4" width="75;" alt="suyunkai"/> <br /> <sub><b>Null</b></sub> </a> </td> <td align="center"> <a href="https://github.com/stoneflying"> <img src="https://avatars.githubusercontent.com/u/38101022?v=4" width="75;" alt="stoneflying"/> <br /> <sub><b>Stoneflying</b></sub> </a> </td> <td align="center"> <a href="https://github.com/cnmill"> <img src="https://avatars.githubusercontent.com/u/21098695?v=4" width="75;" alt="cnmill"/> <br /> <sub><b>Mill Peng</b></sub> </a> </td> <td align="center"> <a href="https://github.com/little-huang"> <img src="https://avatars.githubusercontent.com/u/53588889?v=4" width="75;" alt="little-huang"/> <br /> <sub><b>Little_huang</b></sub> </a> </td> <td align="center"> <a href="https://github.com/iblogc"> <img src="https://avatars.githubusercontent.com/u/3283023?v=4" width="75;" alt="iblogc"/> <br /> <sub><b>Iblogc</b></sub> </a> </td> <td align="center"> <a href="https://github.com/wangbooth"> <img src="https://avatars.githubusercontent.com/u/18130585?v=4" width="75;" alt="wangbooth"/> <br /> <sub><b>WangBooth</b></sub> </a> </td></tr> <tr> <td align="center"> <a href="https://github.com/fantasticmao"> <img src="https://avatars.githubusercontent.com/u/20675747?v=4" width="75;" alt="fantasticmao"/> <br /> <sub><b>Mao Mao</b></sub> </a> </td> <td align="center"> <a href="https://github.com/luoxufeiyan"> <img src="https://avatars.githubusercontent.com/u/6621172?v=4" width="75;" alt="luoxufeiyan"/> <br /> <sub><b>Hugh Gao</b></sub> </a> </td> <td align="center"> <a href="https://github.com/AydenLii"> <img src="https://avatars.githubusercontent.com/u/90502440?v=4" width="75;" alt="AydenLii"/> <br /> <sub><b>AydenLii</b></sub> </a> </td></tr> </table> <!-- readme: collaborators,contributors -end --> </div>