voicemail: index messages, live event, email with the recording
services/voicemail.ts rescans a mailbox on Asterisk's MessageWaiting event (and every mailbox on AMI connect) instead of watching files, upserts voicemail_messages by msg_id, marks vanished ones deleted, sends voicemail.new to the owner only, and emails the wav. Delete-after-email uses AMI VoicemailRemove, and only when the audio was attached. Asterisk 24 has VoicemailMove/VoicemailRemove, so 04 §5.6 drops the renumbering plan. New VOICEMAIL_DIR setting; e2e m4-t2 checks the email arrives within 10 s with a playable attachment (SMTP sink shared with m3-t4). Task: M4-T2
This commit is contained in:
1 parent
0d29131d18
commit
8d752ba705
16 files changed
+642
-58
No files matched your search
@@ -10,3 +10,4 @@ export * from './live.ts';
|
||||
export * from './trunks.ts';
|
||||
export * from './dids.ts';
|
||||
export * from './outbound.ts';
|
||||
export * from './voicemail.ts';
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
// Live state shapes sent over the /api/live WebSocket (04 §5.1, §5.2).
|
||||
import type { VoicemailDto } from './voicemail.ts';
|
||||
|
||||
export type ExtensionState =
|
||||
'idle' | 'inuse' | 'busy' | 'unavailable' | 'ringing' | 'onhold' | 'ringinuse';
|
||||
@@ -59,6 +60,8 @@ export type LiveMessage =
|
||||
| { type: 'trunk.updated'; data: TrunkLive }
|
||||
| { type: 'trunk.removed'; data: { trunkId: string } }
|
||||
| { type: 'emergency.call'; data: EmergencyCall }
|
||||
/** Only to the mailbox owner. */
|
||||
| { type: 'voicemail.new'; data: VoicemailDto & { userId: string } }
|
||||
| { type: 'ami.status'; data: { connected: boolean } }
|
||||
| {
|
||||
type: 'system.configApplied';
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
// Voicemail messages (02 voicemail_messages, 04 §5.6).
|
||||
|
||||
/** Asterisk's mailbox folders that we index. */
|
||||
export const VOICEMAIL_FOLDERS = ['INBOX', 'Old', 'Urgent'] as const;
|
||||
export type VoicemailFolder = (typeof VOICEMAIL_FOLDERS)[number];
|
||||
|
||||
export type VoicemailDto = {
|
||||
id: string;
|
||||
folder: VoicemailFolder;
|
||||
callerNumber: string | null;
|
||||
callerName: string | null;
|
||||
durationS: number;
|
||||
receivedAt: string;
|
||||
};
|
||||
Reference in new issue
Block a user