@mercury-fw/channel-google-chat 0.1.2 → 0.2.0
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/CHANGELOG.md +19 -0
- package/README.md +43 -6
- package/dist/index.d.ts +1 -1
- package/google-chat-provider.ts +5 -2
- package/index.ts +4 -2
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @mercury-fw/channel-google-chat
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8bed46b: - A turn carries a `Principal` (the person behind it and the provider that vouched for them) instead of the opaque `userId` and `wikiUserId`; the core derives every per-person id from it.
|
|
8
|
+
- Episodic memory follows the principal, not the channel: a session is captured whenever a provider vouched for the person. Google Chat keeps the ids it had; the terminal and the HTTP channel (until it authenticates its callers) send a principal nobody vouched for, so they stay out of episodic memory as before.
|
|
9
|
+
- The HTTP channel accepts a `conversationId` on `/turn` and `/confirm` only made of letters, digits, `-` and `_`, up to 128 characters once trimmed, and answers `400` otherwise: a client-chosen id can no longer reach another user's wiki notes, forge log lines or break the turn. An existing HTTP conversation whose id has other characters can still be read with `/conversation`, but not continued. `/conversation` keeps opening any session key `/conversations` lists, whatever channel it came from.
|
|
10
|
+
- The model's wiki read tools refuse a per-user id that isn't one path segment, as writes already did.
|
|
11
|
+
- `CHANNEL_API_VERSION` is 2: a channel written for version 1 is refused at load.
|
|
12
|
+
- The first-party channels declare their channel api version as a literal, so an older channel can't claim a newer contract it doesn't implement.
|
|
13
|
+
|
|
14
|
+
## 0.1.3
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 5e09c69: - README: a section on connecting a new app to a Chat app that already exists (finding the service account and the subscription, creating a key, `mfw google-chat set-key`).
|
|
19
|
+
- README: how to list and delete the keys the old instances left behind, before the service account reaches its limit of 10.
|
|
20
|
+
- README: `--project` on the `keys create` command of the setup.
|
|
21
|
+
|
|
3
22
|
## 0.1.2
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -35,6 +35,7 @@ channels: [googleChatChannel],
|
|
|
35
35
|
- [6. Configure the consent screen (Cloud Console)](#6-configure-the-consent-screen-cloud-console)
|
|
36
36
|
- [7. Configure the Chat app (Cloud Console)](#7-configure-the-chat-app-cloud-console)
|
|
37
37
|
- [8. Start and try it](#8-start-and-try-it)
|
|
38
|
+
- [Connecting an app to an existing Chat app](#connecting-an-app-to-an-existing-chat-app)
|
|
38
39
|
- [When the subscription disappears](#when-the-subscription-disappears)
|
|
39
40
|
|
|
40
41
|
## Setting up the Chat app
|
|
@@ -45,7 +46,7 @@ Everything goes through `gcloud` except two pages of Cloud Console (steps 6 and
|
|
|
45
46
|
|
|
46
47
|
- a Google Workspace Business or Enterprise account: Chat apps don't exist for personal Gmail accounts;
|
|
47
48
|
- `gcloud` logged in with that account (`gcloud auth login <you@company.com>`), allowed to create projects and link a billing account;
|
|
48
|
-
- the app with its dependencies installed (`bun install`), for `
|
|
49
|
+
- the app with its dependencies installed (`bun install`), for `mfw` in step 5.
|
|
49
50
|
|
|
50
51
|
### 1. Name things
|
|
51
52
|
|
|
@@ -100,7 +101,7 @@ gcloud pubsub subscriptions add-iam-policy-binding "$SUBSCRIPTION" \
|
|
|
100
101
|
--project="$PROJECT_ID" \
|
|
101
102
|
--member="serviceAccount:${SA_EMAIL}" \
|
|
102
103
|
--role="roles/pubsub.subscriber"
|
|
103
|
-
gcloud iam service-accounts keys create key.json --iam-account="$SA_EMAIL"
|
|
104
|
+
gcloud iam service-accounts keys create key.json --iam-account="$SA_EMAIL" --project="$PROJECT_ID"
|
|
104
105
|
```
|
|
105
106
|
|
|
106
107
|
A service account takes a few seconds to become visible to the rest of Google Cloud: if the binding fails saying the account doesn't exist, wait a moment and run it again.
|
|
@@ -108,7 +109,7 @@ A service account takes a few seconds to become visible to the rest of Google Cl
|
|
|
108
109
|
Then, from the app's folder, write the key and the subscription into its `.env` with the app's own CLI, and delete the key file. The command replaces the lines `mfw create` left empty (or an older key), puts the private key on one line the way the channel reads it, and never prints it:
|
|
109
110
|
|
|
110
111
|
```bash
|
|
111
|
-
|
|
112
|
+
mfw google-chat set-key key.json --subscription "projects/${PROJECT_ID}/subscriptions/${SUBSCRIPTION}"
|
|
112
113
|
rm key.json
|
|
113
114
|
```
|
|
114
115
|
|
|
@@ -139,14 +140,50 @@ Click **Save**. The field names here come from Google's own Pub/Sub quickstart;
|
|
|
139
140
|
|
|
140
141
|
### 8. Start and try it
|
|
141
142
|
|
|
142
|
-
Start the app (`
|
|
143
|
+
Start the app (`mfw start`) and check that the channel came up without errors:
|
|
143
144
|
|
|
144
145
|
```bash
|
|
145
|
-
|
|
146
|
+
mfw logs mercury
|
|
146
147
|
```
|
|
147
148
|
|
|
148
149
|
`[channel] google-chat started` with no `pubsub stream error` after it means Mercury is pulling from the subscription. Then, in Google Chat, start a new chat and search the app's name (it shows up only for the people and groups in **Visibility**), or add it to a space; write to it and it answers.
|
|
149
150
|
|
|
151
|
+
## Connecting an app to an existing Chat app
|
|
152
|
+
|
|
153
|
+
When the Chat app is already set up and the Mercury instance behind it changes (the app scaffolded again, or moved to another machine), the new app only needs a key of the service account and the subscription's name in its `.env`. It replaces the old instance, it doesn't run next to it: stop the old one first, two instances on one subscription split the conversations between them.
|
|
154
|
+
|
|
155
|
+
If you don't have the project's id at hand, `gcloud projects list` shows it; then the service account and the subscription:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
PROJECT_ID=<the project's id>
|
|
159
|
+
gcloud iam service-accounts list --project="$PROJECT_ID"
|
|
160
|
+
gcloud pubsub subscriptions list --project="$PROJECT_ID" --format="value(name)"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
SA_EMAIL=<the EMAIL column of the service account Mercury runs as>
|
|
165
|
+
SUBSCRIPTION=<the part after subscriptions/>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Then, from the new app's folder, create a key, write it into the `.env` with the subscription, and delete the key file:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
gcloud iam service-accounts keys create key.json --iam-account="$SA_EMAIL" --project="$PROJECT_ID"
|
|
172
|
+
mfw google-chat set-key key.json --subscription "projects/${PROJECT_ID}/subscriptions/${SUBSCRIPTION}"
|
|
173
|
+
rm key.json
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The old instance's key stays valid until you delete it, and a service account holds at most 10 keys, after which `keys create` fails. List them and delete the ones no instance uses anymore:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
gcloud iam service-accounts keys list --iam-account="$SA_EMAIL" --project="$PROJECT_ID" --managed-by=user
|
|
180
|
+
gcloud iam service-accounts keys delete <KEY_ID> --iam-account="$SA_EMAIL" --project="$PROJECT_ID"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The key the new app uses is the one with the latest `CREATED_AT`.
|
|
184
|
+
|
|
185
|
+
Start it and check it as in [step 8](#8-start-and-try-it).
|
|
186
|
+
|
|
150
187
|
## When the subscription disappears
|
|
151
188
|
|
|
152
189
|
A subscription created before `--expiration-period=never` was in step 4 still has the default policy, and Pub/Sub deletes it after 31 days without a pull. The channel then logs `NOT_FOUND` on the subscription, while the topic, the service account and the Chat app's configuration are all still there.
|
|
@@ -177,7 +214,7 @@ gcloud pubsub subscriptions add-iam-policy-binding "$SUBSCRIPTION" \
|
|
|
177
214
|
--role="roles/pubsub.subscriber"
|
|
178
215
|
```
|
|
179
216
|
|
|
180
|
-
Then restart the app (`
|
|
217
|
+
Then restart the app (`mfw restart`). The messages sent while the subscription was missing are lost, though: Pub/Sub keeps messages only for a subscription that exists.
|
|
181
218
|
|
|
182
219
|
If the topic is gone too, redo steps 3 to 5 and, in step 7, paste the new topic in **Connection settings**.
|
|
183
220
|
|
package/dist/index.d.ts
CHANGED
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
* missing is a misconfiguration: `build()` throws and the loader skips this
|
|
8
8
|
* channel fail-soft, leaving the rest of Mercury up.
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
10
|
+
import type { ChannelPlugin } from "@mercury-fw/channel-types";
|
|
11
11
|
export declare const googleChatChannel: ChannelPlugin;
|
package/google-chat-provider.ts
CHANGED
|
@@ -505,8 +505,11 @@ export function createGoogleChatProvider(deps: GoogleChatProviderDeps): GoogleCh
|
|
|
505
505
|
multiUser: !event.isDirectMessage,
|
|
506
506
|
text: markedInput,
|
|
507
507
|
sessionKey,
|
|
508
|
-
|
|
509
|
-
|
|
508
|
+
principal: {
|
|
509
|
+
id: event.sender,
|
|
510
|
+
provider: "google-chat",
|
|
511
|
+
...(event.senderDisplayName ? { displayName: event.senderDisplayName } : {}),
|
|
512
|
+
},
|
|
510
513
|
logPrefix: `[chat:${event.space}:${event.sender}] `,
|
|
511
514
|
},
|
|
512
515
|
sink,
|
package/index.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* missing is a misconfiguration: `build()` throws and the loader skips this
|
|
8
8
|
* channel fail-soft, leaving the rest of Mercury up.
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
10
|
+
import type { ChannelPlugin, ChannelRuntimeContext } from "@mercury-fw/channel-types";
|
|
11
11
|
import { createGoogleChatProvider } from "./google-chat-provider.ts";
|
|
12
12
|
|
|
13
13
|
/** Reads a required env var, failing loudly (caught by the channel loader) instead of silently degrading. */
|
|
@@ -20,7 +20,9 @@ function require(env: ChannelRuntimeContext["env"], name: string): string {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const googleChatChannel: ChannelPlugin = {
|
|
23
|
-
|
|
23
|
+
// The contract this channel is written for, as a literal: importing
|
|
24
|
+
// CHANNEL_API_VERSION would report whichever contract is installed.
|
|
25
|
+
apiVersion: 2,
|
|
24
26
|
name: "google-chat",
|
|
25
27
|
build: (ctx) => {
|
|
26
28
|
// No subscription configured ⇒ this instance simply doesn't run Google Chat.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mercury-fw/channel-google-chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"@google-cloud/pubsub": "^5.3.1"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@mercury-fw/channel-types": ">=0.
|
|
34
|
+
"@mercury-fw/channel-types": ">=0.34.0 <1.0.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@mercury-fw/channel-types": "0.
|
|
37
|
+
"@mercury-fw/channel-types": "0.34.0",
|
|
38
38
|
"@mercury-fw/typescript-config": "*",
|
|
39
|
-
"@types/bun": "^1.4.
|
|
39
|
+
"@types/bun": "^1.4.2",
|
|
40
40
|
"typescript": "^6.0.3"
|
|
41
41
|
}
|
|
42
42
|
}
|