Skip to content

feat(api): support anonymous confession threads - #43

Merged
BastiDood merged 19 commits into
mainfrom
thread-support
May 15, 2026
Merged

BastiDood merged 19 commits into
mainfrom
thread-support

Conversation

@BastiDood

Copy link
Copy Markdown
Owner

Adds first-class anonymous public thread support for confession channels, including /thread, Apps > Reply as Anonymous Thread, thread-aware confession posting, approval dispatch, resend behavior, durable attachment handling, and Discord thread creation error reporting. Resolves #27.

The PR also updates command registration and user docs so the new thread workflows, permissions, and attachment behavior are discoverable.

Implementation Notes

  • Added a normalized thread destination model with pending_channel_thread and approved_channel_thread tables, plus confession.pending_channel_thread_id, so thread creation can be represented before and after moderator approval.
  • Kept approval-required thread creation delayed until approval dispatch. Immediate non-approval submissions create the Discord thread during submission processing, while approval-required submissions persist the pending thread title and materialize the Discord thread later.
  • Introduced shared channel-context resolution so commands can consistently distinguish root confession channels from existing Discord threads and route /confess, /thread, Reply Anonymously, and Reply as Anonymous Thread through the right channel/thread ids.
  • Extended confession submission events with explicit modes: message, new-thread, and new-thread-reply. Empty modal state fields are parsed as null so modal custom ids can represent optional thread and parent-message context without sentinel objects.
  • Added Discord API support for creating public threads directly from channels and from source messages. Thread creation failures now use known DiscordErrorCode values and are converted into friendly user-facing interaction responses.
  • Kept the create-discord-thread step result as SerializedConfessionForProcess | string, using typeof result === 'string' to distinguish handled user-facing failures from successful prepared confession state.
  • Split larger Inngest workflows into query/state helpers for submission, approval dispatch, and resend so BigInt-heavy database rows are serialized before crossing step boundaries.
  • Reworked attachment handling around durable moderator-log uploads. Modal uploads are treated as ephemeral inputs, downloaded with size/content-length validation, uploaded into the moderator log, and later reused for approval, public posting, and resend.
  • Added Discord CDN URL parsing for attachments and ephemeral-attachments, including URL normalization and metadata extraction from Discord message attachments or embed images.
  • Updated moderator log rendering for thread destinations so logs show the parent channel and thread channel instead of treating all destinations as a single channel.
  • Updated discord.json, docs, and command registration helpers for /thread and Reply as Anonymous Thread.
  • Known follow-up: Failed anonymous thread creation still persists confession #42 tracks the remaining edge case where an immediate thread creation failure is reported to the user after the confession row has already been persisted.

Breaking Changes

None expected for users. A database migration is required to add thread-tracking tables and the nullable confession thread reference.

Test Cases

  • /thread modal rejects existing-thread usage and missing public-thread/thread-message permissions.
  • Reply as Anonymous Thread modal rejects recursive thread replies, target-channel mismatches, and missing permissions.
  • /confess and anonymous reply modals resolve channel vs. thread destinations and enforce locked-thread permissions.
  • Modal state parsing converts empty custom-id segments into null.
  • Discord attachment CDN parsing accepts durable and ephemeral attachment URLs and rejects malformed/non-CDN URLs.
  • Attachment download handling rejects bad responses, missing/invalid content lengths, and oversized downloads.
  • Durable attachment metadata is extracted from Discord message attachments and image embeds.
  • Thread creation Discord errors render Spectro-owned user-facing copy.
  • Thread log payloads order parent/thread/reply fields predictably.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@BastiDood
BastiDood merged commit fadfda4 into main May 15, 2026
3 checks passed
@BastiDood
BastiDood deleted the thread-support branch May 15, 2026 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add anonymous thread support for configured text channels

1 participant