@mercury-fw/channel-google-chat 0.1.0 → 0.1.1
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 +8 -0
- package/README.md +163 -2
- package/package.json +2 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# @mercury-fw/channel-google-chat
|
|
2
|
+
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 51bd439: `mfw google-chat set-key <key-file> [--subscription <name>]` writes the Google Chat channel's service account key (and its subscription) into the app's env file, the key on one line the way the channel reads it and never printed. The channel's setup uses it in place of the hand-written `sed`/`printf` step.
|
|
8
|
+
- de8b1e7: The README walks through setting up the Chat app step by step (gcloud wherever it can, the two Cloud Console pages field by field) and creates the Pub/Sub subscription with no expiration. A new section covers a subscription Pub/Sub deleted after 31 idle days: how to recreate it and give the service account its role back.
|
package/README.md
CHANGED
|
@@ -16,8 +16,169 @@ channels: [googleChatChannel],
|
|
|
16
16
|
|---|---|
|
|
17
17
|
| `GOOGLE_CHAT_PUBSUB_SUBSCRIPTION` | `projects/<project>/subscriptions/<subscription>` the Chat app's events arrive on. Empty leaves the channel inert. |
|
|
18
18
|
| `GOOGLE_CHAT_APP_CLIENT_EMAIL` | The service account the app authenticates as. |
|
|
19
|
-
| `GOOGLE_CHAT_APP_PRIVATE_KEY` | That service account's private key. |
|
|
19
|
+
| `GOOGLE_CHAT_APP_PRIVATE_KEY` | That service account's private key, on one line with literal `\n` (step 5 writes it that way). |
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
## Table of contents
|
|
22
|
+
|
|
23
|
+
- [Setting up the Chat app](#setting-up-the-chat-app)
|
|
24
|
+
- [1. Name things](#1-name-things)
|
|
25
|
+
- [2. Create the project](#2-create-the-project)
|
|
26
|
+
- [3. Create the topic, and let Google Chat publish on it](#3-create-the-topic-and-let-google-chat-publish-on-it)
|
|
27
|
+
- [4. Create the subscription](#4-create-the-subscription)
|
|
28
|
+
- [5. Create the service account and its key](#5-create-the-service-account-and-its-key)
|
|
29
|
+
- [6. Configure the consent screen (Cloud Console)](#6-configure-the-consent-screen-cloud-console)
|
|
30
|
+
- [7. Configure the Chat app (Cloud Console)](#7-configure-the-chat-app-cloud-console)
|
|
31
|
+
- [8. Start and try it](#8-start-and-try-it)
|
|
32
|
+
- [When the subscription disappears](#when-the-subscription-disappears)
|
|
33
|
+
|
|
34
|
+
## Setting up the Chat app
|
|
35
|
+
|
|
36
|
+
Each Mercury instance needs a Chat app of its own: its own Google Cloud project, Pub/Sub topic, subscription and service account. Two instances on one subscription either both answer or split a conversation between them, each with no memory of the other's half.
|
|
37
|
+
|
|
38
|
+
Everything goes through `gcloud` except two pages of Cloud Console (steps 6 and 7), which have no command or API. You need:
|
|
39
|
+
|
|
40
|
+
- a Google Workspace Business or Enterprise account: Chat apps don't exist for personal Gmail accounts;
|
|
41
|
+
- `gcloud` logged in with that account (`gcloud auth login <you@company.com>`), allowed to create projects and link a billing account;
|
|
42
|
+
- the app with its dependencies installed (`bun install`), for `bunx mfw` in step 5.
|
|
43
|
+
|
|
44
|
+
### 1. Name things
|
|
45
|
+
|
|
46
|
+
Every command below reads these variables, so set them once in the shell you'll run the steps from:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
PROJECT_ID=<a new project id, globally unique>
|
|
50
|
+
BILLING_ACCOUNT_ID=<from: gcloud billing accounts list>
|
|
51
|
+
TOPIC=mercury-chat-events
|
|
52
|
+
SUBSCRIPTION=mercury-chat-sub
|
|
53
|
+
SA_NAME=mercury-bot
|
|
54
|
+
SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 2. Create the project
|
|
58
|
+
|
|
59
|
+
Pub/Sub needs billing on the project even when its usage stays inside the free tier.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
gcloud projects create "$PROJECT_ID" --name="Mercury"
|
|
63
|
+
gcloud billing projects link "$PROJECT_ID" --billing-account="$BILLING_ACCOUNT_ID"
|
|
64
|
+
gcloud services enable chat.googleapis.com pubsub.googleapis.com iam.googleapis.com --project="$PROJECT_ID"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 3. Create the topic, and let Google Chat publish on it
|
|
68
|
+
|
|
69
|
+
Google Chat delivers the app's events by publishing them on this topic as its own service account, `chat-api-push@system.gserviceaccount.com`, which needs the publisher role there.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
gcloud pubsub topics create "$TOPIC" --project="$PROJECT_ID"
|
|
73
|
+
gcloud pubsub topics add-iam-policy-binding "$TOPIC" \
|
|
74
|
+
--project="$PROJECT_ID" \
|
|
75
|
+
--member="serviceAccount:chat-api-push@system.gserviceaccount.com" \
|
|
76
|
+
--role="roles/pubsub.publisher"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 4. Create the subscription
|
|
80
|
+
|
|
81
|
+
`--expiration-period=never` matters: by default Pub/Sub deletes a subscription nobody has pulled from in 31 days, so an instance that stays off for a month would come back to a `NOT_FOUND` (see [When the subscription disappears](#when-the-subscription-disappears)).
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
gcloud pubsub subscriptions create "$SUBSCRIPTION" --topic="$TOPIC" --expiration-period=never --project="$PROJECT_ID"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 5. Create the service account and its key
|
|
88
|
+
|
|
89
|
+
The service account is who Mercury runs as: it reads the subscription and posts to Chat. It needs the subscriber role on the subscription and nothing on the project.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
gcloud iam service-accounts create "$SA_NAME" --project="$PROJECT_ID" --display-name="Mercury bot"
|
|
93
|
+
gcloud pubsub subscriptions add-iam-policy-binding "$SUBSCRIPTION" \
|
|
94
|
+
--project="$PROJECT_ID" \
|
|
95
|
+
--member="serviceAccount:${SA_EMAIL}" \
|
|
96
|
+
--role="roles/pubsub.subscriber"
|
|
97
|
+
gcloud iam service-accounts keys create key.json --iam-account="$SA_EMAIL"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
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.
|
|
101
|
+
|
|
102
|
+
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:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
bunx mfw google-chat set-key key.json --subscription "projects/${PROJECT_ID}/subscriptions/${SUBSCRIPTION}"
|
|
106
|
+
rm key.json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 6. Configure the consent screen (Cloud Console)
|
|
110
|
+
|
|
111
|
+
Open [Google Auth Platform → Branding](https://console.cloud.google.com/auth/branding) with the project selected (the project picker is at the top of the page), click **Get Started**, then:
|
|
112
|
+
|
|
113
|
+
1. **App name**: what users see, e.g. `Mercury`. **User support email**: your address. Click **Next**.
|
|
114
|
+
2. **Audience**: pick **Internal**. Click **Next**.
|
|
115
|
+
3. **Contact Information**: your address. Click **Next**.
|
|
116
|
+
4. Check **I agree to the Google API Services: User Data Policy**, click **Continue**, then **Create**.
|
|
117
|
+
|
|
118
|
+
No scopes to add: an internal app doesn't list them.
|
|
119
|
+
|
|
120
|
+
### 7. Configure the Chat app (Cloud Console)
|
|
121
|
+
|
|
122
|
+
Open the Chat API's configuration page for the project, `https://console.developers.google.com/apis/api/chat.googleapis.com/hangouts-chat?project=<PROJECT_ID>` (or **APIs & Services → Enabled APIs & Services → Google Chat API → Configuration**), and set:
|
|
123
|
+
|
|
124
|
+
1. **Build this Chat app as a Google Workspace add-on**: unchecked (confirm in the dialog if it asks).
|
|
125
|
+
2. **App name**: the name users search for in Chat (up to 25 characters). **Avatar URL**: an HTTPS link to a square image. **Description**: one line (up to 40 characters).
|
|
126
|
+
3. **Interactive features**: enabled. Without them nobody can write to the app or click its confirmation buttons.
|
|
127
|
+
4. **Functionality**: check **Join spaces and group conversations**.
|
|
128
|
+
5. **Connection settings**: pick **Cloud Pub/Sub** and paste the topic's full name, `projects/<PROJECT_ID>/topics/<TOPIC>`.
|
|
129
|
+
6. **Visibility**: check **Make this Google Chat app available to specific people and groups in <your domain>** and enter who can use it (people or a group).
|
|
130
|
+
7. **Logs**: check **Log errors to Logging**, so a delivery error from Chat shows up in the project's logs.
|
|
131
|
+
|
|
132
|
+
Click **Save**. The field names here come from Google's own Pub/Sub quickstart; Console moves things around now and then, so trust the meaning over the exact position.
|
|
133
|
+
|
|
134
|
+
### 8. Start and try it
|
|
135
|
+
|
|
136
|
+
Start the app (`bunx mfw start`) and check that the channel came up without errors:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
bunx mfw logs mercury
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`[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.
|
|
143
|
+
|
|
144
|
+
## When the subscription disappears
|
|
145
|
+
|
|
146
|
+
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.
|
|
147
|
+
|
|
148
|
+
Set the variables again first, taking them from the app's `.env`: `GOOGLE_CHAT_PUBSUB_SUBSCRIPTION` is `projects/<PROJECT_ID>/subscriptions/<SUBSCRIPTION>`, and `SA_EMAIL` is `GOOGLE_CHAT_APP_CLIENT_EMAIL`. The topic isn't written anywhere in the app: `gcloud pubsub topics list --project="$PROJECT_ID"` shows it (a project made with these steps has only that one).
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
PROJECT_ID=<the part after projects/>
|
|
152
|
+
SUBSCRIPTION=<the part after subscriptions/>
|
|
153
|
+
SA_EMAIL=<GOOGLE_CHAT_APP_CLIENT_EMAIL>
|
|
154
|
+
TOPIC=<the last part of the name the topics list prints>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
To tell which piece is missing:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
gcloud pubsub topics list --project="$PROJECT_ID"
|
|
161
|
+
gcloud pubsub subscriptions list --project="$PROJECT_ID"
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
If only the subscription is gone, recreate it on the same topic and with the same name, so `GOOGLE_CHAT_PUBSUB_SUBSCRIPTION` doesn't change, then give the service account its subscriber role back (it went away with the subscription):
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
gcloud pubsub subscriptions create "$SUBSCRIPTION" --topic="$TOPIC" --expiration-period=never --project="$PROJECT_ID"
|
|
168
|
+
gcloud pubsub subscriptions add-iam-policy-binding "$SUBSCRIPTION" \
|
|
169
|
+
--project="$PROJECT_ID" \
|
|
170
|
+
--member="serviceAccount:${SA_EMAIL}" \
|
|
171
|
+
--role="roles/pubsub.subscriber"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Then restart the app (`bunx mfw restart`). The messages sent while the subscription was missing are lost, though: Pub/Sub keeps messages only for a subscription that exists.
|
|
175
|
+
|
|
176
|
+
If the topic is gone too, redo steps 3 to 5 and, in step 7, paste the new topic in **Connection settings**.
|
|
177
|
+
|
|
178
|
+
To keep a subscription that's still there from expiring:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
gcloud pubsub subscriptions update "$SUBSCRIPTION" --expiration-period=never --project="$PROJECT_ID"
|
|
182
|
+
```
|
|
22
183
|
|
|
23
184
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mercury-fw/channel-google-chat",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@mercury-fw/channel-types": ">=0.24.0 <1.0.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@mercury-fw/channel-types": "0.
|
|
37
|
+
"@mercury-fw/channel-types": "0.28.0",
|
|
38
38
|
"@mercury-fw/typescript-config": "*",
|
|
39
39
|
"@types/bun": "^1.4.0",
|
|
40
40
|
"typescript": "^6.0.3"
|