Initial build: Asterisk voicemail transcription + portal

- mailcmd replacement (vm_mailcmd.py): faster-whisper transcription (CPU int8),
  extractive summary + intent tags + spoken-digit number extraction,
  multipart/alternative HTML email, fail-safe relay of original message
- Telegram DM delivery (vm_telegram.py) with per-mailbox routing
- Caller-ID -> name (vm_contacts.py): file / google / carddav backends
- SQLite store (vm_store.py) with content-addressed audio
- FastAPI portal (vm_web.py): PIN login, list/play/delete, per-user settings,
  zero JS, loopback-only behind Apache TLS
- Backfill importer (vm_import.py) for existing spool recordings
- systemd unit, Apache vhost + certbot TLS, install.sh
- Docs: INSTALL, CONFIGURATION, ARCHITECTURE, OPERATIONS, SECURITY, TESTING

Verified end-to-end on mail.txt3.net: 157 historical messages backfilled,
live voicemail -> transcribed -> stored -> visible at https://vm.txt3.net.
This commit is contained in:
jp
2026-08-13 09:31:41 +01:00
commit 857284abbf
28 changed files with 3793 additions and 0 deletions

20
tests/make_test_mail.py Normal file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
"""Build a fake Asterisk voicemail notification (as sendmail -t would get it)."""
import sys
from email.message import EmailMessage
wav = sys.argv[1]
to = sys.argv[2]
m = EmailMessage()
m["From"] = "voicemail@txt3.net"
m["To"] = to
m["Subject"] = "New message 3 in mailbox 1001"
m.set_content(
"Dear Jamie:\n\n\tjust wanted to let you know you were just left a 0:37 long message "
"(number 3)\nin mailbox 1001 from Dave Roberts <07941223856>, on Thu, 13 Aug 2026 "
"07:12:00, so you might\nwant to check it when you get a chance. Thanks!\n\n"
"\t\t\t\t--Asterisk\n")
with open(wav, "rb") as fh:
m.add_attachment(fh.read(), maintype="audio", subtype="x-wav", filename="msg0003.wav")
sys.stdout.buffer.write(m.as_bytes())