caciarabot: telegram-shaped photo validation, enforced rule priority, and a lint-found dangling task
caciarabot’s validator already caught a
file over Telegram’s upload ceiling, but size is not the only way Telegram
refuses a photo: width and height above 10000 px, or a longer side more than 20×
the shorter, fails with PHOTO_INVALID_DIMENSIONS even at a few hundred KB —
and a panorama or tall screenshot is exactly the file people drop in. A new
telegram/imagesize.py reads the dimensions out of the header with the standard
library alone — PNG (IHDR), JPEG (skip the APPn segments to the
start-of-frame marker) and all three WebP variants — checked against macOS
sips on all 142 real images in media/ with no false positives
(b06e315).
caciarabot: the weekend Wikipedia draws get their own prompt pool
The weekend digest swapped the tech feeds for a random Wikipedia article but kept the tech prompts, which tell the model it reads “computer-science-adjacent feeds” and must say something “technically true and not obvious” — handed a 150-character stub, that forces either an invented fact or a bolted-on code joke, and a county sheriff’s office had drawn a package.json comparison. A separate config/prompts/digest_weekend/ pool now holds three tones mirroring the tech one, confined to the excerpt and forbidden from asserting facts from memory or reaching for code-and-servers comparisons; the prompt is chosen by candidate.source rather than by re-checking the weekday, so it always matches its content, an empty weekend pool falls back to the tech pool instead of losing the day, and the validator requires the pool whenever the digest is enabled (932b0a6). A first pass still leaked — the Nagano article drew “visti i risultati complessivi”, implying an outcome the excerpt never stated — so the prompts now also forbid implying outcomes or quality the excerpt does not support.
caciarabot: weekends take a non-technical turn in the digest
Weekend days — in the bot’s own timezone, default Europe/Rome — now pull the
daily digest’s candidate from Wikipedia under a non-technical topic filter
instead of the configured tech sources, and the daily-thought Wikipedia rabbit
hole uses the same filter on those days; weekdays are unchanged, and weekday
Wikipedia draws stay unfiltered (00e467f,
PR #1). is_weekend_in_bot_timezone()
in llm/scheduler.py is the shared check, looks_technical() in
llm/wikipedia.py the heuristic, and weekend Wikipedia picks skip the
English-only page fetch so Italian reads come through. The same day’s second
change fixes how updates land: deploy/update.sh now rebuilds, then does
podman compose down and up -d, because up -d followed by restart could
leave the old container running the previous image; the script deliberately
keeps -v off down, so the bind-mounted config, media and data/ trees
survive (bbaa82c,
PR #2). The test suite stands at
174 passing.
topshift-trend: a transient failure no longer wipes out what was already delivered
A scheduled notify pass in
topshift-trend can now fail halfway
without repeating itself: per-chat deliveries are recorded as they succeed, so
the next run skips the links a chat already received and retries only the ones
that never went out, and the global cooldown baseline advances only after a
clean pass
(0ce1688,
PR #9). Before this, one
transient Telegram error in the middle of a batch could resend everything that
had already arrived. A ruff UP035 fix — Mapping imported from
collections.abc — rode along.
caciarabot: the secret feature logs how many people, not which ones
The segreto feature in caciarabot keeps
a roster of who has posted — display names only, no message content, because the
Bot API cannot list a group’s membership — but its dry-run log line wrote those
names out in full. It now logs a count instead
(db905db), and the
README’s Privacy section says so explicitly: the events say how many people a
secret was about, never which ones. The change also cleared CodeQL alert
py/clear-text-logging-sensitive-data, whose “sensitive data” label was firing
on the word “secret” rather than on a credential — the dataflow was real even
where the rule’s name was not, and the count is all the operator needs to see the
feature working.
caciarabot: the digest stops posting links it cannot read
The digest in caciarabot now skips
candidate links whose target page is in another language
(7fd451b), because
GitHub trending routinely surfaces repositories documented entirely in Chinese —
two of the fifty candidates in that day’s live fetch were exactly that, and
posting one of them as the link of the day wastes the slot. The check runs in two
stages, cheapest first: the pool is filtered on the title and description the
source already returned, no extra request; only the picked candidate is fetched
and checked, because verifying fifty to post one would be fifty requests a day,
and a rejection drops that link and draws again, up to five times. For a GitHub
repo the check reads the raw README rather than the repo page, since github.com
serves <html lang="en"> on every page it renders, including for repos written
entirely in Chinese; elsewhere the declared lang decides, falling back to an
English-stopword ratio over the visible text. Two deliberate non-rejections:
Latin-script languages pass the metadata stage (ten words of French cannot be told
from English reliably), and a page yielding no usable evidence is accepted rather
than quietly thinning the pool — and Greek is left out of the non-Latin script set
on purpose, since a lone alpha here is more likely to be mathematics than prose.
topshift-trend: a cooldown so a chat is not notified twice about the same repo
topshift-trend, the Telegram bot
that watches GitHub’s monthly trending list, learned to
suppress repositories it recently notified:
a repo that drops out of the top-N and comes back used to announce itself to
every subscriber again. The bot now keeps a notification_history.json
alongside its state and subscribers, and the scheduled check filters out keys
seen inside a configurable window — NOTIFICATION_COOLDOWN_DAYS, default 30
days, 0 disables the suppression. The commit touches the config, store and
main loop plus three test files, and the check’s log line now reports how many
entries were suppressed next to how many notifications actually went out.
caciarabot: videos and GIFs alongside images
caciarabot word-trigger responses now ship videos and GIFs alongside images, so the bot can reply with moving media instead of only stills. The update script also always restarts the bot now, so config-only changes actually land on the next deploy.
caciarabot: config example file and mood-range daily thoughts
caciarabot stopped tracking its live
config: the working bot.jsonc is no longer in the repo, and a
bot.jsonc.example ships instead, so local state can’t be clobbered by updates
or leak into history. The daily thought generator also gained a real mood range
and occasionally follows a Wikipedia rabbit hole instead of picking a templated
topic.
caciarabot Phase 3: admin commands and reply fixes
caciarabot grew a Phase 3 admin surface: /sleep, /wake, /categories, /stats, and /reload let moderators pause the bot, inspect its categories, and reload state without touching the container. Two reply bugs were also fixed — a cited reply and a word-trigger image can now fire together, and the LLM prompt no longer drifts into recurring ants/insects imagery.
caciarabot: an Italian-first Telegram group bot
caciarabot is a new self-hosted, reactive Telegram group bot designed Italian-first. It runs on your own infrastructure rather than a hosted service, and it reacts to group activity rather than only to explicit commands.