Skip to content

Conversation

Fabricio20
Copy link

I was having a chat with twin and this might be a fun (optional) addition, I saw you had a suggestion up for it on #7 so I gave it a shot. I'm a java guy not a golang guy so this is the best I could come up with and there's quite a lot of room for improvement.

This initial implementation should provide a means for robot to learn from a discord server as well as randomly post messages like she does in twitch, the configuration works in a slightly different way however. The idea was to be able to learn from both twitch and discord however only use the discord-learned messages on discord. It can also be setup to learn and work independently from twitch. It seems you kinda had that already with Learn and Send tags, im not exactly sure how they work but I implemented/used them for this.

I also implemented say and forget (slash) commands, she should also handle messages being deleted (by the user or a moderator).

To deploy/connect to Discord just create a bot and enable the Message Content intent as that's necessary to read message contents. If a token is not specified it doesn't enable any discord integrations. It's necessary to create a server configuration for each discord server she's gonna be in, I think it'd be better to put it on a table instead of the toml file but for now this should work.

Things you should probably check:

  • Any exception handling fuckups that could cause a panic
  • Any dependency/compilation issues that might have been introduced (idk how go.mod works)
  • If my UserId/MessageId/UserHash handling makes sense at all

Things that could be improved:

  • I have no clue how to work with the logger, Im sorry.
  • Move all configs to a table?
  • Implement an admin command to make robot shut up for a bit (or maybe dont and just timeout robot?)
  • Implement a way to ban user ids globally or possibly per-server, should not be necessary but might be a nice addition
  • Implement a way for users to opt-out from learning (privacy)
  • Implement the copy-pasta feature
  • Implement all your tracing for grafana, I'm not calling anything on this implementation for now
  • Implement support for deferred messages on discord slash commands
  • Implement a loop for that forget command...?

Things that are not necessary:

  • No need to have an ignore channels config (just disable read perms on discord)
  • No need to have a "dont talk here" config (just disable write perms on discord)
  • Robot already ignores bots

Things that need to be looked into eventually:

  • Meme detection (might not be necessary on discord?)
  • Emote handling (it should just work:tm: but you never know??)
  • Mention handling (it should work however messages are stored raw in the database so they are not usable for twitch, pings are disabled so she should @ the user but not cause a notification)
  • "haha funny" modes are not implemented (uwu, etc..)

Theres quite a lot of things that could be generalized/decoupled from the IRC client, such as learn and think calls to reduce all the duplicate code I ended up introducing with the discord methods. Generalizing some of the meme/copypasta/block/trace and other similar things could also go a long way now that this exists.

I'm assuming that to your golang eyes this is garbo code (I have no clue how that robo *Robot parameter gets passed around) so feel free to tell me what to fix or do any changes you feel are fit. You can also message me on discord if you want to go over anything. I did test this so the bare minimum works.

Copy link
Owner

@zephyrtronium zephyrtronium left a comment

Choose a reason for hiding this comment

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

Thanks for sending this in, as well as for your patience on the review!

Just as an FYI: I was planning to look into this feature after fixing #87 and #91, since those relate pretty heavily to config and initialization. Once I eventually do those, which I swear will happen one day, I will probably refactor a lot of this as well. This is plenty good enough for an initial pass on the feature, though.

Have you been able to verify that this works?

}

type Discord struct {
// Token is the discord bot token
Copy link
Owner

Choose a reason for hiding this comment

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

This must be the path to a file containing the token. Secrets do not live in the config.

// Register as global commands
_, err := session.ApplicationCommandBulkOverwrite(event.Application.ID, "", commands)
if err != nil {
_ = fmt.Errorf("failed to update slash commands: %w", err)
Copy link
Owner

Choose a reason for hiding this comment

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

Making an error and assigning it to _ does nothing. If it's ok for the program to live when this happens, then the error should be logged. If it isn't, then this error should be a panic.

}
err := robo.brain.Forget(ctx, ch.Learn, event.Message.ID)
if err != nil {
_ = fmt.Errorf("failed to delete message: %w", err)
Copy link
Owner

Choose a reason for hiding this comment

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

Log this error.


// Register message handler
session.AddHandler(func(session *discordgo.Session, event *discordgo.MessageCreate) {
robo.onDiscordMessage(ctx, session, event)
Copy link
Owner

Choose a reason for hiding this comment

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

Using ctx here is suspicious because this callback outlives the scope the context is given to. Does discordgo.Session or discordgo.MessageCreate have a context.Context?

if ch == nil {
return
}
err := robo.brain.Forget(ctx, ch.Learn, event.Message.ID)
Copy link
Owner

Choose a reason for hiding this comment

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

Suspicious ctx.


// Start opens the Discord websocket connection.
func (mr *MessageReceiver) Start() error {
return mr.session.Open()
Copy link
Owner

Choose a reason for hiding this comment

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

Probably a good idea to log that we're attempting to open the session at the start of this function.


[discord]
# Discord bot token, requires the Message Content intent enabled.
token = ''
Copy link
Owner

Choose a reason for hiding this comment

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

token = '$CREDENTIALS_DIRECTORY/discord_token'

# however only use discord messages in discord due to how pings are
# formatted, emotes, etc...
# Other parameters work the same way as the twitch configurations.
configs = [
Copy link
Owner

Choose a reason for hiding this comment

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

Instead of an inline array, this should either use [[discord.configs]] syntax or work the same way as Twitch channel config.


require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bwmarrin/discordgo v0.28.1 // indirect
Copy link
Owner

Choose a reason for hiding this comment

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

Run go mod tidy.

[twitch.bocchi.effects]
'AAAAA' = 44444

[discord]
Copy link
Owner

Choose a reason for hiding this comment

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

Update config_test.go to test that this loads as expected.

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.

2 participants