Skip to content

Commit 076f244

Browse files
committed
Add watch alert bridge endpoint for urgent alert testing
1 parent a439cf4 commit 076f244

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

admin/server.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ function adb(args, opts = {}) {
3838
});
3939
}
4040

41+
function resolveWatchTarget() {
42+
if (watchTarget) return watchTarget;
43+
try {
44+
const out = execFileSync('adb', ['devices'], { timeout: 5000, encoding: 'utf8' });
45+
const online = out
46+
.split('\n')
47+
.filter(l => l.includes('\tdevice'))
48+
.map(l => l.split('\t')[0].trim())
49+
.filter(Boolean);
50+
if (online.length > 0) {
51+
watchTarget = online[0];
52+
saveState({ watchTarget });
53+
return watchTarget;
54+
}
55+
} catch {}
56+
return null;
57+
}
58+
4159
// ── Watch ADB connection ──────────────────────────────
4260

4361
app.get('/api/watch', (req, res) => {
@@ -80,6 +98,41 @@ app.post('/api/watch/connect', (req, res) => {
8098
}
8199
});
82100

101+
// Trigger urgent alert on the connected watch (for server-initiated alert bridge testing)
102+
app.post('/api/watch/alert', (req, res) => {
103+
const requiredKey = process.env.CLAWWATCH_ALERT_KEY;
104+
const suppliedKey = req.headers['x-clawwatch-alert-key'];
105+
if (requiredKey && suppliedKey !== requiredKey) {
106+
return res.status(401).json({ ok: false, error: 'Unauthorized alert bridge call' });
107+
}
108+
109+
const payload = req.body || {};
110+
const eventId = String(payload.event_id || `evt-${Date.now()}`);
111+
const title = String(payload.title || 'URGENT alert');
112+
const body = String(payload.body || payload.prompt || 'Open ClawWatch for details.');
113+
const room = String(payload.room || '');
114+
const prompt = String(payload.prompt || body);
115+
const target = resolveWatchTarget();
116+
if (!target) return res.json({ ok: false, error: 'Watch target not set. Connect watch first.' });
117+
118+
try {
119+
execFileSync('adb', ['-s', target, ...[
120+
'shell', 'am', 'start',
121+
'-n', `${PKG}/.MainActivity`,
122+
'-a', 'com.thinkoff.clawwatch.ALERT_OPEN',
123+
'--es', 'alert_event_id', eventId,
124+
'--es', 'alert_title', title,
125+
'--es', 'alert_body', body,
126+
'--es', 'alert_room', room,
127+
'--es', 'alert_prompt', prompt
128+
]], { timeout: 8000, encoding: 'utf8' });
129+
130+
return res.json({ ok: true, dispatched: true, target, event_id: eventId });
131+
} catch (e) {
132+
return res.json({ ok: false, error: e.message, target });
133+
}
134+
});
135+
83136
// ── nullclaw.json config (asset file on Mac) ──────────
84137

85138
app.get('/api/config', (req, res) => {

0 commit comments

Comments
 (0)