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.
@@ -1,26 +1,35 @@
1
1
  ---
2
2
  name: herdrchat
3
- description: Set up, run and look after herdrchat, the chat front-end for hc that mirrors every herdr-app tab into a chat app - Feishu (one group per tab) or Telegram (one topic per tab in the bot's private chat), with dialog buttons, an overview and quiet phones - first setup of either app, running both side by side, start and stop, status and logs, /auth, settings, fixing problems, the Feishu developer console and @BotFather. Use for anything about herdrchat or its Feishu or Telegram bot, even when the user only says "set up the Telegram bot", "is it running", "it doesn't post", "mute the workers" or "publish the bot". Trigger with "/herdrchat", "/herdrchat setup", "/herdrchat status", "/herdrchat fix".
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
- to use both, run a profile each (`--profile telegram` beside the default Feishu one).
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 each). Telegram: `/herdrchat telegram setup`. Feishu, in order: `herdrchat init`; make the Feishu app (`references/feishu.md`: create, bot, scopes, events and callbacks); fill `config.env` with the user (app id, secret, `HERDR_SESSIONS`: the hc sessions herdr-app shows on this machine); `herdrchat start`; publish a version; get the user's open_id (they message the bot, it answers with it) into `FEISHU_OWNER_OPEN_ID`; start again. Optional: `/herdrchat auth`. |
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, as its own profile: `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`. |
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, set events and
57
- callbacks, start the bot (`herdrchat start`) and publish. The "Set up" section of `docs/guide.md`
58
- lists the same steps from the repo's side.
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 is `bin/herdrchat.mjs`. It runs in an hc terminal named `herdrchat`, in the first
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
- Below, `S` is the first session in `HERDR_SESSIONS`.
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
- HC_SESSION=S hc get herdrchat --json # state "live"
18
- HC_SESSION=S hc read herdrchat --lines 40 # its terminal: start lines, "[feishu] connected"
19
- herdrchat status # running, folders, /auth, errors today
20
- herdrchat start # restart: stops it in every session, waits until it reaches its chat app
21
- herdrchat install # run it as a service (launchd/systemd): starts at login, back after a crash
22
- launchctl print gui/$(id -u)/app.herdrchat.<profile> # the service on macOS: state, pid, last exit
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 Feishu within 30 s; fix that before anything else.
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` unset | check it runs; the log says "owner not set" |
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. It runs as its **own profile**, beside a
7
- Feishu one; each bot follows the same hc terminals, so an answer in either reaches the
8
- terminal, and a dialog answered in one closes its card in the other.
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. **Topic mode.** It is not in BotFather's `/mybots` → Bot Settings list; it is in
18
- BotFather's mini app (the **Open** button at the bottom left of the BotFather chat):
19
- pick the bot, turn on Threaded Mode / topics. Check it (step 5): `has_topics_enabled`
20
- must be `true`, or no topic can be made.
21
- 3. **The profile's config.** Make `~/.config/herdrchat/telegram/config.env` (folder mode
22
- 700, file 600) with:
23
- ```
24
- HERDRCHAT_CHAT=telegram
25
- TELEGRAM_BOT_TOKEN=
26
- TELEGRAM_OWNER_ID=
27
- HERDR_SESSIONS=<the same sessions as the Feishu profile>
28
- ```
29
- and ask the user to paste the token after `TELEGRAM_BOT_TOKEN=` themselves
30
- (`open -e <file>` opens it), no quotes, no spaces.
31
- 4. **First start, to learn the owner.** `herdrchat start --profile telegram`; the user
32
- messages the bot anything; it answers `TELEGRAM_OWNER_ID=<digits>`. The user puts that
33
- in the config. Until then the bot makes no topic.
34
- 5. **Check, without printing secrets.** In a short `node -e`: read the token from the
35
- config, call `https://api.telegram.org/bot<token>/getMe`, print only `username` and
36
- `has_topics_enabled`; for the owner, print only whether `TELEGRAM_OWNER_ID` is digits.
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 2 not done | turn it on in BotFather's mini app, check `has_topics_enabled`, start again |
77
- | the bot answers `Owner is not set` | `TELEGRAM_OWNER_ID` empty | step 4 |
78
- | `herdrchat start` says it did not reach its chat app | wrong token, or no network | check with getMe (step 5) |
79
- | log: `telegram poll: ... 409` | another copy polls the same token | `herdrchat stop --profile telegram`, find the other one (another machine?), start once |
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 |