Inbox injection endpoint: POST /api/messages + MCP inject_message (#12) (#18)
CI / build + unit (push) Successful in 1m14s

This commit was merged in pull request #18.
This commit is contained in:
2026-09-25 01:51:50 +02:00
parent 0571c7095e
commit 756086d107
10 changed files with 253 additions and 7 deletions
+26
View File
@@ -23,6 +23,7 @@ import {
extractFrames,
frame,
loadHwModelNames,
randomPacketId,
} from './codec.js';
/** One entry in the message history: an inbound text (dir 'rx') or one of our sends (dir 'tx'). */
@@ -303,6 +304,31 @@ export class MeshService implements OnModuleInit, OnModuleDestroy {
return [...this.history].reverse();
}
/**
* Inject a synthetic inbound (rx) record into the message history — as if received on the mesh.
* NOT transmitted over RF: nothing is written to the bridge or air; the record exists so external
* systems can push messages into the bot's inbox to trigger communication later. `from` is optional
* (integer in 1..0xffffffff when provided) and omitted from the record when absent. The record rides
* channel 0 like a primary-channel capture and appears in messages() newest first, subject to the
* same HISTORY_LIMIT cap as real captures. Returns { id } with a random uint32 packet id (same
* generation as tx sends). Throws on empty text or an invalid `from`.
*/
injectMessage(text: string, from?: number): { id: number } {
if (typeof text !== 'string' || text.length === 0)
throw new Error('text must be a non-empty string');
if (from !== undefined) this.assertNodeNum(from);
const rec: MessageRecord = {
id: randomPacketId(),
dir: 'rx',
...(from !== undefined ? { from } : {}),
text,
channel: 0,
at: Date.now(),
};
this.pushHistory(rec);
return { id: rec.id };
}
/**
* Telemetry records, newest first: TELEMETRY_APP packets from any node — device metrics
* (battery/voltage/uptime/channel+air utilization) and environment sensor readings where nodes have them.