agent-messenger 2.27.2 → 2.28.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/.claude-plugin/README.md +11 -1
- package/.claude-plugin/marketplace.json +14 -1
- package/.claude-plugin/plugin.json +4 -2
- package/AGENTS.md +4 -0
- package/README.md +40 -9
- package/dist/package.json +10 -2
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +3 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/platforms/discordbot/cli.js +1 -1
- package/dist/src/platforms/imessage/cli.d.ts +5 -0
- package/dist/src/platforms/imessage/cli.d.ts.map +1 -0
- package/dist/src/platforms/imessage/cli.js +31 -0
- package/dist/src/platforms/imessage/cli.js.map +1 -0
- package/dist/src/platforms/imessage/client.d.ts +43 -0
- package/dist/src/platforms/imessage/client.d.ts.map +1 -0
- package/dist/src/platforms/imessage/client.js +190 -0
- package/dist/src/platforms/imessage/client.js.map +1 -0
- package/dist/src/platforms/imessage/commands/auth.d.ts +31 -0
- package/dist/src/platforms/imessage/commands/auth.d.ts.map +1 -0
- package/dist/src/platforms/imessage/commands/auth.js +100 -0
- package/dist/src/platforms/imessage/commands/auth.js.map +1 -0
- package/dist/src/platforms/imessage/commands/chat.d.ts +3 -0
- package/dist/src/platforms/imessage/commands/chat.d.ts.map +1 -0
- package/dist/src/platforms/imessage/commands/chat.js +42 -0
- package/dist/src/platforms/imessage/commands/chat.js.map +1 -0
- package/dist/src/platforms/imessage/commands/doctor.d.ts +25 -0
- package/dist/src/platforms/imessage/commands/doctor.d.ts.map +1 -0
- package/dist/src/platforms/imessage/commands/doctor.js +101 -0
- package/dist/src/platforms/imessage/commands/doctor.js.map +1 -0
- package/dist/src/platforms/imessage/commands/index.d.ts +7 -0
- package/dist/src/platforms/imessage/commands/index.d.ts.map +1 -0
- package/dist/src/platforms/imessage/commands/index.js +7 -0
- package/dist/src/platforms/imessage/commands/index.js.map +1 -0
- package/dist/src/platforms/imessage/commands/message.d.ts +5 -0
- package/dist/src/platforms/imessage/commands/message.d.ts.map +1 -0
- package/dist/src/platforms/imessage/commands/message.js +127 -0
- package/dist/src/platforms/imessage/commands/message.js.map +1 -0
- package/dist/src/platforms/imessage/commands/setup.d.ts +20 -0
- package/dist/src/platforms/imessage/commands/setup.d.ts.map +1 -0
- package/dist/src/platforms/imessage/commands/setup.js +57 -0
- package/dist/src/platforms/imessage/commands/setup.js.map +1 -0
- package/dist/src/platforms/imessage/commands/shared.d.ts +10 -0
- package/dist/src/platforms/imessage/commands/shared.d.ts.map +1 -0
- package/dist/src/platforms/imessage/commands/shared.js +53 -0
- package/dist/src/platforms/imessage/commands/shared.js.map +1 -0
- package/dist/src/platforms/imessage/commands/whoami.d.ts +3 -0
- package/dist/src/platforms/imessage/commands/whoami.d.ts.map +1 -0
- package/dist/src/platforms/imessage/commands/whoami.js +20 -0
- package/dist/src/platforms/imessage/commands/whoami.js.map +1 -0
- package/dist/src/platforms/imessage/credential-manager.d.ts +22 -0
- package/dist/src/platforms/imessage/credential-manager.d.ts.map +1 -0
- package/dist/src/platforms/imessage/credential-manager.js +111 -0
- package/dist/src/platforms/imessage/credential-manager.js.map +1 -0
- package/dist/src/platforms/imessage/ensure-auth.d.ts +2 -0
- package/dist/src/platforms/imessage/ensure-auth.d.ts.map +1 -0
- package/dist/src/platforms/imessage/ensure-auth.js +13 -0
- package/dist/src/platforms/imessage/ensure-auth.js.map +1 -0
- package/dist/src/platforms/imessage/errors.d.ts +3 -0
- package/dist/src/platforms/imessage/errors.d.ts.map +1 -0
- package/dist/src/platforms/imessage/errors.js +25 -0
- package/dist/src/platforms/imessage/errors.js.map +1 -0
- package/dist/src/platforms/imessage/index.d.ts +7 -0
- package/dist/src/platforms/imessage/index.d.ts.map +1 -0
- package/dist/src/platforms/imessage/index.js +5 -0
- package/dist/src/platforms/imessage/index.js.map +1 -0
- package/dist/src/platforms/imessage/rpc.d.ts +20 -0
- package/dist/src/platforms/imessage/rpc.d.ts.map +1 -0
- package/dist/src/platforms/imessage/rpc.js +133 -0
- package/dist/src/platforms/imessage/rpc.js.map +1 -0
- package/dist/src/platforms/imessage/types.d.ts +59 -0
- package/dist/src/platforms/imessage/types.d.ts.map +1 -0
- package/dist/src/platforms/imessage/types.js +29 -0
- package/dist/src/platforms/imessage/types.js.map +1 -0
- package/dist/src/platforms/instagram/cli.js +1 -1
- package/dist/src/platforms/instagram/client.d.ts +6 -1
- package/dist/src/platforms/instagram/client.d.ts.map +1 -1
- package/dist/src/platforms/instagram/client.js +17 -0
- package/dist/src/platforms/instagram/client.js.map +1 -1
- package/dist/src/platforms/instagram/hybrid-listener.d.ts +48 -0
- package/dist/src/platforms/instagram/hybrid-listener.d.ts.map +1 -0
- package/dist/src/platforms/instagram/hybrid-listener.js +154 -0
- package/dist/src/platforms/instagram/hybrid-listener.js.map +1 -0
- package/dist/src/platforms/instagram/index.d.ts +2 -0
- package/dist/src/platforms/instagram/index.d.ts.map +1 -1
- package/dist/src/platforms/instagram/index.js +2 -0
- package/dist/src/platforms/instagram/index.js.map +1 -1
- package/dist/src/platforms/instagram/mqtt/connection.d.ts +4 -0
- package/dist/src/platforms/instagram/mqtt/connection.d.ts.map +1 -0
- package/dist/src/platforms/instagram/mqtt/connection.js +66 -0
- package/dist/src/platforms/instagram/mqtt/connection.js.map +1 -0
- package/dist/src/platforms/instagram/mqtt/thrift.d.ts +22 -0
- package/dist/src/platforms/instagram/mqtt/thrift.d.ts.map +1 -0
- package/dist/src/platforms/instagram/mqtt/thrift.js +143 -0
- package/dist/src/platforms/instagram/mqtt/thrift.js.map +1 -0
- package/dist/src/platforms/instagram/mqtt/transport.d.ts +42 -0
- package/dist/src/platforms/instagram/mqtt/transport.d.ts.map +1 -0
- package/dist/src/platforms/instagram/mqtt/transport.js +246 -0
- package/dist/src/platforms/instagram/mqtt/transport.js.map +1 -0
- package/dist/src/platforms/instagram/realtime-listener.d.ts +33 -0
- package/dist/src/platforms/instagram/realtime-listener.d.ts.map +1 -0
- package/dist/src/platforms/instagram/realtime-listener.js +151 -0
- package/dist/src/platforms/instagram/realtime-listener.js.map +1 -0
- package/dist/src/platforms/kakaotalk/cli.js +1 -1
- package/dist/src/platforms/line/cli.js +1 -1
- package/dist/src/platforms/webex/cli.js +1 -1
- package/dist/src/platforms/webexbot/cli.js +1 -1
- package/dist/src/platforms/wechatbot/cli.js +1 -1
- package/dist/src/platforms/whatsapp/cli.js +1 -1
- package/dist/src/platforms/whatsappbot/cli.js +1 -1
- package/dist/src/tui/adapters/imessage-adapter.d.ts +21 -0
- package/dist/src/tui/adapters/imessage-adapter.d.ts.map +1 -0
- package/dist/src/tui/adapters/imessage-adapter.js +110 -0
- package/dist/src/tui/adapters/imessage-adapter.js.map +1 -0
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +9 -0
- package/dist/src/tui/app.js.map +1 -1
- package/docs/content/docs/agent-skills.mdx +1 -1
- package/docs/content/docs/cli/imessage.mdx +99 -0
- package/docs/content/docs/cli/instagram.mdx +1 -1
- package/docs/content/docs/cli/meta.json +1 -0
- package/docs/content/docs/index.mdx +9 -6
- package/docs/content/docs/quick-start.mdx +2 -0
- package/docs/content/docs/sdk/instagram.mdx +90 -5
- package/docs/content/docs/tui.mdx +4 -3
- package/package.json +10 -2
- package/scripts/postbuild.ts +12 -15
- package/skills/agent-channeltalk/SKILL.md +1 -1
- package/skills/agent-channeltalkbot/SKILL.md +1 -1
- package/skills/agent-discord/SKILL.md +1 -1
- package/skills/agent-discordbot/SKILL.md +1 -1
- package/skills/agent-imessage/SKILL.md +133 -0
- package/skills/agent-imessage/references/authentication.md +66 -0
- package/skills/agent-imessage/references/permissions.md +31 -0
- package/skills/agent-imessage/references/setup.md +49 -0
- package/skills/agent-instagram/SKILL.md +72 -2
- package/skills/agent-instagram/references/common-patterns.md +36 -0
- package/skills/agent-instagram/templates/monitor-chat.sh +5 -0
- package/skills/agent-kakaotalk/SKILL.md +1 -1
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +1 -1
- package/skills/agent-slackbot/SKILL.md +1 -1
- package/skills/agent-teams/SKILL.md +1 -1
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-telegrambot/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +1 -1
- package/skills/agent-webexbot/SKILL.md +1 -1
- package/skills/agent-wechatbot/SKILL.md +1 -1
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/cli.ts +4 -0
- package/src/platforms/imessage/cli.ts +39 -0
- package/src/platforms/imessage/client.test.ts +137 -0
- package/src/platforms/imessage/client.ts +253 -0
- package/src/platforms/imessage/commands/auth.ts +142 -0
- package/src/platforms/imessage/commands/chat.ts +51 -0
- package/src/platforms/imessage/commands/doctor.test.ts +80 -0
- package/src/platforms/imessage/commands/doctor.ts +139 -0
- package/src/platforms/imessage/commands/index.ts +6 -0
- package/src/platforms/imessage/commands/message.test.ts +20 -0
- package/src/platforms/imessage/commands/message.ts +151 -0
- package/src/platforms/imessage/commands/setup.test.ts +52 -0
- package/src/platforms/imessage/commands/setup.ts +76 -0
- package/src/platforms/imessage/commands/shared.test.ts +19 -0
- package/src/platforms/imessage/commands/shared.ts +69 -0
- package/src/platforms/imessage/commands/whoami.ts +22 -0
- package/src/platforms/imessage/credential-manager.test.ts +122 -0
- package/src/platforms/imessage/credential-manager.ts +123 -0
- package/src/platforms/imessage/ensure-auth.ts +18 -0
- package/src/platforms/imessage/errors.ts +27 -0
- package/src/platforms/imessage/index.test.ts +13 -0
- package/src/platforms/imessage/index.ts +16 -0
- package/src/platforms/imessage/rpc.ts +157 -0
- package/src/platforms/imessage/test-stub-imsg.mjs +147 -0
- package/src/platforms/imessage/types.test.ts +47 -0
- package/src/platforms/imessage/types.ts +95 -0
- package/src/platforms/instagram/client.ts +23 -0
- package/src/platforms/instagram/hybrid-listener.test.ts +135 -0
- package/src/platforms/instagram/hybrid-listener.ts +196 -0
- package/src/platforms/instagram/index.ts +10 -0
- package/src/platforms/instagram/mqtt/connection.ts +72 -0
- package/src/platforms/instagram/mqtt/thrift.test.ts +91 -0
- package/src/platforms/instagram/mqtt/thrift.ts +159 -0
- package/src/platforms/instagram/mqtt/transport.ts +285 -0
- package/src/platforms/instagram/realtime-listener.test.ts +34 -0
- package/src/platforms/instagram/realtime-listener.ts +201 -0
- package/src/platforms/webexbot/cli.ts +0 -0
- package/src/tui/adapters/imessage-adapter.ts +131 -0
- package/src/tui/app.ts +13 -0
|
@@ -13,6 +13,8 @@ npm install agent-messenger
|
|
|
13
13
|
import {
|
|
14
14
|
InstagramClient,
|
|
15
15
|
InstagramListener,
|
|
16
|
+
InstagramRealtimeListener,
|
|
17
|
+
InstagramHybridListener,
|
|
16
18
|
InstagramError,
|
|
17
19
|
InstagramCredentialManager,
|
|
18
20
|
} from 'agent-messenger/instagram'
|
|
@@ -122,7 +124,83 @@ client.setDebugLog((msg) => console.error(`[debug] ${msg}`))
|
|
|
122
124
|
|
|
123
125
|
## Real-Time Events
|
|
124
126
|
|
|
125
|
-
|
|
127
|
+
### InstagramHybridListener (Recommended)
|
|
128
|
+
|
|
129
|
+
`InstagramHybridListener` tries to connect over Instagram's MQTToT transport first (a persistent TLS connection to `edge-mqtt.facebook.com` — the same protocol Instagram's own app uses). If that fails, it falls back to polling automatically and retries the realtime connection with capped exponential backoff.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { InstagramClient, InstagramHybridListener } from 'agent-messenger/instagram'
|
|
133
|
+
|
|
134
|
+
const client = await new InstagramClient().login()
|
|
135
|
+
const listener = new InstagramHybridListener(client, {
|
|
136
|
+
pollInterval: 5000, // fallback poll interval in ms (default: 5000)
|
|
137
|
+
realtimeRetryBaseMs: 2000, // backoff base for realtime reconnect attempts
|
|
138
|
+
realtimeRetryMaxMs: 60000, // backoff cap
|
|
139
|
+
disableRealtime: false, // set true to force polling-only mode
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
listener.on('message', (msg) => {
|
|
143
|
+
console.log(`[${msg.thread_id}] ${msg.from}: ${msg.text}`)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
listener.on('connected', ({ userId, transport }) => {
|
|
147
|
+
// transport is 'realtime' or 'polling'
|
|
148
|
+
console.log(`Listening as ${userId} via ${transport}`)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
listener.on('error', (err) => console.error(err))
|
|
152
|
+
listener.on('disconnected', () => console.log('Stopped'))
|
|
153
|
+
|
|
154
|
+
await listener.start()
|
|
155
|
+
// listener.stop() to disconnect
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### Events
|
|
159
|
+
|
|
160
|
+
| Event | Payload | Description |
|
|
161
|
+
| -------------- | -------------------------------------------------------- | --------------------------------------------- |
|
|
162
|
+
| `message` | `InstagramMessageSummary` | New message received |
|
|
163
|
+
| `connected` | `{ userId: string; transport: 'realtime' \| 'polling' }` | Listener active; `transport` shows which path |
|
|
164
|
+
| `disconnected` | — | Listener stopped |
|
|
165
|
+
| `error` | `Error` | Network or API error |
|
|
166
|
+
|
|
167
|
+
### InstagramRealtimeListener
|
|
168
|
+
|
|
169
|
+
`InstagramRealtimeListener` connects directly over MQTToT with no polling fallback. Use this when you want pure realtime and prefer to handle reconnection yourself.
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import { InstagramClient, InstagramRealtimeListener } from 'agent-messenger/instagram'
|
|
173
|
+
|
|
174
|
+
const client = await new InstagramClient().login()
|
|
175
|
+
const listener = new InstagramRealtimeListener(client)
|
|
176
|
+
|
|
177
|
+
listener.on('message', (msg) => {
|
|
178
|
+
console.log(`[${msg.thread_id}] ${msg.from}: ${msg.text}`)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
listener.on('connected', ({ userId }) => {
|
|
182
|
+
console.log(`Listening as ${userId}`)
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
listener.on('error', (err) => console.error(err))
|
|
186
|
+
listener.on('disconnected', () => console.log('Disconnected'))
|
|
187
|
+
|
|
188
|
+
await listener.start()
|
|
189
|
+
// listener.stop() to disconnect
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### Events
|
|
193
|
+
|
|
194
|
+
| Event | Payload | Description |
|
|
195
|
+
| -------------- | ------------------------- | ----------------------------- |
|
|
196
|
+
| `message` | `InstagramMessageSummary` | New message received |
|
|
197
|
+
| `connected` | `{ userId: string }` | MQTToT connection established |
|
|
198
|
+
| `disconnected` | — | Connection closed |
|
|
199
|
+
| `error` | `Error` | Connection or protocol error |
|
|
200
|
+
|
|
201
|
+
### InstagramListener (Polling Only)
|
|
202
|
+
|
|
203
|
+
`InstagramListener` polls the Instagram inbox for new messages at a configurable interval. It's the original listener and remains available for environments where a persistent connection isn't suitable.
|
|
126
204
|
|
|
127
205
|
```typescript
|
|
128
206
|
import { InstagramClient, InstagramListener } from 'agent-messenger/instagram'
|
|
@@ -145,7 +223,7 @@ await listener.start()
|
|
|
145
223
|
// listener.stop() to disconnect
|
|
146
224
|
```
|
|
147
225
|
|
|
148
|
-
|
|
226
|
+
#### Events
|
|
149
227
|
|
|
150
228
|
| Event | Payload | Description |
|
|
151
229
|
| -------------- | ------------------------- | --------------------------------------- |
|
|
@@ -220,6 +298,9 @@ import type {
|
|
|
220
298
|
InstagramMessageSummary,
|
|
221
299
|
InstagramSessionState,
|
|
222
300
|
InstagramListenerEventMap,
|
|
301
|
+
InstagramRealtimeListenerEventMap,
|
|
302
|
+
InstagramHybridListenerEventMap,
|
|
303
|
+
InstagramHybridListenerOptions,
|
|
223
304
|
} from 'agent-messenger/instagram'
|
|
224
305
|
```
|
|
225
306
|
|
|
@@ -304,19 +385,23 @@ if (alice) {
|
|
|
304
385
|
|
|
305
386
|
### Message Monitor
|
|
306
387
|
|
|
307
|
-
Watch for new DMs using the
|
|
388
|
+
Watch for new DMs using the hybrid listener, which tries realtime first and falls back to polling automatically.
|
|
308
389
|
|
|
309
390
|
```typescript
|
|
310
|
-
import { InstagramClient,
|
|
391
|
+
import { InstagramClient, InstagramHybridListener } from 'agent-messenger/instagram'
|
|
311
392
|
|
|
312
393
|
const client = await new InstagramClient().login()
|
|
313
|
-
const listener = new
|
|
394
|
+
const listener = new InstagramHybridListener(client)
|
|
314
395
|
|
|
315
396
|
listener.on('message', (msg) => {
|
|
316
397
|
if (msg.is_outgoing) return
|
|
317
398
|
console.log(`New DM from ${msg.from}: ${msg.text ?? `[${msg.type}]`}`)
|
|
318
399
|
})
|
|
319
400
|
|
|
401
|
+
listener.on('connected', ({ userId, transport }) => {
|
|
402
|
+
console.log(`Listening as ${userId} via ${transport}`)
|
|
403
|
+
})
|
|
404
|
+
|
|
320
405
|
listener.on('error', (err) => {
|
|
321
406
|
console.error('Listener error:', err.message)
|
|
322
407
|
})
|
|
@@ -4,11 +4,11 @@ description: A unified terminal interface for all your messaging platforms in on
|
|
|
4
4
|
icon: Monitor
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
> **Experimental** — The TUI is a showcase of what's possible with Agent Messenger's SDK. It's not intended for production use, but demonstrates the power of having a unified adapter layer across
|
|
7
|
+
> **Experimental** — The TUI is a showcase of what's possible with Agent Messenger's SDK. It's not intended for production use, but demonstrates the power of having a unified adapter layer across 11 messaging platforms.
|
|
8
8
|
|
|
9
9
|
## What Is It?
|
|
10
10
|
|
|
11
|
-
The TUI (Terminal User Interface) is a `blessed`-based interactive terminal app that unifies all your messaging platforms into a single screen. Navigate between Slack, Discord, Teams, Webex, Telegram, WhatsApp, LINE, Instagram, KakaoTalk, and Channel Talk — all from your terminal.
|
|
11
|
+
The TUI (Terminal User Interface) is a `blessed`-based interactive terminal app that unifies all your messaging platforms into a single screen. Navigate between Slack, Discord, Teams, Webex, Telegram, WhatsApp, iMessage, LINE, Instagram, KakaoTalk, and Channel Talk — all from your terminal.
|
|
12
12
|
|
|
13
13
|

|
|
14
14
|
|
|
@@ -30,7 +30,7 @@ The TUI has three navigation levels and three input modes.
|
|
|
30
30
|
|
|
31
31
|
| Level | What it shows | How to enter |
|
|
32
32
|
| ------------- | ---------------------------------------------------------- | ------------------------------------------ |
|
|
33
|
-
| **Platform** | All
|
|
33
|
+
| **Platform** | All 11 platforms with online/offline status | Launch or press `Esc` from workspace level |
|
|
34
34
|
| **Workspace** | Workspaces for the selected platform (skipped if only one) | Select a platform |
|
|
35
35
|
| **Channel** | Channels in the current workspace | Select a workspace |
|
|
36
36
|
|
|
@@ -128,6 +128,7 @@ src/tui/
|
|
|
128
128
|
│ ├── webex-adapter.ts
|
|
129
129
|
│ ├── telegram-adapter.ts
|
|
130
130
|
│ ├── whatsapp-adapter.ts
|
|
131
|
+
│ ├── imessage-adapter.ts
|
|
131
132
|
│ ├── line-adapter.ts
|
|
132
133
|
│ ├── instagram-adapter.ts
|
|
133
134
|
│ ├── kakaotalk-adapter.ts
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-messenger",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Multi-platform messaging CLI for AI agents (Slack, Discord, Teams, Webex, Telegram, Telegram Bot, WhatsApp, LINE, Instagram, KakaoTalk, Channel Talk)",
|
|
3
|
+
"version": "2.28.0",
|
|
4
|
+
"description": "Multi-platform messaging CLI for AI agents (Slack, Discord, Teams, Webex, Telegram, Telegram Bot, WhatsApp, LINE, iMessage, Instagram, KakaoTalk, Channel Talk)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/agent-messenger/agent-messenger"
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"agent-channeltalkbot": "dist/src/platforms/channeltalkbot/cli.js",
|
|
12
12
|
"agent-discord": "dist/src/platforms/discord/cli.js",
|
|
13
13
|
"agent-discordbot": "dist/src/platforms/discordbot/cli.js",
|
|
14
|
+
"agent-imessage": "dist/src/platforms/imessage/cli.js",
|
|
14
15
|
"agent-instagram": "dist/src/platforms/instagram/cli.js",
|
|
15
16
|
"agent-kakaotalk": "dist/src/platforms/kakaotalk/cli.js",
|
|
16
17
|
"agent-line": "dist/src/platforms/line/cli.js",
|
|
@@ -65,6 +66,9 @@
|
|
|
65
66
|
"wechatbot": [
|
|
66
67
|
"./dist/src/platforms/wechatbot/index.d.ts"
|
|
67
68
|
],
|
|
69
|
+
"imessage": [
|
|
70
|
+
"./dist/src/platforms/imessage/index.d.ts"
|
|
71
|
+
],
|
|
68
72
|
"instagram": [
|
|
69
73
|
"./dist/src/platforms/instagram/index.d.ts"
|
|
70
74
|
],
|
|
@@ -132,6 +136,10 @@
|
|
|
132
136
|
"types": "./dist/src/platforms/wechatbot/index.d.ts",
|
|
133
137
|
"default": "./dist/src/platforms/wechatbot/index.js"
|
|
134
138
|
},
|
|
139
|
+
"./imessage": {
|
|
140
|
+
"types": "./dist/src/platforms/imessage/index.d.ts",
|
|
141
|
+
"default": "./dist/src/platforms/imessage/index.js"
|
|
142
|
+
},
|
|
135
143
|
"./instagram": {
|
|
136
144
|
"types": "./dist/src/platforms/instagram/index.d.ts",
|
|
137
145
|
"default": "./dist/src/platforms/instagram/index.js"
|
package/scripts/postbuild.ts
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
import { cpSync, readFileSync, writeFileSync } from 'node:fs'
|
|
1
|
+
import { cpSync, existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
'dist/src/cli.js',
|
|
5
|
-
'dist/src/platforms/slack/cli.js',
|
|
6
|
-
'dist/src/platforms/discord/cli.js',
|
|
7
|
-
'dist/src/platforms/teams/cli.js',
|
|
8
|
-
'dist/src/platforms/slackbot/cli.js',
|
|
9
|
-
'dist/src/platforms/channeltalk/cli.js',
|
|
10
|
-
'dist/src/platforms/channeltalkbot/cli.js',
|
|
11
|
-
'dist/src/platforms/telegram/cli.js',
|
|
12
|
-
'dist/src/platforms/telegrambot/cli.js',
|
|
13
|
-
]
|
|
3
|
+
const pkg = JSON.parse(readFileSync('package.json', 'utf8')) as { bin?: Record<string, string> }
|
|
14
4
|
|
|
5
|
+
const cliFiles = Object.values(pkg.bin ?? {}).map((entry) =>
|
|
6
|
+
entry.replace(/^\.\/src\//, 'dist/src/').replace(/\.ts$/, '.js'),
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
let updatedCount = 0
|
|
15
10
|
for (const file of cliFiles) {
|
|
11
|
+
if (!existsSync(file)) continue
|
|
16
12
|
const content = readFileSync(file, 'utf8')
|
|
17
|
-
|
|
18
|
-
writeFileSync(file,
|
|
13
|
+
if (!content.startsWith('#!/usr/bin/env bun')) continue
|
|
14
|
+
writeFileSync(file, content.replace('#!/usr/bin/env bun', '#!/usr/bin/env node'))
|
|
15
|
+
updatedCount++
|
|
19
16
|
}
|
|
20
17
|
|
|
21
|
-
console.log(`Updated shebang in ${
|
|
18
|
+
console.log(`Updated shebang in ${updatedCount} CLI files`)
|
|
22
19
|
|
|
23
20
|
cpSync('src/vendor', 'dist/src/vendor', { recursive: true })
|
|
24
21
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-channeltalk
|
|
3
3
|
description: Interact with Channel Talk using extracted desktop app or browser credentials - read chats, send messages, search messages, manage groups
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.28.0
|
|
5
5
|
allowed-tools: Bash(agent-channeltalk:*)
|
|
6
6
|
metadata:
|
|
7
7
|
openclaw:
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-imessage
|
|
3
|
+
description: Interact with iMessage on a Mac via the imsg tool - send messages, read chats, watch for new messages
|
|
4
|
+
version: 2.28.0
|
|
5
|
+
allowed-tools: Bash(agent-imessage:*)
|
|
6
|
+
metadata:
|
|
7
|
+
openclaw:
|
|
8
|
+
requires:
|
|
9
|
+
bins:
|
|
10
|
+
- agent-imessage
|
|
11
|
+
install:
|
|
12
|
+
- kind: node
|
|
13
|
+
package: agent-messenger
|
|
14
|
+
bins: [agent-imessage]
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Agent iMessage
|
|
18
|
+
|
|
19
|
+
An iMessage CLI for AI agents, backed by [imsg](https://github.com/openclaw/imsg) — a native macOS tool that reads the local Messages database and sends through Messages.app. Apple has no public iMessage API, so this integration runs **on a Mac** and drives Messages locally. You act as yourself with your own Apple ID; nothing leaves the machine.
|
|
20
|
+
|
|
21
|
+
Use one of these entrypoints:
|
|
22
|
+
- Global install: `agent-imessage ...`
|
|
23
|
+
- One-off execution: `bunx --package agent-messenger agent-imessage ...`
|
|
24
|
+
|
|
25
|
+
## Key Concepts
|
|
26
|
+
|
|
27
|
+
- **imsg** = a local Swift CLI (`brew install steipete/tap/imsg`). `agent-imessage` spawns it and talks to it over JSON-RPC (stdin/stdout). There is **no network and no server** — it must run on the Mac signed into iMessage.
|
|
28
|
+
- **On-Mac only** = unlike other agent-messenger platforms, this one cannot run remotely or in a container. The agent runs on the Mac itself.
|
|
29
|
+
- **Permissions** = imsg needs **Full Disk Access** (to read the Messages database) and **Automation → Messages** (to send). macOS grants these to the **parent process** — the app/terminal that launches agent-messenger.
|
|
30
|
+
- **Chat reference** = for `message send`, a chat id (integer rowid), a portable `guid`/`identifier` (e.g. `iMessage;-;+15551234567`), or a phone/email recipient. For `message list`/`react`/`watch --chat`, prefer a **chat id** — a guid also works but (since imsg has no guid→id lookup) is resolved against the 1000 most recent chats only.
|
|
31
|
+
- **Watch** = streams new messages via imsg; resumable from a message rowid with `--since-rowid`.
|
|
32
|
+
- **Multi-account** = each account is an imsg configuration (binary path / region). Send is single-account (Messages has no from-selector).
|
|
33
|
+
- **Private API tier** = typing, edit/unsend, group management, custom/targeted reactions require `imsg launch` (SIP disabled). Basic send/read/watch/standard tapbacks do NOT.
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Guided setup: checks imsg + permissions, saves an account
|
|
39
|
+
agent-imessage setup
|
|
40
|
+
|
|
41
|
+
# Diagnose anytime
|
|
42
|
+
agent-imessage doctor
|
|
43
|
+
|
|
44
|
+
# List chats (source of chat ids/guids)
|
|
45
|
+
agent-imessage chat list
|
|
46
|
+
|
|
47
|
+
# Send (to a chat id, guid, or a phone/email)
|
|
48
|
+
agent-imessage message send 42 "Hello from agent-imessage"
|
|
49
|
+
agent-imessage message send "+15551234567" "Hi"
|
|
50
|
+
|
|
51
|
+
# Read recent messages
|
|
52
|
+
agent-imessage message list 42 --limit 20
|
|
53
|
+
|
|
54
|
+
# Watch for new messages (resumable, JSON lines)
|
|
55
|
+
agent-imessage message watch --chat all --jsonl
|
|
56
|
+
|
|
57
|
+
# React to the most recent incoming message (standard tapbacks)
|
|
58
|
+
agent-imessage message react 42 love
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Setup & Permissions
|
|
62
|
+
|
|
63
|
+
iMessage runs on the Mac via imsg. One-time setup:
|
|
64
|
+
|
|
65
|
+
1. `brew install steipete/tap/imsg`
|
|
66
|
+
2. Sign Messages.app into your Apple ID (a dedicated Apple ID is recommended).
|
|
67
|
+
3. Grant **Full Disk Access** to the app/terminal launching agent-messenger (System Settings → Privacy & Security → Full Disk Access). macOS grants to the **parent process**.
|
|
68
|
+
4. Grant **Automation → Messages** when first prompted (needed to send).
|
|
69
|
+
|
|
70
|
+
See [setup](references/setup.md) and [permissions](references/permissions.md) references for detail.
|
|
71
|
+
|
|
72
|
+
Configuration is scriptable too:
|
|
73
|
+
```bash
|
|
74
|
+
agent-imessage auth set --bin /opt/homebrew/bin/imsg --region US --current
|
|
75
|
+
```
|
|
76
|
+
Environment overrides (runtime only, not persisted): `AGENT_IMESSAGE_BIN`, `AGENT_IMESSAGE_REGION`.
|
|
77
|
+
|
|
78
|
+
### Agent Behavior (MANDATORY)
|
|
79
|
+
|
|
80
|
+
When a command fails, the agent MUST run `agent-imessage doctor` and act on the `suggestion`/`code` rather than telling the user to run commands. If `code` is `imsg_not_found`, guide installing imsg. If `full_disk_access` or `automation_denied`, surface the exact System Settings path (and that macOS grants to the parent process). Never silently retry the same failing call.
|
|
81
|
+
|
|
82
|
+
## Commands
|
|
83
|
+
|
|
84
|
+
- `setup` — guided check + save account.
|
|
85
|
+
- `doctor [--account <id>] [--test-chat <chatId>]` — diagnose imsg + permissions.
|
|
86
|
+
- `auth set|list|use|remove|logout` — manage accounts (binary path / region).
|
|
87
|
+
- `chat list [--limit]` / `chat search <query> [--limit]`.
|
|
88
|
+
- `message list <chat> [--limit] [--start <iso>]` — read history (oldest-last). `<chat>` = chat id (recommended) or recent-chat guid.
|
|
89
|
+
- `message send <chat> <text>` — `<chat>` = chat id/guid or phone/email.
|
|
90
|
+
- `message react <chat> <reaction>` — standard tapback to the **most recent incoming** message.
|
|
91
|
+
- `message watch [--chat <ref|all>] [--since-rowid <n>] [--jsonl]` — stream new messages.
|
|
92
|
+
- `whoami` — active account + imsg status.
|
|
93
|
+
|
|
94
|
+
All commands accept `--account <id>` and `--pretty`.
|
|
95
|
+
|
|
96
|
+
## Output Format
|
|
97
|
+
|
|
98
|
+
JSON by default; `--pretty` for indented output. `message watch --jsonl` emits one JSON object per line.
|
|
99
|
+
|
|
100
|
+
## Feature Tiers
|
|
101
|
+
|
|
102
|
+
| Feature | Available | Requires |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| List/search chats, send text, read/watch messages | ✅ | imsg core (no SIP) |
|
|
105
|
+
| Standard tapbacks, to the most recent incoming message | ✅ | imsg core (no SIP) |
|
|
106
|
+
| React to a specific message / custom-emoji tapbacks | ⏳ planned | imsg bridge (`imsg launch` + SIP) |
|
|
107
|
+
| Typing, read receipts, edit/unsend, group management | ⏳ planned | imsg bridge (`imsg launch` + SIP) |
|
|
108
|
+
|
|
109
|
+
## Error Handling
|
|
110
|
+
|
|
111
|
+
Errors are JSON with a `code` and often a `suggestion`:
|
|
112
|
+
|
|
113
|
+
| Code | Meaning | Action |
|
|
114
|
+
| --- | --- | --- |
|
|
115
|
+
| `imsg_not_found` | imsg binary not runnable | `brew install steipete/tap/imsg` (or set `--bin`/`AGENT_IMESSAGE_BIN`). |
|
|
116
|
+
| `full_disk_access` | Can't read Messages DB | Grant Full Disk Access to the launching app (parent process). |
|
|
117
|
+
| `automation_denied` | Can't control Messages | Grant Automation → Messages in System Settings. |
|
|
118
|
+
| `not_authenticated` | No account configured | Run `agent-imessage setup`. |
|
|
119
|
+
| `chat_not_found` | Unknown chat ref | Use a chat id/guid from `chat list`. |
|
|
120
|
+
| `private_api_required` | Feature needs the bridge | Standard send/read/watch/tapbacks work without it; targeted/custom reactions need `imsg launch` (SIP off). |
|
|
121
|
+
| `invalid_limit` | Bad `--limit`/`--since-rowid` | Use an integer 1–100 for `--limit`; non-negative integer for `--since-rowid`. |
|
|
122
|
+
| `send_failed` | imsg could not send | Run `doctor`; on macOS 26 group sends can fail (imsg reports honestly). |
|
|
123
|
+
| `rpc_error` | imsg rpc problem | Run `doctor`; check the imsg version. |
|
|
124
|
+
|
|
125
|
+
## Troubleshooting
|
|
126
|
+
|
|
127
|
+
- **`agent-imessage doctor`** is the fastest diagnostic — it reports imsg version, Full Disk Access, and the bridge tier.
|
|
128
|
+
- **Permissions denied** — remember macOS grants Full Disk Access / Automation to the **parent** process (the terminal or agent runtime), not just `imsg`.
|
|
129
|
+
- **Reactions only hit the latest message** — that's an imsg/AppleScript limitation without the bridge; reacting to a specific message needs `imsg launch` + SIP off.
|
|
130
|
+
|
|
131
|
+
## Configuration
|
|
132
|
+
|
|
133
|
+
Account config is stored in `~/.config/agent-messenger/imessage-credentials.json` (mode `0600`). Relocate via `AGENT_MESSENGER_CONFIG_DIR`. No secrets are stored — imsg uses macOS permissions, not tokens.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Authentication
|
|
2
|
+
|
|
3
|
+
iMessage authentication is unlike the other platforms: there are **no tokens, cookies, or login flow**. `agent-imessage` drives the local [imsg](https://github.com/openclaw/imsg) tool, which relies on **macOS permissions** (Full Disk Access + Automation) granted to the process that launches it. "Authentication" here means: imsg is installed, Messages.app is signed into your Apple ID, and the permissions are granted.
|
|
4
|
+
|
|
5
|
+
## What gets stored
|
|
6
|
+
|
|
7
|
+
The credential manager stores an **account record with no secrets** in `~/.config/agent-messenger/imessage-credentials.json` (mode `0600`):
|
|
8
|
+
|
|
9
|
+
```jsonc
|
|
10
|
+
{
|
|
11
|
+
"current": "default",
|
|
12
|
+
"accounts": {
|
|
13
|
+
"default": {
|
|
14
|
+
"account_id": "default",
|
|
15
|
+
"provider": "imsg", // backend-agnostic discriminator
|
|
16
|
+
"binary_path": "/opt/homebrew/bin/imsg", // optional; defaults to "imsg" on PATH
|
|
17
|
+
"region": "US", // optional; default region for local-format phone numbers
|
|
18
|
+
"created_at": "…",
|
|
19
|
+
"updated_at": "…"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
There is no password/token field — access is governed entirely by macOS TCC permissions.
|
|
26
|
+
|
|
27
|
+
## Configuring an account
|
|
28
|
+
|
|
29
|
+
Guided:
|
|
30
|
+
```bash
|
|
31
|
+
agent-imessage setup # verifies imsg + permissions (honors --bin/--region), then saves
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Scriptable:
|
|
35
|
+
```bash
|
|
36
|
+
agent-imessage auth set --bin /opt/homebrew/bin/imsg --region US --current
|
|
37
|
+
agent-imessage auth status # via: agent-imessage doctor
|
|
38
|
+
agent-imessage auth list
|
|
39
|
+
agent-imessage auth use <account-id>
|
|
40
|
+
agent-imessage auth remove <account-id>
|
|
41
|
+
agent-imessage auth logout # clears all stored accounts
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Credential resolution order
|
|
45
|
+
|
|
46
|
+
When a command runs, the active configuration is resolved as:
|
|
47
|
+
|
|
48
|
+
1. `--account <id>` (explicit account selection), then
|
|
49
|
+
2. `AGENT_IMESSAGE_BIN` / `AGENT_IMESSAGE_REGION` environment variables (runtime override — **never persisted to disk**), then
|
|
50
|
+
3. the stored **current** account, then
|
|
51
|
+
4. defaults (`imsg` on PATH, no region).
|
|
52
|
+
|
|
53
|
+
If nothing resolves, commands exit with `{ "code": "not_authenticated" }` and point to `agent-imessage setup`.
|
|
54
|
+
|
|
55
|
+
## Permissions (the real "auth")
|
|
56
|
+
|
|
57
|
+
imsg needs two macOS permissions, granted to the **parent process** (the terminal / agent runtime that launches `agent-messenger`), not to `imsg` in isolation:
|
|
58
|
+
|
|
59
|
+
- **Full Disk Access** — to read `~/Library/Messages/chat.db`. Missing → `{ "code": "full_disk_access" }`.
|
|
60
|
+
- **Automation → Messages** — to send. Missing → `{ "code": "automation_denied" }`.
|
|
61
|
+
|
|
62
|
+
These are user-consent TCC grants and **cannot be scripted**. See [permissions](permissions.md) for the exact steps and the parent-process caveat. Run `agent-imessage doctor` to check status.
|
|
63
|
+
|
|
64
|
+
## Multi-account
|
|
65
|
+
|
|
66
|
+
Each account is an imsg configuration (binary path + default region). Messages.app has no from-selector, so **send is single-account per Mac**; multiple accounts are only meaningful if you run distinct imsg setups.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# macOS Permissions for imsg
|
|
2
|
+
|
|
3
|
+
`agent-imessage` drives [imsg](https://github.com/openclaw/imsg), which needs two macOS permissions. These are TCC (Transparency, Consent, and Control) grants that **cannot be scripted** — a human must approve them once in System Settings.
|
|
4
|
+
|
|
5
|
+
## Full Disk Access (required for everything)
|
|
6
|
+
|
|
7
|
+
imsg reads the Messages database at `~/Library/Messages/chat.db`, which macOS protects behind Full Disk Access.
|
|
8
|
+
|
|
9
|
+
- **Grant to:** the app/terminal/agent-runtime that launches `agent-messenger` — **the parent process**, not `imsg` alone.
|
|
10
|
+
- **Where:** System Settings → Privacy & Security → Full Disk Access → enable your terminal/app → restart it.
|
|
11
|
+
- **Symptom when missing:** `agent-imessage doctor` reports `full_disk_access: denied`; commands return `{ "code": "full_disk_access" }`.
|
|
12
|
+
|
|
13
|
+
## Automation → Messages (required to send)
|
|
14
|
+
|
|
15
|
+
Sending uses AppleScript automation of Messages.app.
|
|
16
|
+
|
|
17
|
+
- **Grant to:** same parent process.
|
|
18
|
+
- **Where:** System Settings → Privacy & Security → Automation → (your app) → enable **Messages**. macOS prompts automatically on the first send attempt.
|
|
19
|
+
- **Symptom when missing:** sends fail with `{ "code": "automation_denied" }`.
|
|
20
|
+
|
|
21
|
+
## Contacts (optional)
|
|
22
|
+
|
|
23
|
+
Used only to resolve sender names. Nothing breaks without it; `from_name` is simply absent.
|
|
24
|
+
|
|
25
|
+
## Why these can't be automated
|
|
26
|
+
|
|
27
|
+
TCC grants are deliberately user-consent-only. `tccutil` can reset permissions but cannot grant them, and the TCC database is protected by SIP. There is no supported way to grant Full Disk Access or Automation programmatically on an unmanaged Mac — plan for a one-time manual approval (a quick Screen Sharing/VNC session works for a headless Mac).
|
|
28
|
+
|
|
29
|
+
## SIP and the advanced bridge
|
|
30
|
+
|
|
31
|
+
Core features (send/read/watch/standard tapbacks) need **no SIP changes**. Only the advanced bridge (`imsg launch`: typing, edit/unsend, group management, targeted/custom reactions) requires **disabling SIP**, which is a separate, deliberate step and out of scope for the core `agent-imessage` features.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# imsg Setup (Operator Guide)
|
|
2
|
+
|
|
3
|
+
iMessage has no public API. `agent-imessage` runs **on a Mac** and uses [imsg](https://github.com/openclaw/imsg) — a native Swift CLI — to read the local Messages database and send through Messages.app. The agent must run on the same Mac (imsg is local-only; there is no network/server).
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- **macOS 14+** (Sonoma or newer). imsg supports macOS 26/Tahoe with caveats (group sends via AppleScript can fail; imsg reports the failure honestly rather than lying).
|
|
8
|
+
- **Messages.app signed in** to your Apple ID. A **dedicated Apple ID** is recommended to avoid mixing automated traffic with your personal account.
|
|
9
|
+
- **imsg installed**: `brew install steipete/tap/imsg`.
|
|
10
|
+
- **Full Disk Access** and **Automation → Messages** permissions (see below).
|
|
11
|
+
|
|
12
|
+
## One-time setup
|
|
13
|
+
|
|
14
|
+
1. **Install imsg**
|
|
15
|
+
```bash
|
|
16
|
+
brew install steipete/tap/imsg
|
|
17
|
+
imsg --version
|
|
18
|
+
```
|
|
19
|
+
2. **Sign Messages.app into iMessage** with your (dedicated) Apple ID.
|
|
20
|
+
3. **Grant Full Disk Access** — System Settings → Privacy & Security → Full Disk Access → add the app/terminal that will launch `agent-messenger`. This is required to read `~/Library/Messages/chat.db`.
|
|
21
|
+
4. **Grant Automation → Messages** — triggered on first send; approve the prompt (System Settings → Privacy & Security → Automation → Messages).
|
|
22
|
+
5. **Verify and save an account**
|
|
23
|
+
```bash
|
|
24
|
+
agent-imessage setup # guided: checks imsg + permissions, saves account
|
|
25
|
+
agent-imessage doctor # re-check anytime
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### The parent-process permission caveat (important)
|
|
29
|
+
|
|
30
|
+
macOS grants Full Disk Access and Automation to the **process that launches imsg** — i.e. the terminal, IDE, or agent runtime that runs `agent-imessage`, not `imsg` in isolation. If `doctor` reports `full_disk_access: denied`, grant Full Disk Access to **that launching app** and restart it.
|
|
31
|
+
|
|
32
|
+
## Feature tiers
|
|
33
|
+
|
|
34
|
+
- **Core (no SIP):** list/search chats, read history, send text, watch new messages, standard tapbacks (to the most recent incoming message). This is all that `agent-imessage` v1 uses.
|
|
35
|
+
- **Bridge (advanced):** typing indicators, read receipts, edit/unsend, group create/rename/members, and reacting to a *specific* message or with custom emoji. These require `imsg launch` (which injects into IMCore) and **disabling SIP**. Not used by v1; documented for completeness.
|
|
36
|
+
|
|
37
|
+
## Multi-account
|
|
38
|
+
|
|
39
|
+
Each `agent-imessage` account is an imsg configuration (binary path + default region). Messages.app has no from-selector, so **send is single-account** per Mac. Configure additional accounts only if you run multiple imsg binaries/setups:
|
|
40
|
+
```bash
|
|
41
|
+
agent-imessage auth set --bin /opt/homebrew/bin/imsg --region US --account home --current
|
|
42
|
+
agent-imessage auth use home
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Reliability notes
|
|
46
|
+
|
|
47
|
+
- The Mac must stay awake and logged in for live `watch` to keep receiving.
|
|
48
|
+
- imsg's watcher uses filesystem events + polling and re-arms across Messages database (WAL) rotation, so it keeps up on busy/iCloud-synced databases.
|
|
49
|
+
- Pin macOS updates if stability matters — major updates can change AppleScript/IMCore behavior.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-instagram
|
|
3
3
|
description: Interact with Instagram DMs - send messages, read conversations, manage accounts
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.28.0
|
|
5
5
|
allowed-tools: Bash(agent-instagram:*)
|
|
6
6
|
metadata:
|
|
7
7
|
openclaw:
|
|
@@ -27,7 +27,7 @@ Use one of these entrypoints:
|
|
|
27
27
|
- **Thread ID** = Instagram's identifier for a DM conversation. Numeric string returned by `chat list`.
|
|
28
28
|
- **Browser cookie extraction** = recommended auth method. Extracts cookies from Chromium browsers (Chrome, Chrome Canary, Edge, Arc, Brave, Vivaldi, Chromium) where you're logged into instagram.com. Zero-config.
|
|
29
29
|
- **Username/password auth** = fallback method. Authenticates using Instagram credentials. Supports two-factor authentication via SMS or authenticator app.
|
|
30
|
-
- **HTTP-based** = each command makes HTTP requests and returns. No persistent connection or background process.
|
|
30
|
+
- **HTTP-based** = each CLI command makes HTTP requests and returns. No persistent connection or background process. The SDK additionally offers real-time listeners (`InstagramHybridListener`, `InstagramRealtimeListener`) for streaming DMs — see [SDK: Real-Time Events](#sdk-real-time-events) below.
|
|
31
31
|
- **Multi-account** = multiple Instagram accounts can be stored. Use `auth list` and `auth use` to switch between them.
|
|
32
32
|
- **DM-only** = this CLI focuses on Instagram Direct Messages. It does not manage posts, stories, or followers.
|
|
33
33
|
|
|
@@ -440,3 +440,73 @@ Instagram invalidates sessions based on device fingerprinting and activity patte
|
|
|
440
440
|
1. Avoid frequent re-authentication
|
|
441
441
|
2. Space out API calls
|
|
442
442
|
3. Don't switch between multiple IP addresses rapidly
|
|
443
|
+
|
|
444
|
+
## SDK: Real-Time Events
|
|
445
|
+
|
|
446
|
+
`InstagramHybridListener` connects over Instagram's MQTToT transport (a persistent TLS connection to `edge-mqtt.facebook.com`) and falls back to polling automatically if the connection fails. It retries realtime with capped exponential backoff. This is the recommended listener for most use cases.
|
|
447
|
+
|
|
448
|
+
`InstagramRealtimeListener` is the pure-realtime option with no polling fallback — use it when you want direct MQTToT and prefer to handle reconnection yourself.
|
|
449
|
+
|
|
450
|
+
Both use the unofficial private API, the same risk surface as the existing polling listener.
|
|
451
|
+
|
|
452
|
+
### Setup
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
import { InstagramClient, InstagramHybridListener } from 'agent-messenger/instagram'
|
|
456
|
+
|
|
457
|
+
const client = await new InstagramClient().login()
|
|
458
|
+
const listener = new InstagramHybridListener(client, {
|
|
459
|
+
pollInterval: 5000, // fallback poll interval in ms
|
|
460
|
+
realtimeRetryBaseMs: 2000, // backoff base for realtime reconnect
|
|
461
|
+
realtimeRetryMaxMs: 60000, // backoff cap
|
|
462
|
+
})
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Or for pure realtime:
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
import { InstagramClient, InstagramRealtimeListener } from 'agent-messenger/instagram'
|
|
469
|
+
|
|
470
|
+
const client = await new InstagramClient().login()
|
|
471
|
+
const listener = new InstagramRealtimeListener(client)
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Listening for Events
|
|
475
|
+
|
|
476
|
+
```typescript
|
|
477
|
+
listener.on('connected', ({ userId, transport }) => {
|
|
478
|
+
// transport is 'realtime' or 'polling' (hybrid only)
|
|
479
|
+
console.log(`Listening as ${userId} via ${transport}`)
|
|
480
|
+
})
|
|
481
|
+
|
|
482
|
+
listener.on('message', (msg) => {
|
|
483
|
+
// msg.id, msg.thread_id, msg.from, msg.timestamp
|
|
484
|
+
// msg.is_outgoing, msg.type, msg.text, msg.media_url
|
|
485
|
+
if (msg.is_outgoing) return
|
|
486
|
+
console.log(`[${msg.thread_id}] ${msg.from}: ${msg.text}`)
|
|
487
|
+
})
|
|
488
|
+
|
|
489
|
+
listener.on('error', (err) => {
|
|
490
|
+
console.error(err.message)
|
|
491
|
+
})
|
|
492
|
+
|
|
493
|
+
listener.on('disconnected', () => {
|
|
494
|
+
// hybrid listener retries realtime automatically
|
|
495
|
+
})
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Lifecycle
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
await listener.start() // connects via MQTToT (or starts polling fallback)
|
|
502
|
+
listener.stop() // clean shutdown
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Event Types
|
|
506
|
+
|
|
507
|
+
| Event | Payload (Hybrid) | Payload (Realtime / Polling) | Description |
|
|
508
|
+
| -------------- | --------------------------------------------------------- | ---------------------------- | ------------------------------ |
|
|
509
|
+
| `message` | `InstagramMessageSummary` | `InstagramMessageSummary` | New DM received |
|
|
510
|
+
| `connected` | `{ userId: string; transport: 'realtime' \| 'polling' }` | `{ userId: string }` | Listener active |
|
|
511
|
+
| `disconnected` | — | — | Connection closed |
|
|
512
|
+
| `error` | `Error` | `Error` | Connection or API error |
|