@symerian/symi 2.7.8 → 2.7.10
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/dist/{acp-cli-DV6gYjcL.js → acp-cli-DwKj-AqM.js} +1 -1
- package/dist/{acp-cli-6peVIuMz.js → acp-cli-lkOF8AeX.js} +1 -1
- package/dist/{agents-DhWccW-I.js → agents-Qr0BDw_h.js} +5 -5
- package/dist/{agents.config-DwibJO90.js → agents.config-D0ih9tP3.js} +1 -1
- package/dist/{agents.config-ByNtHnqX.js → agents.config-DIjsIDbS.js} +1 -1
- package/dist/{audio-preflight-DIXDvyz5.js → audio-preflight-D0nJ1LEt.js} +4 -4
- package/dist/{audit-BZU2PNKl.js → audit-DVUHZrf4.js} +1 -1
- package/dist/{audit-CaFXenfE.js → audit-DgAM_dWL.js} +1 -1
- package/dist/{auth-choice-Divyczym.js → auth-choice-DhI8MW-5.js} +2 -2
- package/dist/{auth-choice-DOQ4Xf6i.js → auth-choice-PdYn-qiM.js} +2 -2
- package/dist/{banner-Cyi2LLe-.js → banner-BQhYK_Ag.js} +1 -1
- package/dist/{browser-cli-DUcEYbmP.js → browser-cli-CQKRSqbb.js} +2 -2
- package/dist/{browser-cli-DM3GvpUm.js → browser-cli-ClxJjz9C.js} +2 -2
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +6 -6
- package/dist/bundled/session-memory/handler.js +6 -6
- package/dist/{call-CJl0moIs.js → call-BrRWr7Lj.js} +1 -0
- package/dist/{call-BHn18ubR.js → call-CVqBgwrx.js} +1 -0
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-options-C1sGPky6.js → channel-options-CFwo8sFR.js} +1 -1
- package/dist/{channel-options-Bk4m4-d5.js → channel-options-ZHpChVVk.js} +1 -1
- package/dist/{channel-web-BKbzqQ7x.js → channel-web-UmRhDGhI.js} +1 -1
- package/dist/{channels-cli-CAz8gCcs.js → channels-cli-CRDgQtex.js} +6 -6
- package/dist/{channels-cli-CGOOVbGf.js → channels-cli-rzQvsXSw.js} +6 -6
- package/dist/{chrome-ROtrXlNs.js → chrome-C08Z0XAa.js} +7 -7
- package/dist/cli/daemon-cli.js +1 -1
- package/dist/{cli-7JBNvH2_.js → cli-CC9jaj6w.js} +3 -3
- package/dist/{cli-C0zcu-AX.js → cli-DN6fX0Xu.js} +3 -3
- package/dist/{command-registry-BGMCr778.js → command-registry-CH1cn-Lz.js} +10 -10
- package/dist/{completion-cli-EO1xz8q6.js → completion-cli-BgneZQ7D.js} +1 -1
- package/dist/{completion-cli-B1wj8Q43.js → completion-cli-CG24rSh8.js} +2 -2
- package/dist/{config-cli-B9RnWD0Y.js → config-cli-CXa7oMTX.js} +1 -1
- package/dist/{config-cli-QugXKbsV.js → config-cli-DVEOa8P5.js} +1 -1
- package/dist/{configure-DOfxxuzV.js → configure-BDxyPzBl.js} +6 -6
- package/dist/{configure-C_BD9gNf.js → configure-U2yrALDt.js} +6 -6
- package/dist/control-ui/css/style.css +213 -6
- package/dist/control-ui/index.html +24 -2
- package/dist/control-ui/js/connections.js +113 -5
- package/dist/{cron-cli-CH0XOOxj.js → cron-cli--z6DSGhk.js} +2 -2
- package/dist/{cron-cli-DBt3Lxhm.js → cron-cli-DZJZ_EvY.js} +2 -2
- package/dist/{daemon-cli-BRMcpQb7.js → daemon-cli-B9yneKpO.js} +2 -2
- package/dist/{daemon-cli-DZeTm_F2.js → daemon-cli-bwFAShzf.js} +2 -2
- package/dist/daemon-cli.js +1 -0
- package/dist/{deliver-BC3liFsT.js → deliver-CLZGlRZt.js} +1 -1
- package/dist/{devices-cli-DwCYjYyV.js → devices-cli-fVRpoa9z.js} +1 -1
- package/dist/{devices-cli-C7aaQeFG.js → devices-cli-oqibXYae.js} +1 -1
- package/dist/{doctor-completion-DL-ojJGb.js → doctor-completion-8zSqfzuU.js} +1 -1
- package/dist/{doctor-completion-Dm4QxJdc.js → doctor-completion-ny9DIsuL.js} +1 -1
- package/dist/entry.js +1 -1
- package/dist/{exec-approvals-cli-BcwVEh83.js → exec-approvals-cli-BpOqYXNL.js} +3 -3
- package/dist/{exec-approvals-cli-CWpi7F1X.js → exec-approvals-cli-DjGZKQbZ.js} +3 -3
- package/dist/extensionAPI.js +1 -1
- package/dist/{gateway-cli-DcrPLnL3.js → gateway-cli-CmfMdGhz.js} +14 -13
- package/dist/{gateway-cli-DyFOMcg2.js → gateway-cli-Dg0UoYav.js} +14 -13
- package/dist/{gateway-rpc-BzkjTxlD.js → gateway-rpc-Bp0KNJtL.js} +1 -1
- package/dist/{gateway-rpc-CJPoGX_W.js → gateway-rpc-XT8cFwtz.js} +1 -1
- package/dist/{glass-ui-ws-Czh-1YjO.js → glass-ui-ws-Bgpyl16w.js} +10 -10
- package/dist/{glass-ui-ws-nxFknxgE.js → glass-ui-ws-aKGCf5hN.js} +10 -10
- package/dist/{health-CFd-Q1SH.js → health-Bj8mUXDd.js} +48 -14
- package/dist/{health-1ZDwurPU.js → health-D9pKXesa.js} +48 -14
- package/dist/{hooks-cli-C4tUO222.js → hooks-cli-5G9JN39f.js} +4 -4
- package/dist/{hooks-cli-nKBiWE2v.js → hooks-cli-DtVT3wM_.js} +4 -4
- package/dist/{image-C6v6m8Id.js → image-BnO8X_hj.js} +1 -1
- package/dist/index.js +8 -8
- package/dist/llm-slug-generator.js +6 -6
- package/dist/{logs-cli-DWqkAMwy.js → logs-cli-gU7p7zX0.js} +2 -2
- package/dist/{logs-cli-q93Kur4b.js → logs-cli-tJPD_Dps.js} +2 -2
- package/dist/{models-Cd9pFy1G.js → models-DQthIpnz.js} +3 -3
- package/dist/{models-cli-Cxo55E0S.js → models-cli-D8zc0jSg.js} +5 -5
- package/dist/{models-cli-CSqy5xI0.js → models-cli-UaHeUaJq.js} +4 -4
- package/dist/{nodes-cli-BHVOxukb.js → nodes-cli-6vHqlpLI.js} +2 -2
- package/dist/{nodes-cli-seBKfjdd.js → nodes-cli-DxHMNlWq.js} +2 -2
- package/dist/{onboard-SceHniST.js → onboard-B7CIWmHb.js} +3 -3
- package/dist/{onboard-CVKCZHVL.js → onboard-CYYcbEPR.js} +3 -3
- package/dist/{onboard-channels-BI-59zLH.js → onboard-channels-CUUTFx1F.js} +1 -1
- package/dist/{onboard-channels-KGMbYFcP.js → onboard-channels-HyGv2y5c.js} +1 -1
- package/dist/{onboard-helpers-BV3zKTt_.js → onboard-helpers-7H_XiJt-.js} +1 -1
- package/dist/{onboard-helpers-BFyI1sla.js → onboard-helpers-CPSKXD5k.js} +1 -1
- package/dist/{onboard-remote-C-EvSvV9.js → onboard-remote-BlCdyTsP.js} +1 -1
- package/dist/{onboard-remote-CvtBwhma.js → onboard-remote-DFavRxQ6.js} +1 -1
- package/dist/{onboard-skills-C1jrqA-P.js → onboard-skills-CssuFDjw.js} +1 -1
- package/dist/{onboard-skills-CWaMGMQi.js → onboard-skills-DVtfVPsB.js} +1 -1
- package/dist/{onboarding-Bs3JhONv.js → onboarding-BHnEBXBG.js} +7 -7
- package/dist/{onboarding-BPjquWC3.js → onboarding-CchD1d-n.js} +7 -7
- package/dist/{onboarding.finalize-lAwIuZFE.js → onboarding.finalize-BZ6tQzoC.js} +8 -8
- package/dist/{onboarding.finalize-Dbx89qG2.js → onboarding.finalize-CnzLAjla.js} +9 -9
- package/dist/{onboarding.gateway-config-Btb5PaGv.js → onboarding.gateway-config-TM8ERKyn.js} +2 -2
- package/dist/{onboarding.gateway-config-gMhAsXgO.js → onboarding.gateway-config-vGTQDqA6.js} +2 -2
- package/dist/{pi-embedded-CG4P3hy3.js → pi-embedded-BIATvD3R.js} +3 -2
- package/dist/{pi-embedded-helpers-BUNbSNWw.js → pi-embedded-helpers-DcN8GHTt.js} +4 -4
- package/dist/{plugin-registry-DSrgdZKM.js → plugin-registry-7MeuYUTG.js} +1 -1
- package/dist/{plugin-registry-C4aoDdOB.js → plugin-registry-Dx8MaVaX.js} +1 -1
- package/dist/plugin-sdk/{channel-web-CsZ6epLT.js → channel-web-C6_r-2VI.js} +1 -1
- package/dist/plugin-sdk/index.js +2 -2
- package/dist/plugin-sdk/{reply-Rv3jE0Rs.js → reply-CIDYJYie.js} +3 -2
- package/dist/plugin-sdk/{web-D6R4__wu.js → web-CHKraWl6.js} +2 -2
- package/dist/{plugins-cli-DJM_xxIg.js → plugins-cli-bblxpPhT.js} +4 -4
- package/dist/{plugins-cli-CSwcV2M6.js → plugins-cli-oatWFlGr.js} +4 -4
- package/dist/{program-CtX7o1VN.js → program-cj70FFee.js} +9 -9
- package/dist/{program-context-B2HPYMcn.js → program-context-DSkr5IEn.js} +28 -28
- package/dist/{prompt-select-styled-5a7_K1sn.js → prompt-select-styled-C9MQv67C.js} +6 -6
- package/dist/{prompt-select-styled-Cs79EjHm.js → prompt-select-styled-DxtxwQmE.js} +6 -6
- package/dist/{provider-auth-helpers-DOa1Rc3D.js → provider-auth-helpers-CezJXPrZ.js} +1 -1
- package/dist/{provider-auth-helpers-fWAoFIwZ.js → provider-auth-helpers-D9BOiQMP.js} +1 -1
- package/dist/{push-apns-HnaGVJwW.js → push-apns-CL2MBhWP.js} +1 -1
- package/dist/{push-apns-Dnd_jTU-.js → push-apns-DUWtWoB-.js} +1 -1
- package/dist/{pw-ai-BLrC_W1X.js → pw-ai-B476LzSK.js} +1 -1
- package/dist/{register.agent-CaputGWT.js → register.agent-B-v1ixge.js} +8 -8
- package/dist/{register.agent-lqb5eXZs.js → register.agent-Dms0oymW.js} +7 -7
- package/dist/{register.configure-C3AQZaAa.js → register.configure-BP_a-E21.js} +10 -10
- package/dist/{register.configure-C0KBR4e6.js → register.configure-DcwAboPG.js} +10 -10
- package/dist/{register.maintenance-DLY3bZTm.js → register.maintenance-C4tn55a5.js} +9 -9
- package/dist/{register.maintenance-c8Ig4nYO.js → register.maintenance-D_1D-fbi.js} +10 -10
- package/dist/{register.message-CUclEFp5.js → register.message-Csn-WBH0.js} +4 -4
- package/dist/{register.message-Bexo7F0u.js → register.message-FsBEsQeD.js} +4 -4
- package/dist/{register.onboard-CVmFRJ__.js → register.onboard-CHpUtNWT.js} +6 -6
- package/dist/{register.onboard-DpeqS3GT.js → register.onboard-OXqQs97I.js} +6 -6
- package/dist/{register.setup-DogqYYN7.js → register.setup-C8FuEUO_.js} +6 -6
- package/dist/{register.setup-NiDBVZE2.js → register.setup-DbPNjezQ.js} +6 -6
- package/dist/{register.status-health-sessions-C5noW7M3.js → register.status-health-sessions-BzB_lPbR.js} +6 -6
- package/dist/{register.status-health-sessions-CTErhiR9.js → register.status-health-sessions-c8vq6An_.js} +6 -6
- package/dist/{register.subclis-E_1XOkdf.js → register.subclis-Dt0Az0gT.js} +19 -19
- package/dist/{reply-DAMo5JhO.js → reply-B0azB7WR.js} +4 -4
- package/dist/{rpc-IXmOgc1l.js → rpc-CHb_JvbM.js} +1 -1
- package/dist/{rpc-k8pnK8TE.js → rpc-Cog-Z1rx.js} +1 -1
- package/dist/{run-main-Cv91hLSK.js → run-main-D-OIb2fr.js} +16 -16
- package/dist/{runner-QX0Z6K1w.js → runner-D5nFF9E6.js} +1 -1
- package/dist/{security-cli-Cxmb5Rpv.js → security-cli-B5s73Le2.js} +2 -2
- package/dist/{security-cli-BsStEfWU.js → security-cli-CzWHkrqD.js} +2 -2
- package/dist/{server-methods-CXL1Nrbp.js → server-methods-Dph_r18S.js} +68 -10
- package/dist/{server-methods-C_rhjm5p.js → server-methods-b55BoGQD.js} +68 -10
- package/dist/{server-node-events-B_UZBZn_.js → server-node-events-AVxH5dXs.js} +4 -4
- package/dist/{server-node-events-CdUVoXvg.js → server-node-events-Ba9K9DB9.js} +4 -4
- package/dist/{status-CzI_lZth.js → status-Bbss-JjB.js} +5 -5
- package/dist/{status-DQQ-w3eF.js → status-Cg3Vn5FV.js} +5 -5
- package/dist/{status-Ds4oB9tJ.js → status-CpWkGj5h.js} +1 -1
- package/dist/{status-Drn5xFtL.js → status-DNxAYvxM.js} +1 -1
- package/dist/{subagent-registry-CfoRc8ng.js → subagent-registry-CsYeP8wc.js} +4 -4
- package/dist/{system-cli-DnlgTnqh.js → system-cli-D3CVv1ab.js} +2 -2
- package/dist/{system-cli-CQNazJoF.js → system-cli-rpyy5jcw.js} +2 -2
- package/dist/{tui-CXTwJqpz.js → tui-DfPeXwah.js} +1 -1
- package/dist/{tui-DTW81r9y.js → tui-LZPdrFmK.js} +1 -1
- package/dist/{tui-cli-KiaTeKr0.js → tui-cli-Bm3TJgXf.js} +2 -2
- package/dist/{tui-cli-DGmt1Xs0.js → tui-cli-DFXZ7r1F.js} +2 -2
- package/dist/{unified-runner-DweFv8Vx.js → unified-runner-BojeuKIk.js} +17 -16
- package/dist/{update-cli-Ba4La00X.js → update-cli-DO0A0UCN.js} +10 -10
- package/dist/{update-cli-BkJZPKh8.js → update-cli-Dh_GPhI4.js} +11 -11
- package/dist/{update-runner-w3GO-spo.js → update-runner-BE6kDMsw.js} +1 -1
- package/dist/{update-runner-CqWSrJXt.js → update-runner-Cv6hDgKV.js} +1 -1
- package/dist/{web-0cG6_ynp.js → web-BOv3xM7W.js} +4 -4
- package/dist/{web-DHAEIalz.js → web-CYf5I3aU.js} +3 -3
- package/dist/{web-9rrJ5lZr.js → web-Dxkxcp7P.js} +6 -6
- package/dist/{web-Cx3SfQiX.js → web-Ifwqx6Dt.js} +1 -1
- package/docs/connections/email.md +143 -0
- package/docs/connections/msteams.md +80 -0
- package/docs/connections/slack.md +91 -0
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/learning-loop/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +12 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +12 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +12 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/outlook/package.json +1 -1
- package/extensions/pipeline/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +12 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +12 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +12 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +12 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Email
|
|
2
|
+
|
|
3
|
+
Symi connects to email through two integrations. Pick based on which account you have and what you want to do with it.
|
|
4
|
+
|
|
5
|
+
| Integration | Best for | Setup effort |
|
|
6
|
+
| --------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------ |
|
|
7
|
+
| **Outlook 365** | Microsoft 365 work/school accounts, `outlook.com`, `hotmail.com`, `live.com` | Two minutes — one chat command |
|
|
8
|
+
| **Gmail** | Google Workspace, personal Gmail, and you want incoming mail to auto-create Symi sessions | 15–30 minutes — Google Cloud Pub/Sub setup |
|
|
9
|
+
|
|
10
|
+
## Outlook 365
|
|
11
|
+
|
|
12
|
+
Ships bundled and auto-enabled. To connect:
|
|
13
|
+
|
|
14
|
+
1. Open any chat surface (Glass UI, Telegram, WhatsApp, etc.).
|
|
15
|
+
2. Type `/outlook login`.
|
|
16
|
+
3. Symi replies with a device-code URL and an 8-character code.
|
|
17
|
+
4. Open the URL in a browser, sign in with your Microsoft account, paste the code, approve access.
|
|
18
|
+
5. Credentials are stored at `~/.symi/credentials/outlook.json` (mode 0600) and the tools below are live immediately.
|
|
19
|
+
|
|
20
|
+
### Tools the agent gains
|
|
21
|
+
|
|
22
|
+
- `outlook_list` — list messages in a folder (`inbox`, `sentitems`, `drafts`, `archive`, `junkemail`). Optional unread filter.
|
|
23
|
+
- `outlook_read` — fetch the full body of a message by id (auto-marks read).
|
|
24
|
+
- `outlook_send` — new message with To, CC, subject, body.
|
|
25
|
+
- `outlook_reply` — reply or reply-all to an existing message id.
|
|
26
|
+
- `outlook_search` — keyword search across subject, body, sender.
|
|
27
|
+
- `outlook_folders` — list folders with unread and total counts.
|
|
28
|
+
- `outlook_move` — move a message to another folder.
|
|
29
|
+
|
|
30
|
+
### Commands
|
|
31
|
+
|
|
32
|
+
- `/outlook login` — connect (device-code flow).
|
|
33
|
+
- `/outlook status` — show current account, token state, last update timestamp.
|
|
34
|
+
- `/outlook logout` — disconnect and delete stored credentials.
|
|
35
|
+
|
|
36
|
+
### Limitations
|
|
37
|
+
|
|
38
|
+
- Plain-text body only. No HTML formatting, no attachments.
|
|
39
|
+
- **Pull-only.** Outlook does not create Symi sessions for incoming mail. You have to ask Symi ("any new mail?") and it calls `outlook_list` / `outlook_search`. If you want inbound-triggered sessions, use Gmail instead.
|
|
40
|
+
- No automatic retry on transient Graph 5xx errors — re-running a tool usually succeeds.
|
|
41
|
+
|
|
42
|
+
## Gmail
|
|
43
|
+
|
|
44
|
+
Gmail inbound uses Google Cloud Pub/Sub so new email triggers a webhook into Symi and creates a `hook:gmail:<id>` session.
|
|
45
|
+
|
|
46
|
+
### Prerequisites
|
|
47
|
+
|
|
48
|
+
- Access to a **Google Cloud project** — free at [console.cloud.google.com](https://console.cloud.google.com).
|
|
49
|
+
- `gcloud` CLI installed.
|
|
50
|
+
- macOS: `brew install --cask google-cloud-sdk`
|
|
51
|
+
- Linux: see [Google's install guide](https://cloud.google.com/sdk/docs/install).
|
|
52
|
+
- OAuth credentials for the Gmail API, managed via `gogcli`. See the `gog` skill for setup.
|
|
53
|
+
- Symi's webhook endpoint reachable by Google's push service — either a publicly reachable host or a Tailscale serve/funnel.
|
|
54
|
+
|
|
55
|
+
### Setup
|
|
56
|
+
|
|
57
|
+
1. **Authenticate gcloud**
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
gcloud auth login
|
|
61
|
+
gcloud config set project <project-id>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
2. **Set up gogcli OAuth**
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
gog auth credentials /path/to/client_secret.json
|
|
68
|
+
gog auth add <your-email> --services gmail
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
3. **Create the Pub/Sub topic**
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
gcloud pubsub topics create symi-gmail
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
4. **Grant Gmail permission to publish to the topic**
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
gcloud pubsub topics add-iam-policy-binding symi-gmail \
|
|
81
|
+
--member=serviceAccount:gmail-api-push@system.gserviceaccount.com \
|
|
82
|
+
--role=roles/pubsub.publisher
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
5. **Create the push subscription** (points at Symi's webhook)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
gcloud pubsub subscriptions create symi-gmail-sub \
|
|
89
|
+
--topic=symi-gmail \
|
|
90
|
+
--push-endpoint=<SYMI_WEBHOOK_URL>/gmail-pubsub
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
6. **Register the Gmail watch** on the inbox label. The helpers in `src/hooks/gmail-setup-utils.ts` can do this from the gateway, or call the Gmail API's `users.watch` method directly with `curl`.
|
|
94
|
+
|
|
95
|
+
7. **Add `hooks.gmail` to `~/.symi/symi.json`**:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"hooks": {
|
|
100
|
+
"gmail": {
|
|
101
|
+
"account": "user@example.com",
|
|
102
|
+
"label": "INBOX",
|
|
103
|
+
"topic": "projects/<project-id>/topics/symi-gmail",
|
|
104
|
+
"subscription": "projects/<project-id>/subscriptions/symi-gmail-sub",
|
|
105
|
+
"pushToken": "<random-shared-secret>",
|
|
106
|
+
"hookUrl": "http://127.0.0.1:8788/gmail-pubsub",
|
|
107
|
+
"includeBody": true,
|
|
108
|
+
"maxBytes": 20480,
|
|
109
|
+
"renewEveryMinutes": 720,
|
|
110
|
+
"serve": { "bind": "127.0.0.1", "port": 8788, "path": "/gmail-pubsub" },
|
|
111
|
+
"tailscale": { "mode": "off" }
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
8. **Restart the gateway** to pick up the new hook config. `hooks.gmail` is not hot-reloaded.
|
|
118
|
+
|
|
119
|
+
9. **Verify** — send a test email. Google publishes to the topic → Pub/Sub pushes to Symi's endpoint → a `hook:gmail:<id>` session appears in the Glass UI feed.
|
|
120
|
+
|
|
121
|
+
### Config field reference
|
|
122
|
+
|
|
123
|
+
- `account` — the Gmail address being watched.
|
|
124
|
+
- `label` — Gmail label/folder to watch. Default `INBOX`.
|
|
125
|
+
- `topic` / `subscription` — fully-qualified Pub/Sub resource names.
|
|
126
|
+
- `pushToken` — shared secret Symi verifies on incoming push requests.
|
|
127
|
+
- `hookUrl` — URL the push subscription posts to. Must match `serve.bind` + `serve.port` + `serve.path` (or a Tailscale serve/funnel exposing them).
|
|
128
|
+
- `includeBody` — include the email body in the prompt. `maxBytes` truncates oversized emails.
|
|
129
|
+
- `renewEveryMinutes` — Gmail `watch` expires after ~7 days. Default 720 (12 hours) re-registers well ahead.
|
|
130
|
+
- `tailscale.mode` — `"off"` if Symi is publicly reachable, `"serve"` for a private tailnet webhook, `"funnel"` for a Tailscale-exposed public endpoint.
|
|
131
|
+
- `allowUnsafeExternalContent` — leave unset. Setting `true` disables the external-content safety wrapper on email content.
|
|
132
|
+
|
|
133
|
+
### Limitations
|
|
134
|
+
|
|
135
|
+
- Inbound only works while the Gmail watch is live. If `renewEveryMinutes` lapses, the Pub/Sub subscription fails, or the IAM binding is removed, mail stops arriving.
|
|
136
|
+
- Outgoing mail goes through the reply path of whichever session handles the inbound — there is no native Gmail send tool. For outgoing from scratch, Outlook is simpler.
|
|
137
|
+
- Very large messages are truncated at `maxBytes` so the prompt stays usable.
|
|
138
|
+
|
|
139
|
+
## Which one should you pick?
|
|
140
|
+
|
|
141
|
+
- **Send and read on demand from a Microsoft account** — Outlook.
|
|
142
|
+
- **Incoming mail auto-creates sessions** — Gmail (only option today).
|
|
143
|
+
- **You want both send and auto-receive in Outlook** — not available yet; push for Outlook is not implemented.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Microsoft Teams
|
|
2
|
+
|
|
3
|
+
Symi connects to Microsoft Teams via the **Bot Framework** — you register a bot in Azure, configure a messaging endpoint, and the Symi gateway receives activities over HTTPS.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- An Azure account with permission to create an Azure Bot resource (free tier works for development).
|
|
8
|
+
- An Entra ID (Azure AD) tenant. Can be your work tenant or a personal "Microsoft 365 Developer Program" tenant.
|
|
9
|
+
- A publicly reachable HTTPS endpoint for Symi. During development you can use a Tailscale funnel or ngrok; for production, any TLS-terminated host works.
|
|
10
|
+
- Teams admin approval to sideload or publish the bot in your org (the sideload path is simplest for personal/dev use).
|
|
11
|
+
|
|
12
|
+
## Setup
|
|
13
|
+
|
|
14
|
+
1. **Create the Azure Bot**
|
|
15
|
+
In the Azure Portal: _Create a resource_ → search _Azure Bot_ → Create. Choose:
|
|
16
|
+
- Bot handle (e.g., `symi-bot`)
|
|
17
|
+
- Subscription + resource group
|
|
18
|
+
- Pricing tier (F0 Free is fine)
|
|
19
|
+
- Microsoft App ID type: _Multi Tenant_ (easiest) or _Single Tenant_
|
|
20
|
+
- Creation type: _Create new Microsoft App ID_
|
|
21
|
+
|
|
22
|
+
2. **Grab credentials**
|
|
23
|
+
After creation → _Configuration_ tab. Note:
|
|
24
|
+
- _Microsoft App ID_ (`appId`)
|
|
25
|
+
- _Tenant ID_ (`tenantId`) — shown if Single Tenant
|
|
26
|
+
_Manage Password_ → generate a client secret. Copy the secret value **immediately** — Azure only shows it once. That's your `appPassword`.
|
|
27
|
+
|
|
28
|
+
3. **Set the messaging endpoint**
|
|
29
|
+
Same _Configuration_ tab → _Messaging endpoint_ → enter `https://<your-symi-host>/msteams/messages`. Save.
|
|
30
|
+
|
|
31
|
+
4. **Enable the Teams channel**
|
|
32
|
+
Left sidebar → _Channels_ → _Microsoft Teams_ → _Apply_. Accept the terms.
|
|
33
|
+
|
|
34
|
+
5. **Add to `~/.symi/symi.json`**
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"channels": {
|
|
39
|
+
"msteams": {
|
|
40
|
+
"appId": "...",
|
|
41
|
+
"appPassword": "...",
|
|
42
|
+
"tenantId": "..."
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Omit `tenantId` if the bot is multi-tenant.
|
|
49
|
+
|
|
50
|
+
6. **Restart the gateway** to load the new config.
|
|
51
|
+
|
|
52
|
+
## Install the bot in Teams
|
|
53
|
+
|
|
54
|
+
Azure's bot registration isn't automatically visible inside Teams — you need an app package.
|
|
55
|
+
|
|
56
|
+
1. Go to [Teams Developer Portal](https://dev.teams.microsoft.com/) → _Apps_ → _New app_.
|
|
57
|
+
2. Under _Basic information_ fill in the app name, descriptions, etc.
|
|
58
|
+
3. Under _App features_ → _Bot_ → select _Enter a bot ID_ and paste your `appId` from step 2.
|
|
59
|
+
4. Scope: _Personal_, _Team_, and/or _Group Chat_ depending on where you want to use it.
|
|
60
|
+
5. _Preview in Teams_ → install to yourself or your team.
|
|
61
|
+
|
|
62
|
+
For organization-wide rollout, submit the app via the Teams admin center's custom app catalog.
|
|
63
|
+
|
|
64
|
+
## Pairing
|
|
65
|
+
|
|
66
|
+
Like Slack, Teams DMs default to pairing mode — first-time users receive a pairing prompt so unauthorized people can't invoke the agent. Configure in `channels.msteams.pairing` (see full channel docs).
|
|
67
|
+
|
|
68
|
+
## Troubleshooting
|
|
69
|
+
|
|
70
|
+
- **Bot responds in Azure test but not in Teams** — Teams channel is not enabled yet (step 4), or the app package wasn't installed to Teams (above).
|
|
71
|
+
- **401 Unauthorized on incoming activities** — `appId` / `appPassword` mismatch, or `tenantId` set but the bot is actually multi-tenant (remove it).
|
|
72
|
+
- **Bot installed but silent** — check that the messaging endpoint is publicly reachable over HTTPS. Azure must be able to POST to it. Test with `curl -X POST https://<your-host>/msteams/messages` — you should see a 401 or 400 from Symi (meaning the route exists), not a connection failure.
|
|
73
|
+
- **Secret expired** — client secrets in Entra ID expire (default 2 years). Generate a new one in _Manage Password_ and update `appPassword`.
|
|
74
|
+
|
|
75
|
+
## Limitations
|
|
76
|
+
|
|
77
|
+
- Adaptive Cards beyond simple text are experimental.
|
|
78
|
+
- File attachments and inline images are not fully supported in all flows.
|
|
79
|
+
- Meeting and call actions (join, transcribe, etc.) are out of scope — Teams voice is handled separately.
|
|
80
|
+
- Each bot is tied to a specific Azure tenant's App ID — you can't share one bot registration across disconnected tenants without using multi-tenant mode.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Slack
|
|
2
|
+
|
|
3
|
+
Symi connects to Slack through a Slack App you create in your workspace. Default mode is **Socket Mode** (no public webhook required); HTTP Events API mode is also supported.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- A Slack workspace where you can create and install an app. Workspace admin approval may be required depending on org policy.
|
|
8
|
+
- The Symi gateway running locally or on a reachable host. Socket Mode does not require the gateway to be publicly reachable.
|
|
9
|
+
|
|
10
|
+
## Socket Mode setup (recommended)
|
|
11
|
+
|
|
12
|
+
1. **Create the Slack app**
|
|
13
|
+
Go to [api.slack.com/apps](https://api.slack.com/apps) → _Create New App_ → _From scratch_. Name it (e.g., "Symi"), pick your workspace.
|
|
14
|
+
|
|
15
|
+
2. **Enable Socket Mode**
|
|
16
|
+
Left sidebar → _Socket Mode_ → toggle on. Generate an app-level token with the `connections:write` scope — this is your `appToken` (starts with `xapp-`).
|
|
17
|
+
|
|
18
|
+
3. **Add bot scopes**
|
|
19
|
+
Left sidebar → _OAuth & Permissions_ → _Bot Token Scopes_. Add at minimum:
|
|
20
|
+
- `chat:write` — send messages
|
|
21
|
+
- `im:history` — read DMs
|
|
22
|
+
- `im:read` — list DMs
|
|
23
|
+
- `users:read` — look up user info
|
|
24
|
+
- `app_mentions:read` — respond to @mentions in channels
|
|
25
|
+
- `channels:history` — read channel messages (for channel integrations)
|
|
26
|
+
|
|
27
|
+
4. **Subscribe to events**
|
|
28
|
+
Left sidebar → _Event Subscriptions_ → toggle on. Under _Subscribe to bot events_ add:
|
|
29
|
+
- `message.im` — direct messages
|
|
30
|
+
- `app_mention` — @mentions in channels
|
|
31
|
+
- `message.channels` (optional) — messages in public channels the bot is in
|
|
32
|
+
|
|
33
|
+
5. **Install to workspace**
|
|
34
|
+
Left sidebar → _Install App_ → _Install to Workspace_. Approve the scopes. Copy the bot token that appears (starts with `xoxb-`) — this is your `botToken`.
|
|
35
|
+
|
|
36
|
+
6. **Add to `~/.symi/symi.json`**
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"channels": {
|
|
41
|
+
"slack": {
|
|
42
|
+
"botToken": "xoxb-...",
|
|
43
|
+
"appToken": "xapp-...",
|
|
44
|
+
"mode": "socket"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
7. **Restart the gateway** to pick up the config. You should see `channel=slack socket connected` in the logs.
|
|
51
|
+
|
|
52
|
+
## HTTP Events API mode
|
|
53
|
+
|
|
54
|
+
Use this when your Symi host is publicly reachable (or via a Tailscale funnel) and you'd rather not hold a WebSocket open.
|
|
55
|
+
|
|
56
|
+
1. Complete steps 1, 3, and 4 above.
|
|
57
|
+
2. _Event Subscriptions_ → _Request URL_ → enter `https://<your-symi-host>/slack/events`. Slack will verify.
|
|
58
|
+
3. `~/.symi/symi.json`:
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"channels": {
|
|
62
|
+
"slack": {
|
|
63
|
+
"botToken": "xoxb-...",
|
|
64
|
+
"signingSecret": "<from-Basic-Information>",
|
|
65
|
+
"mode": "http"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
4. Restart the gateway.
|
|
71
|
+
|
|
72
|
+
## Pairing (DMs)
|
|
73
|
+
|
|
74
|
+
By default, Slack DMs require pairing. The first time a user DMs the bot, they'll receive a pairing code prompt. This prevents unauthorized users from invoking your agent. Configure pairing behaviour in `channels.slack.pairing` (see full channel docs for the exact schema).
|
|
75
|
+
|
|
76
|
+
## Slash commands
|
|
77
|
+
|
|
78
|
+
Symi exposes a catalog of slash commands in Slack (`/symi`, `/new`, `/outlook login`, etc.) once the bot is installed. The exact command set depends on which plugins are enabled in your config.
|
|
79
|
+
|
|
80
|
+
## Troubleshooting
|
|
81
|
+
|
|
82
|
+
- **"not_in_channel" when sending** — invite the bot to the channel first: `/invite @Symi`.
|
|
83
|
+
- **No events arriving in Socket Mode** — verify `appToken` has `connections:write`, and that the app is installed (not just created).
|
|
84
|
+
- **HTTP 401 on events** — signing secret mismatch. Re-copy from _Basic Information_ → _Signing Secret_.
|
|
85
|
+
- **DMs silently ignored** — check pairing status. New users must complete pairing before DMs flow to the agent.
|
|
86
|
+
|
|
87
|
+
## Limitations
|
|
88
|
+
|
|
89
|
+
- File uploads/attachments are not yet fully handled in all flows — text messages are the primary supported shape.
|
|
90
|
+
- Reaction-based commands depend on the workspace's reaction configuration and Slack plan tier.
|
|
91
|
+
- Threaded messages are supported but require the bot to be in the channel where the thread lives.
|