Commit Graph
28 Commits
Author SHA1 Message Date
Zack Pollard a7d8276bdb feat: configure zulip github expansion per stream by command (#654) 2026-09-24 16:54:34 +01:00
Zack Pollard 9d9ee3b680 fix: mirror review follow-ups (#653) 2026-09-24 12:23:50 +01:00
Zack Pollard 49f0661baa feat: backfill the discord history of a mirrored conversation into zulip (#652) 2026-09-24 09:37:24 +01:00
Zack Pollard 4ed72292b5 feat: mirror improvements (#651) 2026-09-24 00:02:35 +01:00
Zack PollardandClaude b70e207962 chore: add a local dev environment for the dev discord server (#455)
Co-authored-by: Claude <noreply@anthropic.com>
2026-09-23 19:22:29 +00:00
Zack Pollard 88de64b545 feat: link mirrored channels and accounts with commands (#650) 2026-09-23 20:20:01 +01:00
Zack Pollard 26dffb00a1 feat: mirror the discord dev channels to zulip (#646) 2026-09-23 14:22:18 +01:00
Zack Pollard acd5ee4064 fix: report errors thrown in discord event handlers (#649) 2026-09-23 13:58:03 +01:00
Zack Pollard 39c7cc3bfc fix: suffix emotes named like zulip built-in emoji (#647) 2026-09-23 11:05:04 +01:00
Zack Pollard e3919a6870 fix: send bot startup and error messages to zulip immich-alerts (#648) 2026-09-23 11:01:42 +01:00
Zack Pollard bfb68a8179 feat: scheduled messages and rss feeds on zulip (#644) 2026-09-23 09:17:26 +01:00
Zack Pollard 8494ad8243 fix: zulip issues found testing against a real server (#645)
* fix: reference every bracket in zulip link labels

* fix: acknowledge backfill-pull-requests all before listing the pull requests

* fix: fail emote-sync on an unreadable discord server and count the uploads

* fix: skip emotes mattermost already has instead of failing them

* fix: stop the zulip side of emote-sync once zulip refuses the user account

* fix: write pull request actions as words in notifications

* fix: shorten the unknown zulip command echo

* fix: keep the full pull request title in its zulip topic

* fix: fail fourthwall update with a clear error when the order is not returned
2026-09-23 02:24:17 +01:00
Zack Pollard a286e32ae7 fix: expand zulip references in #immich and every team stream (#643) 2026-09-23 00:47:44 +00:00
Zack Pollard fb0dea13a1 feat: zulip @-mention command router (#641)
zulip has no slash commands, modals, buttons, autocomplete or ephemeral
replies, so the bot is driven by mentioning it at the start of a message in a
team stream and it answers in the topic. help, emote-sync,
backfill-pull-requests, fourthwall update and similar are ported; the community
commands stay on discord.

commands are accepted only in the private team streams, because membership of
those is the only authorization signal zulip offers a bot, and the stream is
checked to actually be private rather than assumed. every reply is public in
the topic, which is a real downgrade from the discord commands that answer
ephemerally.

fixes a pre-existing bug the port uncovered: /backfill-pull-requests has never
done anything. getOpenPullRequests overwrote the graphql node id with the
numeric database id and never set node_id, which is the key both team paths
look a pull request up by, so every lookup missed and the command reported
success regardless. it now backfills only what a pull request is missing,
leaves existing threads and topics alone, and reports what it created, skipped
and failed.
2026-09-23 01:19:55 +01:00
Zack Pollard 40c840d105 feat: zulip event queue and passive expanders (#639)
the bot can now hear zulip. a long-poll event queue feeds github reference
expansion, github permalink snippets and the x.com mirror into the team
channels, reusing the same methods discord and mattermost already use.

the loop is the point of this change. zulip garbage-collects idle queues and
drops them on restart, so a dead queue is normal operation, and zulip-js
answered that by re-polling the dead queue once a second forever, silently. this
loop re-registers on a dead queue, backs off exponentially on anything else,
treats a long poll that outlives the server timeout as an empty poll, keeps a
floor between polls so a fast server cannot be hammered, says so when it has
been unhealthy for a while, and on shutdown aborts the poll and deletes the
queue.

expanders run only in an allowlist of private team streams. they pass
isPrivileged, so they would expose private repository titles and code if a
public stream were ever added to that list. the server tells us which streams
are private when the queue is registered, so that is now enforced rather than
assumed, and a stream whose privacy is unknown is treated as public.
2026-09-23 01:19:54 +01:00
Zack Pollard 0fcde16476 feat: one zulip topic per pull request (#638)
mirrors the discord team pull-request forum in zulip stream 112: a topic per
public immich pull request, a notice on close, reopen and draft, and the topic
resolved with a checkmark when the pull request is merged or closed.

zulip topics are mutable strings with no id, so the bot stores the id of its
first message and reads the topic back before every rename. a human who renames
or resolves a topic is respected, instead of the bot silently creating a second
empty topic beside the real conversation.

realm settings can refuse an edit, a rename or a resolve: pull requests outlive
message_content_edit_limit_seconds and move_messages_within_stream_limit_seconds,
and resolving needs can_resolve_topics_group. every one of those degrades — it is
logged, a plain message is posted where the information would otherwise be lost,
and the webhook still succeeds.

the discord and zulip paths no longer depend on each other. discord's failure
used to skip the zulip topic entirely, which would have left topics missing and
permanently stale after any discord outage. discord still runs first and its
error still surfaces unchanged.

emote names are normalised for zulip, which lowercases names and treats
underscores as spaces, so colliding names get a numeric suffix and a second sync
is a no-op. the bot warns at boot when it is not subscribed to a stream it posts
to.
2026-09-23 01:19:54 +01:00
Zack Pollard 59ea289350 feat: send team notifications to zulip (#637)
adds a zulip renderer and zulip routes for the eight team destinations, so
github feeds, purchases, reports and release alerts reach zulip alongside
discord and mattermost. webhook.service and schedule.service are untouched,
which is what the phase 1 seam was for.

zulip has no embeds or colour, so the renderer flattens a notification into
markdown and maps each accent to an emoji by meaning. untrusted github titles,
bodies and the customer-written merch order message are contained: bodies go in
a tilde quote fence sized to outrun any fence inside them, mentions are
neutralised, and link labels cannot be broken out of.

delivery is now isolated per platform. previously a platform failure stopped the
ones after it, and because community.* destinations are discord-only and the
handlers post community then team in sequence, a discord outage also silenced
zulip. notify now logs failures and never rejects; a webhook reports success
even when every post failed, so the log is the signal.

fhs pull requests and releases stay on mattermost only, as agreed.
2026-09-23 01:19:54 +01:00
Zack Pollard f7cea83fb2 feat: typed zulip client on openapi-fetch (#636) 2026-09-22 23:50:36 +01:00
Zack Pollard 12f4bbfddd refactor: route notifications through a platform-neutral seam (#635) 2026-09-22 17:17:49 +01:00
Zack Pollard 2fc02ff95e feat: add scheduled message functionality with cron job support (#452) 2026-02-25 19:24:01 +01:00
Zack Pollard 0dc46e0c1c fix: incorrect table naming (#42) 2024-07-18 19:42:34 +01:00
Zack Pollard a9f038c1ff feat: add payment totals to discord messages (#41) 2024-07-18 20:33:05 +02:00
Zack Pollard 2b75f8555e feat: add payment totals to discord messages (#40) 2024-07-18 19:26:19 +01:00
Zack Pollard 58c3b929d9 fix: parse currency to 2 decimal places and make embed color green (#38) 2024-07-18 16:26:08 +01:00
Zack Pollard 4349c008a4 fix: wrong event pls send help (#36) 2024-07-18 17:07:40 +02:00
Zack Pollard ebb04e7341 fix: incorrect stripe typings (#35) 2024-07-18 16:03:17 +01:00
Zack Pollard 25f173b9aa fix: incorrect discord channel id (#34) 2024-07-18 15:46:02 +01:00
Zack Pollard 371a25325b feat: stripe webhook notifications (#33) 2024-07-18 15:41:19 +01:00