Delete stuff on message delete

still need to do bulk delete
This commit is contained in:
Ben Visness 2021-08-26 18:33:39 -05:00
parent 7d5590ee10
commit 719c0d230c
4 changed files with 145 additions and 4 deletions

View File

@ -557,11 +557,14 @@ func (bot *botInstance) processEventMsg(ctx context.Context, msg *GatewayMessage
if err != nil {
return oops.New(err, "error on updated message")
}
case "MESSAGE_DELETE":
bot.messageDelete(ctx, MessageDeleteFromMap(msg.Data))
}
return nil
}
// TODO: Should this return an error? Or just log errors?
func (bot *botInstance) messageCreateOrUpdate(ctx context.Context, msg *Message) error {
if msg.OriginalHasFields("author") && msg.Author.ID == config.Config.Discord.BotUserID {
// Don't process your own messages
@ -587,6 +590,78 @@ func (bot *botInstance) messageCreateOrUpdate(ctx context.Context, msg *Message)
return nil
}
func (bot *botInstance) messageDelete(ctx context.Context, msgDelete MessageDelete) {
log := logging.ExtractLogger(ctx)
tx, err := bot.dbConn.Begin(ctx)
if err != nil {
log.Error().Err(err).Msg("failed to start transaction")
return
}
defer tx.Rollback(ctx)
type deleteMessageQuery struct {
Message models.DiscordMessage `db:"msg"`
DiscordUser *models.DiscordUser `db:"duser"`
HMNUser *models.User `db:"hmnuser"`
SnippetID *int `db:"snippet.id"`
}
iresult, err := db.QueryOne(ctx, tx, deleteMessageQuery{},
`
SELECT $columns
FROM
handmade_discordmessage AS msg
LEFT JOIN handmade_discorduser AS duser ON msg.user_id = duser.userid
LEFT JOIN auth_user AS hmnuser ON duser.hmn_user_id = hmnuser.id
LEFT JOIN handmade_snippet AS snippet ON snippet.discord_message_id = msg.id
WHERE msg.id = $1 AND msg.channel_id = $2
`,
msgDelete.ID, msgDelete.ChannelID,
)
if errors.Is(err, db.ErrNoMatchingRows) {
return
} else if err != nil {
log.Error().Err(err).Msg("failed to check for message to delete")
return
}
result := iresult.(*deleteMessageQuery)
log.Debug().Msg("deleting Discord message")
_, err = tx.Exec(ctx,
`
DELETE FROM handmade_discordmessage
WHERE id = $1 AND channel_id = $2
`,
msgDelete.ID,
msgDelete.ChannelID,
)
shouldDeleteSnippet := result.HMNUser != nil && result.HMNUser.DiscordDeleteSnippetOnMessageDelete
if result.SnippetID != nil && shouldDeleteSnippet {
log.Debug().
Int("snippet_id", *result.SnippetID).
Int("user_id", result.HMNUser.ID).
Msg("deleting snippet from Discord message")
_, err = tx.Exec(ctx,
`
DELETE FROM handmade_snippet
WHERE id = $1
`,
result.SnippetID,
)
if err != nil {
log.Error().Err(err).Msg("failed to delete snippet")
return
}
}
err = tx.Commit(ctx)
if err != nil {
log.Error().Err(err).Msg("failed to delete Discord message")
return
}
}
type MessageToSend struct {
ChannelID string
Req CreateMessageRequest

View File

@ -110,6 +110,23 @@ type Resume struct {
SequenceNumber int `json:"seq"`
}
// https://discord.com/developers/docs/topics/gateway#message-delete
type MessageDelete struct {
ID string `json:"id"`
ChannelID string `json:"channel_id"`
GuildID string `json:"guild_id"`
}
func MessageDeleteFromMap(m interface{}) MessageDelete {
mmap := m.(map[string]interface{})
return MessageDelete{
ID: mmap["id"].(string),
ChannelID: mmap["channel_id"].(string),
GuildID: maybeString(mmap, "guild_id"),
}
}
type ChannelType int
// https://discord.com/developers/docs/resources/channel#channel-object-channel-types

View File

@ -7,9 +7,9 @@ stuff we need to worry about:
- posts that come in while the bot is down
- what to do with posts if you unlink your account
- what to do with posts if you re-link your account
- what to do if you edit the original discord message
- what to do if you edit the original discord message
- what to do if you delete the original discord message
- the user's preferences re: saving content
- the user's preferences re: saving content
- we don't want to save content without the user's consent, especially since it may persist after they disable the integration
- manually adding content for various reasons
- maybe a bug prevented something from saving
@ -17,10 +17,10 @@ stuff we need to worry about:
real-time stuff:
- on new showcase message
- on new showcase message
- always save the lightweight record
- if we have permission, create a snippet
- on edit
- on edit
- re-save the lightweight record and content as if it was new
- create snippet, unconditionally???? (bug??)
- update snippet contents if the edit makes sense

View File

@ -0,0 +1,49 @@
package migrations
import (
"context"
"time"
"git.handmade.network/hmn/hmn/src/migration/types"
"git.handmade.network/hmn/hmn/src/oops"
"github.com/jackc/pgx/v4"
)
func init() {
registerMigration(FixSnippetConstraints{})
}
type FixSnippetConstraints struct{}
func (m FixSnippetConstraints) Version() types.MigrationVersion {
return types.MigrationVersion(time.Date(2021, 8, 26, 0, 56, 7, 0, time.UTC))
}
func (m FixSnippetConstraints) Name() string {
return "FixSnippetConstraints"
}
func (m FixSnippetConstraints) Description() string {
return "Fix the ON DELETE behaviors of snippets"
}
func (m FixSnippetConstraints) Up(ctx context.Context, tx pgx.Tx) error {
_, err := tx.Exec(ctx, `
ALTER TABLE handmade_snippet
DROP CONSTRAINT handmade_snippet_asset_id_c786de4f_fk_handmade_asset_id,
DROP CONSTRAINT handmade_snippet_discord_message_id_d16f1f4e_fk_handmade_,
DROP CONSTRAINT handmade_snippet_owner_id_fcca1783_fk_auth_user_id,
ADD FOREIGN KEY (asset_id) REFERENCES handmade_asset (id) ON DELETE SET NULL,
ADD FOREIGN KEY (discord_message_id) REFERENCES handmade_discordmessage (id) ON DELETE SET NULL,
ADD FOREIGN KEY (owner_id) REFERENCES auth_user (id) ON DELETE CASCADE;
`)
if err != nil {
return oops.New(err, "failed to fix constraints")
}
return nil
}
func (m FixSnippetConstraints) Down(ctx context.Context, tx pgx.Tx) error {
panic("Implement me")
}