atxp 1.23.1 → 1.24.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/commands/notifications.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/commands/notifications.ts"],"names":[],"mappings":"AAoRA,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe5E"}
|
|
@@ -3,71 +3,170 @@ import fs from 'fs/promises';
|
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import { execSync } from 'child_process';
|
|
5
5
|
const NOTIFICATIONS_BASE_URL = 'https://clowdbot-notifications.corp.circuitandchisel.com';
|
|
6
|
+
const OPENCLAW_CONFIG_PATH = '/data/.openclaw/openclaw.json';
|
|
7
|
+
const SESSIONS_PATH = '/data/.openclaw/agents/main/sessions/sessions.json';
|
|
8
|
+
const WORKSPACE_DIR = '/data/.openclaw/workspace';
|
|
9
|
+
const HEARTBEAT_SECTION_HEADER = '# ATXP Notification Relay';
|
|
10
|
+
// eslint-disable-next-line no-control-regex
|
|
11
|
+
const sanitizeSessionValue = (s) => s.replace(/[\x00-\x1f"`[\]]/g, '');
|
|
6
12
|
/**
|
|
7
|
-
*
|
|
13
|
+
* Discover connected messaging channels by reading the local session store.
|
|
14
|
+
* Parses session keys like "agent:main:telegram:direct:8204320066" to extract
|
|
15
|
+
* the channel type and peer ID for each active DM session.
|
|
16
|
+
*/
|
|
17
|
+
async function discoverConnectedChannels() {
|
|
18
|
+
try {
|
|
19
|
+
const raw = await fs.readFile(SESSIONS_PATH, 'utf-8');
|
|
20
|
+
const sessions = JSON.parse(raw);
|
|
21
|
+
const channels = [];
|
|
22
|
+
const seen = new Set();
|
|
23
|
+
for (const key of Object.keys(sessions)) {
|
|
24
|
+
// Match DM session keys: agent:main:<channel>:direct:<peerId>
|
|
25
|
+
const match = key.match(/^agent:main:([^:]+):direct:(.+)$/);
|
|
26
|
+
if (!match)
|
|
27
|
+
continue;
|
|
28
|
+
const channel = sanitizeSessionValue(match[1]).slice(0, 64);
|
|
29
|
+
const to = sanitizeSessionValue(match[2]).slice(0, 128);
|
|
30
|
+
if (!channel || !to)
|
|
31
|
+
continue;
|
|
32
|
+
// Skip ephemeral channels (webchat has no persistent address)
|
|
33
|
+
if (channel === 'webchat')
|
|
34
|
+
continue;
|
|
35
|
+
const dedupKey = `${channel}:${to}`;
|
|
36
|
+
if (seen.has(dedupKey))
|
|
37
|
+
continue;
|
|
38
|
+
seen.add(dedupKey);
|
|
39
|
+
channels.push({ channel, to });
|
|
40
|
+
}
|
|
41
|
+
return channels;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return []; // sessions file may not exist yet
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build the HEARTBEAT.md content with notification relay instructions.
|
|
49
|
+
* The default heartbeat prompt says "Read HEARTBEAT.md if it exists. Follow it strictly."
|
|
50
|
+
* so writing these instructions directly to the file ensures the LLM relays
|
|
51
|
+
* system events to all discovered channels.
|
|
52
|
+
*/
|
|
53
|
+
function buildHeartbeatMd(channels) {
|
|
54
|
+
const lines = [
|
|
55
|
+
HEARTBEAT_SECTION_HEADER,
|
|
56
|
+
'',
|
|
57
|
+
'When you see System: event lines about new emails or SMS messages,',
|
|
58
|
+
'you MUST immediately relay each one to the user.',
|
|
59
|
+
'Do NOT reply HEARTBEAT_OK when System events are present.',
|
|
60
|
+
'',
|
|
61
|
+
];
|
|
62
|
+
if (channels.length > 0) {
|
|
63
|
+
lines.push('Relay to ALL of these channels:');
|
|
64
|
+
for (const c of channels) {
|
|
65
|
+
lines.push(`- Use the message tool with channel=\`${c.channel}\` and target=\`${c.to}\``);
|
|
66
|
+
}
|
|
67
|
+
lines.push('');
|
|
68
|
+
}
|
|
69
|
+
return lines.join('\n');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Configure hooks, heartbeat delivery target, and HEARTBEAT.md on the instance.
|
|
8
73
|
* Only runs when inside a Fly instance (FLY_MACHINE_ID is set).
|
|
9
|
-
*
|
|
74
|
+
*
|
|
75
|
+
* Discovers all connected messaging channels from the session store, writes
|
|
76
|
+
* HEARTBEAT.md with relay instructions for each channel, and sets the primary
|
|
77
|
+
* delivery target to the first discovered channel.
|
|
10
78
|
*/
|
|
11
79
|
async function configureHooksOnInstance(hooksToken) {
|
|
12
80
|
if (!process.env.FLY_MACHINE_ID)
|
|
13
81
|
return;
|
|
14
|
-
const configPath =
|
|
82
|
+
const configPath = OPENCLAW_CONFIG_PATH;
|
|
15
83
|
try {
|
|
16
84
|
const raw = await fs.readFile(configPath, 'utf-8');
|
|
17
85
|
const config = JSON.parse(raw);
|
|
86
|
+
// Discover connected channels from session store
|
|
87
|
+
const channels = await discoverConnectedChannels();
|
|
88
|
+
let changed = false;
|
|
89
|
+
// Configure hooks
|
|
18
90
|
if (!config.hooks)
|
|
19
91
|
config.hooks = {};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
config.hooks.token = hooksToken;
|
|
25
|
-
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
26
|
-
console.log(chalk.gray('Hooks configured in openclaw.json'));
|
|
27
|
-
// Restart gateway to pick up new config (watchdog auto-restarts it)
|
|
28
|
-
try {
|
|
29
|
-
execSync('pkill -f openclaw-gateway', { stdio: 'ignore' });
|
|
30
|
-
console.log(chalk.gray('Gateway restarting to apply hooks config...'));
|
|
92
|
+
if (config.hooks.token !== hooksToken || config.hooks.enabled !== true) {
|
|
93
|
+
config.hooks.enabled = true;
|
|
94
|
+
config.hooks.token = hooksToken;
|
|
95
|
+
changed = true;
|
|
31
96
|
}
|
|
32
|
-
|
|
33
|
-
|
|
97
|
+
// Set primary delivery target to first discovered channel
|
|
98
|
+
if (!config.agents)
|
|
99
|
+
config.agents = {};
|
|
100
|
+
if (!config.agents.defaults)
|
|
101
|
+
config.agents.defaults = {};
|
|
102
|
+
if (!config.agents.defaults.heartbeat)
|
|
103
|
+
config.agents.defaults.heartbeat = {};
|
|
104
|
+
const hb = config.agents.defaults.heartbeat;
|
|
105
|
+
if (channels.length > 0) {
|
|
106
|
+
const primary = channels[0];
|
|
107
|
+
if (hb.target !== primary.channel || hb.to !== primary.to) {
|
|
108
|
+
hb.target = primary.channel;
|
|
109
|
+
hb.to = primary.to;
|
|
110
|
+
changed = true;
|
|
111
|
+
}
|
|
34
112
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
113
|
+
else if (hb.target !== 'last') {
|
|
114
|
+
// No channels discovered — fall back to 'last' and clear stale target
|
|
115
|
+
hb.target = 'last';
|
|
116
|
+
delete hb.to;
|
|
117
|
+
changed = true;
|
|
118
|
+
}
|
|
119
|
+
if (changed) {
|
|
120
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
121
|
+
console.log(chalk.gray('Hooks and heartbeat configured in openclaw.json'));
|
|
122
|
+
}
|
|
123
|
+
// Append notification relay instructions to HEARTBEAT.md.
|
|
124
|
+
// The default heartbeat prompt reads this file and follows it strictly.
|
|
125
|
+
await fs.mkdir(WORKSPACE_DIR, { recursive: true });
|
|
126
|
+
const heartbeatPath = `${WORKSPACE_DIR}/HEARTBEAT.md`;
|
|
127
|
+
const section = buildHeartbeatMd(channels);
|
|
128
|
+
let existing = '';
|
|
129
|
+
try {
|
|
130
|
+
existing = await fs.readFile(heartbeatPath, 'utf-8');
|
|
131
|
+
}
|
|
132
|
+
catch { /* file may not exist */ }
|
|
133
|
+
// Replace existing notification section or append if not present.
|
|
134
|
+
// Uses split-on-header to avoid regex edge cases with anchors/newlines.
|
|
135
|
+
const idx = existing.indexOf(HEARTBEAT_SECTION_HEADER);
|
|
136
|
+
if (idx !== -1) {
|
|
137
|
+
let before = existing.slice(0, idx);
|
|
138
|
+
// Ensure a newline separates preceding content from our section
|
|
139
|
+
if (before.length > 0 && !before.endsWith('\n'))
|
|
140
|
+
before += '\n';
|
|
141
|
+
const afterHeader = existing.slice(idx + HEARTBEAT_SECTION_HEADER.length);
|
|
142
|
+
// Find next top-level heading. Assumes a preceding newline (standard markdown).
|
|
143
|
+
const nextHeading = afterHeader.search(/\n# /);
|
|
144
|
+
const after = nextHeading !== -1 ? afterHeader.slice(nextHeading) : '';
|
|
145
|
+
await fs.writeFile(heartbeatPath, before + section.trimEnd() + after);
|
|
64
146
|
}
|
|
65
147
|
else {
|
|
66
|
-
|
|
148
|
+
const separator = existing.length > 0 && !existing.endsWith('\n') ? '\n\n' : existing.length > 0 ? '\n' : '';
|
|
149
|
+
await fs.writeFile(heartbeatPath, existing + separator + section);
|
|
150
|
+
}
|
|
151
|
+
console.log(chalk.gray('HEARTBEAT.md updated with notification relay instructions'));
|
|
152
|
+
if (channels.length > 0) {
|
|
153
|
+
console.log(chalk.gray(`Notification channels: ${channels.map(c => `${c.channel}:${c.to}`).join(', ')}`));
|
|
154
|
+
}
|
|
155
|
+
// Restart gateway to pick up new config (watchdog auto-restarts it)
|
|
156
|
+
if (changed) {
|
|
157
|
+
try {
|
|
158
|
+
execSync('pkill -f openclaw-gateway', { stdio: 'ignore' });
|
|
159
|
+
console.log(chalk.gray('Gateway restarting to apply config...'));
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Gateway may not be running yet — config will be picked up on next start
|
|
163
|
+
}
|
|
67
164
|
}
|
|
68
165
|
}
|
|
69
|
-
catch {
|
|
70
|
-
console.log(chalk.
|
|
166
|
+
catch (err) {
|
|
167
|
+
console.log(chalk.yellow('Warning: Could not configure instance locally.'));
|
|
168
|
+
console.log(chalk.gray(`${err instanceof Error ? err.message : err}`));
|
|
169
|
+
console.log(chalk.gray('Hooks will be configured on next instance reboot.'));
|
|
71
170
|
}
|
|
72
171
|
}
|
|
73
172
|
function getMachineId() {
|
|
@@ -83,9 +182,14 @@ function getMachineId() {
|
|
|
83
182
|
return undefined;
|
|
84
183
|
}
|
|
85
184
|
async function getAccountId() {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
185
|
+
try {
|
|
186
|
+
const { getAccountInfo } = await import('./whoami.js');
|
|
187
|
+
const account = await getAccountInfo();
|
|
188
|
+
return account?.accountId;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
89
193
|
}
|
|
90
194
|
async function enableNotifications() {
|
|
91
195
|
const machineId = getMachineId();
|
|
@@ -100,11 +204,19 @@ async function enableNotifications() {
|
|
|
100
204
|
const body = { machine_id: machineId };
|
|
101
205
|
if (accountId)
|
|
102
206
|
body.account_id = accountId;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
207
|
+
let res;
|
|
208
|
+
try {
|
|
209
|
+
res = await fetch(`${NOTIFICATIONS_BASE_URL}/notifications/enable`, {
|
|
210
|
+
method: 'POST',
|
|
211
|
+
headers: { 'Content-Type': 'application/json' },
|
|
212
|
+
body: JSON.stringify(body),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
console.error(chalk.red(`Error: Could not reach notifications service.`));
|
|
217
|
+
console.error(chalk.gray(`${err instanceof Error ? err.message : err}`));
|
|
218
|
+
process.exit(1);
|
|
219
|
+
}
|
|
108
220
|
const data = await res.json().catch(() => ({}));
|
|
109
221
|
if (!res.ok) {
|
|
110
222
|
console.error(chalk.red(`Error: ${data.error || res.statusText}`));
|
|
@@ -128,8 +240,6 @@ async function enableNotifications() {
|
|
|
128
240
|
console.log(chalk.gray('Save the secret — it will not be shown again.'));
|
|
129
241
|
console.log(chalk.gray('Use it to verify webhook signatures (HMAC-SHA256).'));
|
|
130
242
|
}
|
|
131
|
-
// Send one-time HEARTBEAT.md instruction to the agent
|
|
132
|
-
await sendHeartbeatInstruction(instance.webhookUrl, instance.hooksToken);
|
|
133
243
|
}
|
|
134
244
|
function showNotificationsHelp() {
|
|
135
245
|
console.log(chalk.bold('Notifications Commands:'));
|
|
@@ -138,6 +248,7 @@ function showNotificationsHelp() {
|
|
|
138
248
|
console.log();
|
|
139
249
|
console.log(chalk.bold('Available Events:'));
|
|
140
250
|
console.log(' ' + chalk.green('email.received') + ' ' + 'Triggered when an inbound email arrives');
|
|
251
|
+
console.log(' ' + chalk.green('sms.received') + ' ' + 'Triggered when an inbound SMS arrives');
|
|
141
252
|
console.log();
|
|
142
253
|
console.log(chalk.bold('Examples:'));
|
|
143
254
|
console.log(' npx atxp notifications enable');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/commands/notifications.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,sBAAsB,GAAG,0DAA0D,CAAC;
|
|
1
|
+
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/commands/notifications.ts"],"names":[],"mappings":"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"}
|