bot.py: - Run all yt-dlp/ffmpeg/ffprobe/file-IO/base64 work off the event loop via asyncio.to_thread, bounded by a Semaphore(2); the loop no longer freezes bot-wide during downloads/encodes. - download_attachments=False; VideoTracker fetches only video attachments lazily instead of the library base64-ing every attachment of every message. - last_video keyed per (group, sender) with group-latest fallback so /speed and /rev stop silently targeting a stranger's video; proactive TTL sweeps free the big base64 blobs and bound recent_urls growth. - _reencode guards 0/NaN ffprobe duration and adds -maxrate/-bufsize; /rev now size-checks + re-encodes + faststart like the other paths. - Twitter URL regex no longer merges space-separated links (keeps i/web/status); dedupe repeated URLs within a message; mark-handled only on success/no-media so a corrective edit can retry; 'unsupported url' surfaced instead of silently dropped. - All sends wrapped (catch SendMessageError); base64 decode guarded; edit/sync attachment envelopes handled; /cookies temp file created 0600. deploy: - Pin signalbot==1.1.0, yt-dlp floor, add missing yt-dlp-ejs. - Pin signal-cli-rest-api by digest + add /v1/health healthcheck. - Restart=always (the library never exits non-zero when wedged). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
23 lines
754 B
Plaintext
23 lines
754 B
Plaintext
[Unit]
|
|
Description=Signal Twitter Video Bot
|
|
After=network.target docker.service
|
|
Requires=docker.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=YOUR_USER
|
|
WorkingDirectory=/home/YOUR_USER/signal-bot
|
|
# The bot's own Signal number (the account it's linked to as a device).
|
|
Environment=SIGNAL_PHONE_NUMBER=+15551234567
|
|
Environment=SIGNAL_SERVICE=127.0.0.1:8080
|
|
# Optional: comma-separated numbers allowed to run /cookies (admin command).
|
|
# Environment=BOT_ADMINS=+15551234567
|
|
ExecStart=/home/YOUR_USER/signal-bot/venv/bin/python bot.py
|
|
# always (not on-failure): the bot's library swallows exceptions in its own run
|
|
# loop and never exits non-zero even when wedged, so on-failure would never bounce it.
|
|
Restart=always
|
|
RestartSec=10
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|