Skip to content

Commit

Permalink
2.7.0版本更新计划 (#144)
Browse files Browse the repository at this point in the history
- [x] #165
暂时只用文本展示
  - [x] 代码提交 @Daydaylw3 
  - [x] 文档增加说明
- [x] #159
    - [x] 增加有条件开启是否转发自己消息
    - [x] 消息增加标识自己
    - [x] 设备上自己发送消息上报recvd-api
    - [x] 通过推消息api自己发送的消息上报recvd-api
- [x] #140
  - [x] 系统消息单独定义类型 
  - [x] 根据特定的错误标识,提前触发logout 事件,并且屏蔽上报请求
  - [x] 完善readme
- [x] #160
  - [x] 尝试根据wechaty的通用错误手动触发 logout 事件,并且登出当前账号
  - [x] 版本部署测试环境,观测掉线事件中
  - [x] 优化代码,确保登出事件只触发一次
  • Loading branch information
danni-cool authored Mar 2, 2024
2 parents 67615d3 + 6a895c7 commit 3d9d737
Show file tree
Hide file tree
Showing 29 changed files with 590 additions and 205 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ LOG_LEVEL=info
# 如果不希望登录一次后就记住当前账号,想每次都扫码登陆,填 true
DISABLE_AUTO_LOGIN=

# RECVD_MSG_API 是否接收来自自己发的消息
ACCEPT_RECVD_MSG_MYSELF=false

# 如果想自己处理收到消息的逻辑,在下面填上你的API地址, 默认为空
LOCAL_RECVD_MSG_API=

Expand Down
13 changes: 10 additions & 3 deletions .github/workflows/nightly-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@ jobs:
with:
username: dannicool
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Build and Push Docker Image
run: |
docker build . -t dannicool/docker-wechatbot-webhook:nightly
docker push dannicool/docker-wechatbot-webhook:nightly
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: true
tags: dannicool/docker-wechatbot-webhook:nightly
platforms: linux/amd64,linux/arm64
2 changes: 1 addition & 1 deletion .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx -y commitlint --edit "$1"
npx commitlint --edit "$1"
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx -y lint-staged
npx lint-staged
34 changes: 20 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,13 @@ docker logs -f wxBotWebhook

> Tips:需要增加参数使用 -e,多行用 \ 隔开,例如 -e RECVD_MSG_API="<https://example.com/your/url>" \
| 功能 | 环境变量 | 案例 | 备注 |
|--|--|--|--|
| 收消息 | RECVD_MSG_API | RECVD_MSG_API=<https://example.com/your/url> | 如果想自己处理收到消息的逻辑,比如根据消息联动,填上你的处理逻辑 url,该行可以省略 |
| 禁用自动登录 | DISABLE_AUTO_LOGIN | DISABLE_AUTO_LOGIN=true | 非微信踢下线账号,可以依靠session免登, 如果想每次都扫码登陆,则增加该条配置 |
| 自定义登录 API token | LOGIN_API_TOKEN | LOGIN_API_TOKEN=abcdefg123 | 你也可以自定义一个自己的登录令牌,不配置的话,默认会生成一个 |
| 功能 | 变量 | 备注 |
|--|--|--|
| 日志级别 | LOG_LEVEL=info | 日志级别,默认 info,只影响当前日志输出,详细输出考虑使用 debug。无论该值如何变化,日志文件总是记录debug级别的日志 |
| 收消息 API | RECVD_MSG_API=<https://example.com/your/url> | 如果想自己处理收到消息的逻辑,比如根据消息联动,填上你的处理逻辑 url |
| 收消息 API 接受自己发的消息 | ACCEPT_RECVD_MSG_MYSELF=false | RECVD_MSG_API 是否接收来自自己发的消息(设置为true,即接收, 默认false) |
| 自定义登录 API token | LOGIN_API_TOKEN=abcdefg123 | 你也可以自定义一个自己的登录令牌,不配置的话,默认会生成一个 |
| 禁用自动登录 | DISABLE_AUTO_LOGIN=true | **非微信踢下线账号,可以依靠当前登录的session免登**, 如果想每次都扫码登陆,则增加该条配置 |

## 🛠️ API

Expand Down Expand Up @@ -309,11 +311,11 @@ curl --location --request POST 'http://localhost:3001/webhook/msg?token=[YOUR_PE

| formData | 说明 | 数据类型 | 可选值 | 示例 |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ----------------------- | ------------------------------------------------ |
| type | <div>支持的类型</div><ul><li>✅ 文字(text)</li><li>✅ 链接卡片(urlLink)</li><li>✅ 图片(file)</li><li>✅ 视频(file)</li><li>✅ 附件(file)</li> <li>✅ 语音(file)</li><li>✅ 添加好友邀请(friendship)</li></ul> refer: [wechaty类型支持列表](https://wechaty.js.org/docs/api/message#messagetype--messagetype) | `String` | `text` `file` `urlLink` `friendship` | - |
| type | <div>功能类型</div><ul><li>✅ 文字(text)</li><li>✅ 链接卡片(urlLink)</li><li>✅ 图片(file)</li><li>✅ 视频(file)</li><li>✅ 附件(file)</li> <li>✅ 语音(file)</li><li>✅ 添加好友邀请(friendship)</li></ul><div>其他类型</div><ul><li>未实现的消息类型(unknown)</li></ul><div>系统类型</div><ul><li>✅ 登录(system_event_login)</li><li>✅ 登出(system_event_logout)</li><li>✅ 异常报错(system_event_error)</li><li>✅ 快捷回复后消息推送状态通知(system_event_push_notify)</li></ul> | `String` | `text` `file` `urlLink` `friendship` `unknown` `system_event_login` `system_event_logout` `system_event_error` `system_event_push_notify`| - |
| content | 传输的内容, 文本或传输的文件共用这个字段,结构映射请看示例 | `String` `Binary` | | [示例](docs/recvdApi.example.md#formdatacontent) |
| source | 消息的相关发送方数据, JSON String | `String` | | [示例](docs/recvdApi.example.md#formdatasource) |
| isMentioned | 该消息是@我的消息[#38](https://github.com/danni-cool/wechatbot-webhook/issues/38) | `String` | `1` `0` | - |
| isSystemEvent | 是否是来自系统消息事件(上线,掉线、异常事件、快捷回复后的通知) | `String` | `1` `0` | - |
| isMentioned | 该消息是@我的消息 [#38](https://github.com/danni-cool/wechatbot-webhook/issues/38) | `String` | `1` `0` | - |
| isMsgFromSelf | 是否是来自自己的消息 [#159](https://github.com/danni-cool/wechatbot-webhook/issues/159) | `String` | `1` `0` | - |

**服务端处理 formData 一般需要对应的处理程序,假设你已经完成这一步,你将得到以下 request**

Expand All @@ -323,7 +325,8 @@ curl --location --request POST 'http://localhost:3001/webhook/msg?token=[YOUR_PE
"content": "你好",
"source": "{\"room\":\"\",\"to\":{\"_events\":{},\"_eventsCount\":0,\"id\":\"@f387910fa45\",\"payload\":{\"alias\":\"\",\"avatar\":\"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=1302335654&username=@f38bfd1e0567910fa45&skey=@crypaafc30\",\"friend\":false,\"gender\":1,\"id\":\"@f38bfd1e10fa45\",\"name\":\"ch.\",\"phone\":[],\"star\":false,\"type\":1}},\"from\":{\"_events\":{},\"_eventsCount\":0,\"id\":\"@6b5111dcc269b6901fbb58\",\"payload\":{\"address\":\"\",\"alias\":\"\",\"avatar\":\"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=123234564&username=@6b5dbb58&skey=@crypt_ec356afc30\",\"city\":\"Mars\",\"friend\":false,\"gender\":1,\"id\":\"@6b5dbd3facb58\",\"name\":\"Daniel\",\"phone\":[],\"province\":\"Earth\",\"signature\":\"\",\"star\":false,\"weixin\":\"\",\"type\":1}}}",
"isMentioned": "0",
"isSystemEvent": "0"
"isMsgFromSelf": "0",
"isSystemEvent": "0" // 考虑废弃,请使用type类型判断系统消息
}
```

Expand All @@ -334,8 +337,7 @@ curl --location 'https://your.recvdapi.com' \
--form 'type="file"' \
--form 'content=@"/Users/Downloads/13482835.jpeg"' \
--form 'source="{\\\"room\\\":\\\"\\\",\\\"to\\\":{\\\"_events\\\":{},\\\"_eventsCount\\\":0,\\\"id\\\":\\\"@f387910fa45\\\",\\\"payload\\\":{\\\"alias\\\":\\\"\\\",\\\"avatar\\\":\\\"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=1302335654&username=@f38bfd1e0567910fa45&skey=@crypaafc30\\\",\\\"friend\\\":false,\\\"gender\\\":1,\\\"id\\\":\\\"@f38bfd1e10fa45\\\",\\\"name\\\":\\\"ch.\\\",\\\"phone\\\":[],\\\"star\\\":false,\\\"type\\\":1}},\\\"from\\\":{\\\"_events\\\":{},\\\"_eventsCount\\\":0,\\\"id\\\":\\\"@6b5111dcc269b6901fbb58\\\",\\\"payload\\\":{\\\"address\\\":\\\"\\\",\\\"alias\\\":\\\"\\\",\\\"avatar\\\":\\\"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=123234564&username=@6b5dbb58&skey=@crypt_ec356afc30\\\",\\\"city\\\":\\\"Mars\\\",\\\"friend\\\":false,\\\"gender\\\":1,\\\"id\\\":\\\"@6b5dbd3facb58\\\",\\\"name\\\":\\\"Daniel\\\",\\\"phone\\\":[],\\\"province\\\":\\\"Earth\\\",\\\"signature\\\":\\\"\\\",\\\"star\\\":false,\\\"weixin\\\":\\\"\\\",\\\"type\\\":1}}}"' \
--form 'isMentioned="0"' \
--form 'isSystemEvent="0"'
--form 'isMentioned="0"'
```


Expand Down Expand Up @@ -399,14 +401,18 @@ curl --location 'https://your.recvdapi.com' \
- **query**: token

**status**: `200`
登录成功,返回 json 包含当前用户

##### 登录成功

返回 json 包含当前用户

```json
{"success":true,"message":"Contact<TestUser>is already login"}
```

**status**: `302`
登录态掉了,跳转最新的登录二维码
##### 登录失败

展示微信登录扫码页面

#### `/healthz?token=[YOUR_PERSONAL_TOKEN]`

Expand Down
7 changes: 4 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ services:
ports:
- "3001:3001"
environment:
- LOG_LEVEL=info # 调整容器输出级别(不影响日志文件输出等级)运行时提示的消息等级(默认info,想有更详细的日志,等级同log4js)
- LOG_LEVEL=info # 调整容器输出级别(不影响日志文件输出等级)运行时提示的消息等级(默认info,debug级别会输出详细的日志)
# - DISABLE_AUTO_LOGIN=true # 如果不希望登录一次后就记住当前账号,想每次都扫码登陆,填 true
# - LOCAL_RECVD_MSG_API= # 如果想自己处理收到消息的逻辑,在下面填上你的API地址, 默认为空
# - LOCAL_LOGIN_API_TOKEN= # 登录地址Token访问地址: http://localhost:3001/login?token=[LOCAL_LOGIN_API_TOKEN]
# - ACCEPT_RECVD_MSG_MYSELF=true # 如果希望机器人可以自己接收消息,填 true
# - RECVD_MSG_API= # 如果想自己处理收到消息的逻辑,在下面填上你的API地址, 默认为空
# - LOGIN_API_TOKEN= # 登录地址Token访问地址: http://localhost:3001/login?token=[LOCAL_LOGIN_API_TOKEN]
restart: unless-stopped
4 changes: 4 additions & 0 deletions dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ ENV RECVD_MSG_API=
ENV LOGIN_API_TOKEN=
# 是否禁用默认登录
ENV DISABLE_AUTO_LOGIN=
# 运行时提示的消息等级(默认info,想有更详细的日志,可以指定为debug)
ENV LOG_LEVEL=info
# RECVD_MSG_API 是否接收来自自己发的消息(设置为true,即接收)
ENV ACCEPT_RECVD_MSG_MYSELF=false

# 暴露端口(你的 Express 应用程序监听的端口)
EXPOSE 3001
Expand Down
95 changes: 81 additions & 14 deletions docs/recvdApi.example.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# RECVD_MSG_API JSON 示例

## formData 请求体不同情况说明
## 1. `formData.type` 不同情况说明

### 文字消息 `formData.type === text`
### 1.1 功能消息类型

#### 文字消息 `text`

- 是否支持快捷回复:✅
- `formData.content`: `String`

### 文件消息 `formData.type === file`
#### 文件消息 `file`

- 是否支持快捷回复:✅
- `formData.content`: `binary`

### 公众号推文 `formData.type === urlLink`
#### 公众号推文 `urlLink`

- 是否支持快捷回复:❌
- `formData.content``json`
Expand All @@ -27,7 +29,7 @@
}
```

### 加好友请求 `formData.type === friendship`
#### 加好友请求 `friendship`

- 是否支持快捷回复:✅
- `formData.content``json`
Expand All @@ -41,16 +43,31 @@

> 通过好友请求,需要通过接口返回 `{ "success": true }` 字段
### 4. 系统消息 `formData.isSystemEvent === '1'`
### 1.2 其他消息类型

#### 不支持的消息类型 `unknown`

- 是否支持快捷回复:✅

没法在当前版本微信中展示的消息,如果能展示值,会以**文本形式**展示,否则为空

例如:
- [unknown 类型里拍一拍消息提示](https://github.com/danni-cool/wechatbot-webhook/pull/121)


### 1.3 系统通知消息类型

- 是否支持快捷回复:❌

#### 微信已登录/登出 `system_event_login` | `system_event_logout`

- `formData.content`: `json`
示例

```js
{
"event": "login", // login | logout | error | notifyOfRecvdApiPushMsg
"event": "login", // login | logout

"user": { // 当前的用户信息,没有则为null
"user": { // 当前的用户信息
"_events": {},
"_eventsCount": 0,
"id": "@xxxasdfsf",
Expand All @@ -65,11 +82,61 @@
"star": false,
"type": 1
}

"error": ''// js 报错的错误栈信息
}
}
```

#### 系统运行出错 `system_event_error`
- `formData.content`: `json`
```js
{
"event": "error", //notifyOfRecvdApiPushMsg

"user": { // 当前的用户信息
"_events": {},
"_eventsCount": 0,
"id": "@xxxasdfsf",
"payload": {
"alias": "",
"avatar": "",
"friend": false,
"gender": 1,
"id": "@xxx",
"name": "somebody",
"phone": [],
"star": false,
"type": 1
}
},

"error": {} // 具体出错信息 js error stack
}
```

#### 快捷回复后通知 `system_event_push_notify`
- `formData.content`: `json`
```js
{
"event": "error", //notifyOfRecvdApiPushMsg

"user": { // 当前的用户信息
"_events": {},
"_eventsCount": 0,
"id": "@xxxasdfsf",
"payload": {
"alias": "",
"avatar": "",
"friend": false,
"gender": 1,
"id": "@xxx",
"name": "somebody",
"phone": [],
"star": false,
"type": 1
}
},

//仅当 event: "notifyOfRecvdApiPushMsg" 快捷回复后触发才返回次结构, 如果有部分消息推送失败也在此结构能拿到所有信息, 结构同推消息的api结构
// 快捷回复后触发才返回此结构,如果有部分消息推送失败也在此结构能拿到所有信息, 结构同推消息的api结构
"recvdApiReplyNotify": {
"success": true,
"message": "Message sent successfully",
Expand All @@ -86,7 +153,7 @@
```


## formData.source `String`
## 2. formData.source `String`

```js
{
Expand All @@ -99,7 +166,7 @@
"adminIdList": [],
"avatar": "xxxx", // 相对路径,应该要配合解密
"memberList": [
{id: '@xxxx', name:'昵称', alias: '备注名' }
{id: '@xxxx', name:'昵称', alias: '备注名'/** 个人备注名,非群备注名 */ }
]
},
//以下暂不清楚什么用途,如有兴趣,请查阅 wechaty 官网文档
Expand Down
5 changes: 1 addition & 4 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
require('dotenv').config({
path: process.env.homeEnvCfg /** 兼容cli调用 */ ?? './.env'
})
/** log 在 prestart 阶段初始化了,后续需要手动改level才能同步env配置 */
require('./src/utils/index').proxyConsole({
logLevel: process.env.LOG_LEVEL
})
require('./src/utils/index').proxyConsole()
const { PORT } = process.env
const { Hono } = require('hono')
const { serve } = require('@hono/node-server')
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"dotenv": "^16.3.1",
"file-box": "1.4.15",
"form-data": "^4.0.0",
"gerror": "^1.0.16",
"hono": "^3.11.11",
"log4js": "^6.9.1",
"mime": "^3.0.0",
Expand All @@ -70,7 +71,9 @@
},
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]"
}
}
}
3 changes: 3 additions & 0 deletions packages/cli/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ LOG_LEVEL=info
# 如果不希望登录一次后就记住当前账号,想每次都扫码登陆,填 true
DISABLE_AUTO_LOGIN=

# RECVD_MSG_API 是否接收来自自己发的消息
ACCEPT_RECVD_MSG_MYSELF=false

# 如果想自己处理收到消息的逻辑,在下面填上你的API地址, 默认为空
LOCAL_RECVD_MSG_API=

Expand Down
4 changes: 1 addition & 3 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@

### 1. 安装

> 目前使用 pnpm 管理包,以支持临时包修补(patches)和加速依赖安装,如果你还不了解 pnpm,可以先了解 [pnpm](https://pnpm.io/zh/motivation)
```bash
pnpm i wechatbot-webhook -g
npm i wechatbot-webhook -g
```

### 2. 运行 & 扫码
Expand Down
9 changes: 0 additions & 9 deletions packages/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,6 @@ const memoryCardFile = (process.env.homeMemoryCardPath = path.join(
'./loginSession.memory-card.json'
))

console.log(
[
'╔════════════════════════════╗',
'║ wechatbot-webhook ║',
`║ v${version} ║`,
`╚════════════════════════════╝`
].join('\n')
)

program
.name('wechatbot-webhook')
.description(
Expand Down
13 changes: 13 additions & 0 deletions patches/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/dist/cjs/src/puppet-wechat4u.js b/dist/cjs/src/puppet-wechat4u.js
index 68a52e6eb60c6efa0436984ef4399b1cf38d03af..6d1ae5aa166f61c288b66ea9a8e0273777d22687 100644
--- a/dist/cjs/src/puppet-wechat4u.js
+++ b/dist/cjs/src/puppet-wechat4u.js
@@ -353,6 +353,8 @@ class PuppetWechat4u extends PUPPET.Puppet {
if (!this.getContactInterval) {
this.getContactsInfo();
this.getContactInterval = setInterval(() => {
+ //fix: 修复登出了还一直请求
+ this.isLoggedIn &&
this.getContactsInfo();
}, 2000);
}
13 changes: 13 additions & 0 deletions patches/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/dist/cjs/src/mixins/login-mixin.js b/dist/cjs/src/mixins/login-mixin.js
index 01c9a9caea23816ebdd36398bb2cd1f4f0e85559..d273c203e0d41262559cc3c85543485b4affb4ea 100644
--- a/dist/cjs/src/mixins/login-mixin.js
+++ b/dist/cjs/src/mixins/login-mixin.js
@@ -110,6 +110,8 @@ const loginMixin = (mixinBase) => {
this.__currentUserId = undefined;
resolve();
}));
+ // bugfix: 修复wechat4u并未真正登出的问题
+ this.wechat4u?.emit('logout');
}
/**
* @deprecated use `currentUserId` instead. (will be removed in v2.0)
Loading

0 comments on commit 3d9d737

Please sign in to comment.