mirror of
https://github.com/kuhyx/signal-bot.git
synced 2026-11-10 20:37:03 +01:00
Per-person photo commands, where the mechanism is public and the album is not. Nothing identifying is in this repository: who the people are, what fires their photos and which file shows whom all live in one directory outside it, and the tests, the docs and the offline e2e run use three invented people instead. Several names in one message intersect -- "!alfa beta" is a photo with both -- and where an entry offers a choice the bot picks among the readings that actually have a photo, so a question the album could answer is not refused. A combination nobody photographed gets one line rather than silence, which from the group's side is indistinguishable from a broken bot. Scoping is enforced in the dispatcher, not in the handler: a command the group is not allowed resolves to nothing, so it is not answered, not counted as a command, and never named in a log line outside its own groups. A handler that quietly returned would leak all three. Commands are named by pseudonym (pack:p1), so the journal and command_uses say somebody asked for a photo and nothing about whose. Video works: the attachment goes out as data:video/mp4;filename=...;base64, which is the container's own spelling, read off its /swagger/doc.json. Told it is a photo, Signal renders a clip as an unplayable file. tool/tagger.py serves one page on loopback to fill the album in -- names are typed into the page, never as arguments, and it prints how many photos each command would have when it stops, because a command with zero is dead on arrival. Also renames the real people who were still sitting in the stats test fixtures. They remain in the history; the point is that nothing new is added to it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017w1HZ3cZ7neL3rFdQ6VMBA
90 lines
3.9 KiB
Plaintext
90 lines
3.9 KiB
Plaintext
# Copy to .env and fill in. Every value here is read by signal_bot/config.py.
|
|
# The bot refuses to start if any REQUIRED value is missing or blank.
|
|
|
|
# REQUIRED. The account signal-cli is linked to, in +E.164 form.
|
|
PHONE_NUMBER=
|
|
|
|
# OPTIONAL, and normally left empty. Comma-separated group ids.
|
|
#
|
|
# Empty means "every group this account is a member of", discovered at
|
|
# runtime: adding the bot to a group is then the whole procedure, with no
|
|
# edit here and no restart. That is safe when the bot has its OWN number,
|
|
# because such an account has no other chats.
|
|
#
|
|
# Set it when the bot runs as a LINKED DEVICE on a personal account, where
|
|
# it would otherwise see every group on that account. scripts/live_smoke.sh
|
|
# writes it for you in that case; scripts/register_bot.sh deliberately does
|
|
# not. Startup fails if a listed group is not one the bot has joined.
|
|
#
|
|
# Find the ids with: curl -s localhost:9922/v1/groups/$PHONE_NUMBER | jq
|
|
#
|
|
# Replies, rate limits and the daily tally are per group either way: a
|
|
# command is answered in the group that asked and nowhere else, so there is
|
|
# no send target to configure. GROUP_ID is still accepted as the one-group
|
|
# spelling; GROUP_ID_SEND was removed and now fails startup if set.
|
|
GROUP_IDS=
|
|
|
|
# Optional. The signal-cli-rest-api container. Point this at the fake server
|
|
# to run entirely offline. Default: http://localhost:9922
|
|
API_BASE_URL=
|
|
|
|
# Optional. Tally database. Survives restarts. Default: signal_bot.sqlite3
|
|
DATABASE_PATH=
|
|
|
|
# Optional. When the daily tally is posted. Default: 21:37
|
|
REPORT_HOUR=
|
|
REPORT_MINUTE=
|
|
|
|
# Optional. Per-user, per-command cooldown in seconds. Default: 10
|
|
COOLDOWN_SECONDS=
|
|
|
|
# Optional but recommended. Comma-separated +E.164 numbers -- or member
|
|
# UUIDs, which is how /v1/groups spells anybody the account has never
|
|
# messaged -- allowed to add this bot to a group.
|
|
#
|
|
# Empty means anyone who knows the number can pull the bot into a group and
|
|
# have it answer there. With it set, "add the bot" is still the whole setup
|
|
# for you, and a stranger's group is refused with one WARNING naming that
|
|
# group's members, so you can see exactly which string to add here.
|
|
TRUSTED_INVITERS=
|
|
|
|
# Optional. How long the bot may hear nothing at all -- no message, no
|
|
# receipt, no typing indicator -- before it probes /v1/devices to find out
|
|
# whether it has gone deaf. Three failed probes and /healthz turns 503.
|
|
# Default: 120. scripts/e2e.sh sets it to 0 to prove the gate really fires.
|
|
SILENCE_SECONDS=
|
|
|
|
# Optional. Image APIs. Overridden by scripts/e2e.sh to serve local fixtures.
|
|
CAT_API_URL=
|
|
DOG_API_URL=
|
|
GECKO_API_URL=
|
|
COMMONS_API_URL=
|
|
|
|
# Optional. Where !papież keeps the 267 papal portraits it has downloaded.
|
|
# Default: $CACHE_DIRECTORY/portraits under systemd (the unit sets
|
|
# CacheDirectory=signal-bot), otherwise $XDG_CACHE_HOME/signal-bot/portraits.
|
|
PORTRAIT_CACHE_DIR=
|
|
|
|
# Optional. Groups scripts/selftest.sh may make the bot post into. Empty by
|
|
# default, which makes POST /_selftest refuse everything -- Signal never
|
|
# delivers an account its own sends, so this is the only way to exercise a
|
|
# command without a second account, and it posts for real.
|
|
SELFTEST_GROUPS=
|
|
|
|
# Optional, and private. The album the per-person photo commands draw
|
|
# from: a directory holding people.json, tags.json and media/. Everything
|
|
# identifying lives in there and nothing about it is in this repository --
|
|
# see DOCS-photo-pack.md, and tool/tagger.py for how it gets filled in.
|
|
#
|
|
# Leave it empty and the bot looks in $STATE_DIRECTORY/pack (systemd) and
|
|
# then $XDG_DATA_HOME/signal-bot/pack. Not finding one is normal: the
|
|
# commands simply do not exist. Naming one that is not there, or one whose
|
|
# manifest cannot be honoured, fails startup rather than every command.
|
|
PHOTO_PACK_DIR=
|
|
|
|
# Optional. Where the /healthz readiness probe binds.
|
|
# Default: 127.0.0.1:8137 -- deliberately not 8000, which unrelated dev
|
|
# servers grab, and below the ephemeral range so the kernel cannot take it.
|
|
BIND_HOST=
|
|
BIND_PORT=
|