herdrchat 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -23
- package/README.zh.md +70 -16
- package/bin/cli.mjs +125 -46
- package/bin/herdrchat.mjs +2 -2
- package/config.env.example +37 -20
- package/docs/architecture.md +13 -10
- package/docs/guide.md +84 -43
- package/lib/chats/contract.mjs +2 -1
- package/lib/chats/feishu/index.mjs +5 -1
- package/lib/chats/telegram/index.mjs +6 -2
- package/lib/core/config.mjs +28 -10
- package/lib/core/engine.mjs +14 -8
- package/lib/core/hc.mjs +57 -1
- package/lib/core/log.mjs +6 -3
- package/lib/core/readers/index.mjs +1 -1
- package/lib/core/service.mjs +1 -0
- package/package.json +3 -2
- package/skills/herdrchat/SKILL.md +16 -8
- package/skills/herdrchat/references/feishu.md +4 -3
- package/skills/herdrchat/references/ops.md +22 -52
- package/skills/herdrchat/references/telegram.md +29 -35
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: herdrchat
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
Set up, run and look after herdrchat, which mirrors every herdr-app (hc) tab into
|
|
5
|
+
Feishu (a group per tab) or Telegram (a topic per tab): first setup of either app,
|
|
6
|
+
start, stop, status, logs, running it as a service, settings, fixing problems, the
|
|
7
|
+
Feishu developer console and @BotFather. Use for anything about herdrchat or its
|
|
8
|
+
Feishu or Telegram bot, even "set up the Telegram bot", "is it running", "it does not
|
|
9
|
+
post" or "mute the workers". Trigger with "/herdrchat", "/herdrchat setup",
|
|
10
|
+
"/herdrchat status", "/herdrchat fix".
|
|
4
11
|
---
|
|
5
12
|
|
|
6
13
|
# herdrchat
|
|
7
14
|
|
|
8
15
|
herdrchat mirrors every herdr-app tab into a chat app: a group per tab in Feishu, a topic
|
|
9
16
|
per tab in the bot's private chat in Telegram; the conversation as it happens, dialogs as
|
|
10
|
-
buttons, an overview in the direct chat. One profile is one chat app (`HERDRCHAT_CHAT`)
|
|
11
|
-
|
|
17
|
+
buttons, an overview in the direct chat. One profile is one chat app (`HERDRCHAT_CHAT`):
|
|
18
|
+
one app uses the default profile; a second app beside it gets its own (`--profile <name>`).
|
|
12
19
|
|
|
13
20
|
Its command is `herdrchat` (`node bin/cli.mjs` in a clone): check with `command -v
|
|
14
21
|
herdrchat`; when it is missing, ask before `npm install -g herdrchat`. A profile
|
|
15
22
|
(`--profile`, default `default`) keeps its settings in
|
|
16
23
|
`~/.config/herdrchat/<profile>/config.env` and its state in
|
|
17
|
-
`~/.local/state/herdrchat/<profile>/`; `herdrchat status` prints both.
|
|
24
|
+
`~/.local/state/herdrchat/<profile>/`; `herdrchat status` prints both. Files named here
|
|
25
|
+
from the package (`config.env.example`, `docs/guide.md`) are in the installed package,
|
|
26
|
+
`$(npm root -g)/herdrchat/`, or in the clone.
|
|
18
27
|
|
|
19
28
|
## Commands
|
|
20
29
|
|
|
21
30
|
| Command | Do |
|
|
22
31
|
|---|---|
|
|
23
|
-
| `/herdrchat setup` | First ask which chat app (Feishu, Telegram, or both: one profile
|
|
32
|
+
| `/herdrchat setup` | First ask which chat app (Feishu, Telegram, or both: the second one on its own profile). Telegram: `/herdrchat telegram setup`. Feishu, in this order: create the app, the bot ability and the scopes (`references/feishu.md`); `herdrchat init` and fill `config.env` with the user (App ID, App Secret, `HERDR_SESSIONS`: `ls ~/.local/state/herdr-core` lists the sessions); `herdrchat start` (the console's long-connection check needs it running); events and callbacks; publish a version; the user messages the bot and adds the `FEISHU_OWNER_OPEN_ID` line it answers with; `herdrchat start` again; offer `/herdrchat auth` and `herdrchat install`. |
|
|
24
33
|
| `/herdrchat status` | `herdrchat status`; explain each line; on errors, `/herdrchat fix`. |
|
|
25
34
|
| `/herdrchat start`, `/herdrchat stop` | Read `config.env` (its `HERDR_SESSIONS`) in one step, then `herdrchat start` / `stop` in the next; never both at once. With a service installed they go through it. |
|
|
26
35
|
| `/herdrchat install`, `/herdrchat uninstall` | Run it as a service of the system (launchd on macOS, systemd on Linux): it starts at login and comes back after a crash, whatever happens to the hc cores. Recommended once it works. Read the config first; after a node upgrade, install again (`herdrchat status` says so). |
|
|
@@ -29,7 +38,7 @@ herdrchat`; when it is missing, ask before `npm install -g herdrchat`. A profile
|
|
|
29
38
|
| `/herdrchat config` | Change a setting in `config.env` with the user (sessions, `HERDR_MUTED_SPACES`, `HERDR_SILENT_SPACES`, `HERDR_BOT_TAGS`, `HERDR_USER_TAGS`, `HERDR_HISTORY`, `HERDRCHAT_CHAT`; each is explained in `config.env.example`), read the file back, then restart. |
|
|
30
39
|
| `/herdrchat fix` | Find the cause from `herdrchat status`, the logs and the live result, then fix it: `references/ops.md`. |
|
|
31
40
|
| `/herdrchat feishu <task>` | Anything in the Feishu developer console: scopes, callbacks, publishing, the icon, deleting an app: `references/feishu.md`. |
|
|
32
|
-
| `/herdrchat telegram <task>` | The Telegram bot
|
|
41
|
+
| `/herdrchat telegram <task>` | The Telegram bot (the default profile when it is the only app): `setup` (@BotFather, topic mode, token, owner id, first start), checking the token, quiet and silent spaces, what Telegram cannot do and what stands in: `references/telegram.md`. |
|
|
33
42
|
|
|
34
43
|
With no subcommand, run `herdrchat status` and suggest the next step from it.
|
|
35
44
|
|
|
@@ -39,8 +48,7 @@ With no subcommand, run `herdrchat status` and suggest the next step from it.
|
|
|
39
48
|
disbanding anything, sending to a real group. One yes covers one action.
|
|
40
49
|
- Never print, screenshot or paste `FEISHU_APP_SECRET`, `TELEGRAM_BOT_TOKEN` or
|
|
41
50
|
`user-token.json`; ask the user to paste a token into `config.env` themselves.
|
|
42
|
-
- A check that decides an action runs on its own first (read the config, then start
|
|
43
|
-
scan, then commit).
|
|
51
|
+
- A check that decides an action runs on its own first (read the config, then start).
|
|
44
52
|
- Say what was checked on the live bot and what was not.
|
|
45
53
|
|
|
46
54
|
## References
|
|
@@ -53,9 +53,10 @@ that applies or publishes something, and read it.
|
|
|
53
53
|
### Create the app (first setup only)
|
|
54
54
|
|
|
55
55
|
Developer console home -> create a custom app (企业自建应用) with a name, a description
|
|
56
|
-
and an icon -> Add capabilities -> Bot. Then import the scopes,
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
and an icon -> Add capabilities -> Bot. Then import the scopes, have the user fill
|
|
57
|
+
`config.env` (`herdrchat init`), start the bot (`herdrchat start`: the long-connection
|
|
58
|
+
check below needs it running), set events and callbacks, and publish. "Set up: Feishu"
|
|
59
|
+
in `docs/guide.md` lists the same steps from the user's side.
|
|
59
60
|
|
|
60
61
|
### Import scopes
|
|
61
62
|
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
# Ops: running and looking after herdrchat
|
|
2
2
|
|
|
3
|
-
The bot
|
|
4
|
-
hc session listed in `HERDR_SESSIONS`; `herdrchat start` (re)starts it and keeps it
|
|
5
|
-
running (`node bin/cli.mjs` from a clone). A profile (`--profile` or `HERDRCHAT_PROFILE`,
|
|
6
|
-
default `default`; another one runs as the hc terminal `herdrchat-<profile>`) has its
|
|
7
|
-
settings in `~/.config/herdrchat/<profile>/config.env` and writes to
|
|
8
|
-
`~/.local/state/herdrchat/<profile>/` (call it `D` below), unless `HERDRCHAT_HOME` holds
|
|
9
|
-
both (`config.env`, `state/`). Its settings in Feishu itself (scopes, callbacks, icon,
|
|
10
|
-
versions) are in `references/feishu.md`.
|
|
3
|
+
The bot (`bin/herdrchat.mjs` in the installed package) runs one of two ways:
|
|
11
4
|
|
|
12
|
-
|
|
5
|
+
- as a **service** of the system, after `herdrchat install` (launchd on macOS, systemd on
|
|
6
|
+
Linux): it starts at login and comes back after a crash; recommended;
|
|
7
|
+
- in an **hc terminal** named `herdrchat` (`herdrchat-<profile>` for another profile), in
|
|
8
|
+
the first session of `HERDR_SESSIONS`, after `herdrchat start` without a service.
|
|
9
|
+
|
|
10
|
+
`herdrchat status` says which, and where the profile's files are: settings in
|
|
11
|
+
`~/.config/herdrchat/<profile>/config.env`, state and logs in
|
|
12
|
+
`~/.local/state/herdrchat/<profile>/` (call it `D` below). The app's own settings (Feishu
|
|
13
|
+
scopes, callbacks; the Telegram bot's topic mode) are in `references/feishu.md` and
|
|
14
|
+
`references/telegram.md`.
|
|
13
15
|
|
|
14
16
|
## Is it running
|
|
15
17
|
|
|
16
18
|
```sh
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
herdrchat
|
|
20
|
-
herdrchat
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
herdrchat status # how it runs, sessions, keys set or missing, errors today
|
|
20
|
+
herdrchat logs --errors # what went wrong today ("[feishu] connected" / "[telegram] connected as @…" when in)
|
|
21
|
+
herdrchat start # restart: stops it everywhere, waits up to a minute until it is in
|
|
22
|
+
herdrchat install # make it a service: starts at login, back after a crash
|
|
23
|
+
launchctl print gui/$(id -u)/app.herdrchat.<profile> # macOS: the service's state, pid, last exit
|
|
24
|
+
systemctl --user status herdrchat-<profile> # Linux: the same
|
|
23
25
|
```
|
|
24
26
|
|
|
25
27
|
A restart is needed after any code or `config.env` change. It is safe: what was posted
|
|
@@ -28,7 +30,7 @@ is in `D/state.json`, so it picks up where it stopped.
|
|
|
28
30
|
While the bot is down the user hears nothing, so:
|
|
29
31
|
|
|
30
32
|
- Never end with the bot down: `herdrchat start` exits 1 with its errors when the bot
|
|
31
|
-
does not reach
|
|
33
|
+
does not reach its chat app within 60 s; fix that before anything else.
|
|
32
34
|
- Never stop or restart the hc core (`hc server stop|restart`) of the session the bot
|
|
33
35
|
runs in without saying so first, and run `herdrchat start` right after.
|
|
34
36
|
- Never start an hc core from an agent's shell: the core passes that shell's variables
|
|
@@ -73,49 +75,17 @@ grep -h ' <- \| -> ' D/logs/$(date -u +%F).log | tail # posts out, your messag
|
|
|
73
75
|
Read it with a short `node -e` and print only what you need. `D/user-token.json` is
|
|
74
76
|
your token after `/auth`: never print it.
|
|
75
77
|
|
|
76
|
-
## Did the change take effect
|
|
77
|
-
|
|
78
|
-
Check the live result, not only the code: count what actually happened in Feishu with
|
|
79
|
-
the bot's own client (`lib/chats/feishu/client.mjs` `createClient` with `loadConfig()`), for example:
|
|
80
|
-
|
|
81
|
-
- mentions in a group since a time: `im.v1.message.list` on the chat, then each item's
|
|
82
|
-
`mentions` (a mention inside a card is not counted by Feishu, so it does not ring);
|
|
83
|
-
- a group's bot tags: `im.v2.bizEntityTagRelation.get` with `tag_biz_type: 'chat'`;
|
|
84
|
-
- whether a card was edited: `im.v1.message.get`, compare `update_time` with `create_time`.
|
|
85
|
-
|
|
86
|
-
Say which checks were run and which were not; "the code is there" is not "it works".
|
|
87
|
-
|
|
88
78
|
## Usual problems
|
|
89
79
|
|
|
90
80
|
| You see | Likely cause | Do |
|
|
91
81
|
|---|---|---|
|
|
92
|
-
| nothing posts | bot down, or `FEISHU_OWNER_OPEN_ID`
|
|
82
|
+
| nothing posts | bot down, or the owner not set (`FEISHU_OWNER_OPEN_ID`, `TELEGRAM_OWNER_ID`) | `herdrchat status`; the log says "owner not set" |
|
|
83
|
+
| Telegram: no topic appears | topic mode off | log: "topic mode is off"; BotFather's mini app, the bot, Threaded Mode, then start again |
|
|
84
|
+
| Telegram: `telegram poll: ... 409` | another copy polls the same token | stop it (another machine?), then start once |
|
|
93
85
|
| a button gives error 200340 | the card callback is not set up | `references/feishu.md`: events and card callbacks |
|
|
94
86
|
| a dialog had no card | answered in the terminal before the card; or no numbered menu on screen | log: `blocked`; the card says `/answer` when it saw no menu |
|
|
95
87
|
| the phone rings too much | Feishu: not `/auth`ed; either app: settings | Feishu `/auth`; `HERDR_MUTED_SPACES` (quiet but for needs you and done), `HERDR_SILENT_SPACES` (nothing rings), per profile |
|
|
96
88
|
| a ⚠️ warning in the direct chat about acting as you | the token could not be refreshed | send `/auth` again |
|
|
97
89
|
| a group keeps an old name | its terminal is not live | it renames when the terminal is back |
|
|
98
90
|
| a Feishu call fails with 400 in a burst | a rate limit (tags: 5 a second) | space the calls; the bot queues tag calls |
|
|
99
|
-
|
|
100
|
-
## Trying a Feishu API safely
|
|
101
|
-
|
|
102
|
-
1. Read the official doc first (open.feishu.cn); write down the scope and limits.
|
|
103
|
-
2. Make real calls only with this repo's own code (the SDK or `fetch`), never through a
|
|
104
|
-
third-party tool; reading another tool's docs or a dry run to learn a path is fine.
|
|
105
|
-
3. Test in a throwaway group the bot creates for it (`zz-test ...`), never in a
|
|
106
|
-
terminal's group; label each test message ("Test 2/3: ...") so the user can tell
|
|
107
|
-
which one rang.
|
|
108
|
-
4. Measure the result (an API field, a read-back) instead of assuming it; ask the user
|
|
109
|
-
only what only a phone shows (did it ring).
|
|
110
|
-
5. Clean up in the same run: disband the test group, delete test labels and tags you
|
|
111
|
-
made, recall test messages, delete scratch files.
|
|
112
|
-
|
|
113
|
-
## Before a commit
|
|
114
|
-
|
|
115
|
-
1. `npm test` passes.
|
|
116
|
-
2. Stage, then, as its own step, scan the staged files for anything real: session and
|
|
117
|
-
machine names, the app id (`cli_`), open_ids (`ou_`), chat ids (`oc_`), message ids
|
|
118
|
-
(`om_`), label ids (`ofg_`), the tenant's name, people's names, local paths. Read the
|
|
119
|
-
result before committing; never chain the scan and the commit in one command.
|
|
120
|
-
3. Show the commit message (Conventional Commits; the body says why) and commit only
|
|
121
|
-
after the user's yes. No push without its own yes.
|
|
91
|
+
| `herdrchat start` says it did not reach its chat app | wrong keys, or no network | `herdrchat logs --errors`; check the keys in `config.env` |
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
A Telegram bot cannot make groups (the Bot API has no such method), so herdrchat puts each
|
|
4
4
|
herdr-app tab in a **topic** of your private chat with the bot: each has its own name,
|
|
5
5
|
icon color (one per space), unread count, and can be muted on its own. The chat's main
|
|
6
|
-
thread holds the overview and the commands.
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
thread holds the overview and the commands. When Telegram is the only chat app, it uses
|
|
7
|
+
the default profile; beside a Feishu bot it gets its own (`--profile telegram`), and both
|
|
8
|
+
follow the same hc terminals, so an answer in either reaches the terminal and a dialog
|
|
9
|
+
answered in one closes its card in the other. Below, `P` is ` --profile <name>` when it
|
|
10
|
+
has its own profile, else nothing.
|
|
9
11
|
|
|
10
12
|
## Setup (`/herdrchat telegram setup`)
|
|
11
13
|
|
|
@@ -14,34 +16,26 @@ Do these in order; the user does the Telegram steps, you check each one.
|
|
|
14
16
|
1. **The bot.** The user messages **@BotFather**: `/newbot`, a name, a username ending in
|
|
15
17
|
`bot`. BotFather answers with a token. The user keeps it: never ask them to paste it
|
|
16
18
|
into the chat.
|
|
17
|
-
2. **
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
3. **
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
`
|
|
37
|
-
6. **Start again.** Read the config (secrets hidden) in one step, then
|
|
38
|
-
`herdrchat start --profile telegram` in the next. One topic per tab appears; Telegram
|
|
39
|
-
takes about one message a second in a chat, so twenty tabs take twenty seconds. A new
|
|
40
|
-
topic gets the conversation before it (`HERDR_HISTORY`); `/history` in a topic posts it
|
|
41
|
-
again.
|
|
42
|
-
7. **Make it a service.** Once it works: `herdrchat install --profile telegram`. It then
|
|
43
|
-
starts at login and comes back by itself after a crash, whatever happens to the hc
|
|
44
|
-
cores; `herdrchat status --profile telegram` says it runs as the service.
|
|
19
|
+
2. **The config.** `herdrchat init --chat telegram P` makes the profile's `config.env`
|
|
20
|
+
(private) and prints where it is. Ask the user to paste the token after
|
|
21
|
+
`TELEGRAM_BOT_TOKEN=` themselves (`open -e <file>` opens it), no quotes, no spaces, and
|
|
22
|
+
fill `HERDR_SESSIONS` with them (`ls ~/.local/state/herdr-core` lists the sessions).
|
|
23
|
+
3. **Topic mode, checked before the first start.** It is not in BotFather's `/mybots` →
|
|
24
|
+
Bot Settings list; it is in BotFather's mini app (the **Open** button at the bottom
|
|
25
|
+
left of the BotFather chat): pick the bot, turn on Threaded Mode. Check it without
|
|
26
|
+
printing the token: a short `node -e` reads the token from the config, calls
|
|
27
|
+
`https://api.telegram.org/bot<token>/getMe` and prints only `username` and
|
|
28
|
+
`has_topics_enabled`, which must be `true`.
|
|
29
|
+
4. **First start, to learn the owner.** `herdrchat start P`; the user messages the bot
|
|
30
|
+
anything; it answers with the line to add, `TELEGRAM_OWNER_ID=<digits>`, and where the
|
|
31
|
+
file is. The user adds it. Until then the bot makes no topic.
|
|
32
|
+
5. **Start again.** Read the config (secrets hidden) in one step, then
|
|
33
|
+
`herdrchat start P` in the next. One topic per tab appears; Telegram takes about one
|
|
34
|
+
message a second in a chat, so twenty tabs take twenty seconds. A new topic gets the
|
|
35
|
+
conversation before it (`HERDR_HISTORY`); `/history` in a topic posts it again.
|
|
36
|
+
6. **Make it a service.** Once it works: `herdrchat install P`. It then starts at login
|
|
37
|
+
and comes back by itself after a crash, whatever happens to the hc cores;
|
|
38
|
+
`herdrchat status P` says it runs as the service.
|
|
45
39
|
|
|
46
40
|
## What rings
|
|
47
41
|
|
|
@@ -73,9 +67,9 @@ without muting each topic by hand.
|
|
|
73
67
|
|
|
74
68
|
| Seen | Cause | Do |
|
|
75
69
|
|---|---|---|
|
|
76
|
-
| log: `topic mode is off for @<bot>` | step
|
|
77
|
-
| the bot answers
|
|
78
|
-
| `herdrchat start` says it did not reach its chat app | wrong token, or no network | check with getMe (step
|
|
79
|
-
| log: `telegram poll: ... 409` | another copy polls the same token | `herdrchat stop
|
|
70
|
+
| log: `topic mode is off for @<bot>` | step 3 not done | turn it on in BotFather's mini app, check `has_topics_enabled`, start again |
|
|
71
|
+
| the bot answers "To make you this bot's owner…" | `TELEGRAM_OWNER_ID` empty | step 4 |
|
|
72
|
+
| `herdrchat start` says it did not reach its chat app | wrong token, or no network | check with getMe (step 3) |
|
|
73
|
+
| log: `telegram poll: ... 409` | another copy polls the same token | `herdrchat stop P`, find the other one (another machine?), start once |
|
|
80
74
|
| log: `too fast, waiting N s` | Telegram's flood limit; the bot waits as told | nothing; it catches up |
|
|
81
75
|
| a click answers "This dialog is gone" | the card is older than the last 300 dialog cards | answer the newest card, or in the terminal |
|