169 lines
7.4 KiB
Markdown
169 lines
7.4 KiB
Markdown
|
# Discord is crazy
|
||
|
|
||
|
This document describes the entire process of persisting Discord messages and handling:
|
||
|
|
||
|
- showcase messages
|
||
|
- library messages
|
||
|
- snippets
|
||
|
- backfills
|
||
|
- admin commands
|
||
|
- who even knows what else
|
||
|
|
||
|
If you want to just hop in and make a quick change to the Discord logic, don't. Not without reading this first, and in particular not without going through the user stories.
|
||
|
|
||
|
## Constraints and design guidelines
|
||
|
|
||
|
We must never save message content for anyone without a linked Discord account.
|
||
|
|
||
|
We always have to respect rate limits, heartbeats, other gateway nuances.
|
||
|
|
||
|
Actions on Discord should never affect the website if the Discord account is not linked to an HMN profile.
|
||
|
|
||
|
Nothing should be added to a user's HMN profile without explicit user action. For example, linking your account should not result in snippets being automatically created from old #project-showcase posts.
|
||
|
|
||
|
We shouldn't assume that just because we have a message (or its contents) stored, we want to create a snippet from it. Sometimes messages could be saved for other reasons.
|
||
|
|
||
|
## All the logic
|
||
|
|
||
|
On new/updated message:
|
||
|
- if in a showcase channel and it doesn't fit the format, delete and return
|
||
|
- if in a library channel and it doesn't fit the format, delete and return
|
||
|
- if we care about the content of this message (see below):
|
||
|
- persist mirror of message data (incl. content if allowed)
|
||
|
- if persisting content, clean up message markdown
|
||
|
- if user has a linked Discord account:
|
||
|
- if this message is snippet-able (see below):
|
||
|
- if snippet exists (in any channel):
|
||
|
- update snippet
|
||
|
- if no snippet exists:
|
||
|
- check conditions for a new snippet:
|
||
|
- the flag for snippet creation is set
|
||
|
- any of the following is true:
|
||
|
- in "showcase" channel, and the user has the setting enabled
|
||
|
- an admin wants a snippet here
|
||
|
- we have message content
|
||
|
- SnippetCreated is false on the message
|
||
|
- if conditions are met, create snippet
|
||
|
- if this message is not snippet-able (see below):
|
||
|
- delete any existing snippets that are connected to Discord (huzzah for edge cases)
|
||
|
|
||
|
On deleted message:
|
||
|
- delete snippets, if the following conditions are true:
|
||
|
- snippet is connected to Discord
|
||
|
- the author has a Discord account linked
|
||
|
- the author chooses not to keep captured snippets on Discord deletes (profile setting)
|
||
|
- delete mirror of message data
|
||
|
|
||
|
On Discord account unlink:
|
||
|
- DO NOT disconnect snippets from Discord.
|
||
|
- There's no reason to.
|
||
|
|
||
|
We care about the content of the message if:
|
||
|
- we already have content for this message, or
|
||
|
- it is in a showcase channel or whatever, or
|
||
|
- an admin said so (CLI command)
|
||
|
|
||
|
A message is snippet-able if:
|
||
|
- It contains enough information to make a snippet. Namely:
|
||
|
- it has media
|
||
|
- Things that DO NOT affect snippetability:
|
||
|
- whether a Discord account is linked
|
||
|
- the user's settings for automatic snippet creation
|
||
|
- other permissions or whatever
|
||
|
|
||
|
### Things we do
|
||
|
|
||
|
These actions all fall into one of the two flows above - the create/update flow, or the delete flow. Some may require flags to modify the main flow behavior slightly.
|
||
|
|
||
|
Stuff for the create/update flow:
|
||
|
- receive message creates/updates in real time
|
||
|
- general backfill (1 hour) (exactly the same behavior as real-time)
|
||
|
- new user backfill (5 seconds) (message content only, no snippets)
|
||
|
- make snippets from #project-showcase posts (exactly the same behavior as real-time)
|
||
|
- admin scrapechannel (fetch messages and content in arbitrary channels, no snippets)
|
||
|
- admin makesnippet
|
||
|
|
||
|
Stuff for the delete flow:
|
||
|
- receive message deletes in real time
|
||
|
- IN THE FUTURE: delete messages in history backfill
|
||
|
|
||
|
## ✨ :D user story time :D ✨
|
||
|
|
||
|
Whenever touching the logic, consider all of these lovely edge cases!
|
||
|
|
||
|
- bad showcase post
|
||
|
- expected: post is immediately deleted
|
||
|
|
||
|
- bad library post
|
||
|
- expected: post is immediately deleted
|
||
|
|
||
|
- good showcase post from an unlinked user
|
||
|
- expected: lightweight message record is created, but no snippet is created
|
||
|
|
||
|
- good showcase post, then the user unlinks their discord account
|
||
|
- expected: the snippet remains on the user's profile
|
||
|
|
||
|
- good showcase post, then the user unlinks their discord account, then edits the message
|
||
|
- expected: the message edit has no effect on the snippet
|
||
|
|
||
|
- good showcase post, then the user unlinks their discord account, then deletes the message
|
||
|
- expected: the message delete has no effect on the snippet
|
||
|
|
||
|
- good showcase post, then the user unlinks and re-links their discord account, then edits the showcase post
|
||
|
- expected: the snippet remained connected to the discord message, and is updated
|
||
|
|
||
|
- good showcase post, then the user unlinks their discord account and links a different one
|
||
|
- expected: nothing happens to old snippets; new snippets get added as usual
|
||
|
|
||
|
- good showcase post, then the user unlinks their discord account, then their discord account is linked to a different website profile
|
||
|
- expected: snippets may be re-created on the new HMN profile
|
||
|
|
||
|
- good showcase post, then the user unlinks their discord account, then we run a backfill on that specific message
|
||
|
- expected: nothing happens because there is no discord account linked for that message
|
||
|
|
||
|
- good showcase post gets edited to be bad
|
||
|
- expected: the message and associated snippet are deleted
|
||
|
|
||
|
- good library post gets edited to be bad
|
||
|
- expected: the message is deleted
|
||
|
|
||
|
- good showcase post gets edited and is still good
|
||
|
- expected: the message record and associated snippet are updated
|
||
|
|
||
|
- good library post gets edited and is still good
|
||
|
- expected: nothing happens
|
||
|
|
||
|
- Ryan posts like 50 things in #projects, and we want them to be on his profile
|
||
|
- expected: an admin can run `admin makesnippet` on all the messages, and they will be added to Ryan's profile
|
||
|
|
||
|
- Ryan edits his old posts in #projects
|
||
|
- same as: someone edits their posts in #jam-showcase
|
||
|
- expected: any associated snippets are updated, even though the edit was not in a showcase channel
|
||
|
|
||
|
- Ryan edits an old post in #projects to no longer have a link
|
||
|
- expected: the associated snippet is deleted, but the message persists.
|
||
|
|
||
|
- Ryan edits an old post in #projects to no longer have a link, then edits it again to have a link again.
|
||
|
- expected: the associated snippet is deleted, and not reinstated on the second edit. (oh well!)
|
||
|
|
||
|
- an admin attempts to make a snippet for someone without a linked discord account
|
||
|
- expected: nothing happens
|
||
|
|
||
|
- an admin attempts to make a snippet for a message without media
|
||
|
- expected: nothing happens
|
||
|
|
||
|
- good showcase post is deleted
|
||
|
- expected: any snippets are deleted, if the user wishes.
|
||
|
|
||
|
- good showcase post, snippet is deleted from website, post is edited
|
||
|
- expected: no new snippet is created
|
||
|
|
||
|
- good showcase post, snippet is deleted from website, backfill runs
|
||
|
- expected: no new snippet is created
|
||
|
|
||
|
- good showcase post while the user has the showcase integration profile setting disabled, then they enable the showcase integration, then a backfill runs
|
||
|
- expected: no new snippets are created for old showcase posts
|
||
|
|
||
|
- good showcase post while the user has the integration disabled, then they enable the integration, then they explicitly create snippets from their showcase posts
|
||
|
- expected: all user messages in showcase without snippets get snippets (subject to SnippetCreated)
|