Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CreateMessageDetailed and support for Discord native replies #64

Merged
merged 9 commits into from Mar 31, 2021

Conversation

yutotakano
Copy link
Member

@yutotakano yutotakano commented Mar 14, 2021

Discord introduced their native "reply" feature a while back. It seems like cross-posted messages from news channels also use the same format. I thought I'd take a go at implementing it in discord-haskell.
This pull request adds the functionality to create messages with manual controls via R.CreateMessageDetailed, and also adds support for native replies on the way.

Changes:

  • Added messageReference and referencedMessage fields in the Message type, as per the docs.
    • Former contains a Maybe MessageReference (expanded below) of the original message if it exists.
    • Latter contains a Maybe Message of the full original message (only present in Replies; Therefore messageReference does not imply the presence of referencedMessage)
  • Added the MessageReference type, following the Discord API object of the same name.
    • It contains the MessageId, ChannelId, and optional GuildId of the referenced message.
    • This is useful for when the referencedMessage does not exist, e.g. for crossposted news messages
  • Added CreateMessageDetailed. Granular controls to send a message. Backwards compatible due to separate name.
    • It takes an ADT MessageDetailedOpts in its signature, which is an entirely new ADT featuring extremely granular options for the core users.
    • Also added the ADT AllowedMentions which is used in the above Opts as a structure to control what the message is allowed to mention (e.g. disabling @ everyone pings)
  • Updated the example ping-pong executable to add a more complex example

Remaining Issues:

  • None

@yutotakano
Copy link
Member Author

yutotakano commented Mar 14, 2021

Actually, this approach is quite flawed. The reason being that replies and sending files, or replies and sending embeds aren't mutually exclusive -- you could have any of CreateMessage, CreateMessageFile, and CreateMessageEmbed as a reply.

I'm struggling to think of a smooth approach to this problem, would anyone help me out in thinking?

@yutotakano yutotakano marked this pull request as draft March 14, 2021 23:00
@aquarial
Copy link
Collaborator

Very detailed, awesome!

You're right to bring up the complexity of messages. There's more flexibility than this library API provides. I went with 3 separate functions because it was simple to implement.

A unified CreateMessageDetailed will involve a few Maybes. I haven't thought too deeply about it

@yutotakano
Copy link
Member Author

Alright, I'll try implement a CreateMessageDetailed. Its type signature would be long for sure hehe.
Regarding that, may I ask what the distinction is for using or not using tuples in the data constructor type signatures?
It seems peculiar to me that CreateReaction has the signature (ChannelId, MessageId) -> T.Text -> ChannelRequest (), while e.g. GroupDMRemoveRecipient has the the IDs untupled: ChannelId -> UserId -> ChannelRequest ().

Should I tuple all the various options to pass into CreateMessageDetailed, or?

@aquarial
Copy link
Collaborator

My intuition was that (ChannelId, MessageId) was one thing, but it's pretty weak justification.

Tryout the type with a lot of args, and also an ADT like RunDiscordOpts, with a Deafult instance. So something like:

CreateMessageDetailed $ def { messageDetailedText = Just "the file"
                            , messageDetailedReferencedMessage = Just (Chanid, MessageId)
                            }

- Tested replies, some allowed-mention fields, and tts
- Untested: file upload, embed, and user/role id allowed-mentions
Previously removed because it was annoying ;)
@yutotakano
Copy link
Member Author

yutotakano commented Mar 20, 2021

I've got something working, took a few tries. I still need to thoroughly look through and see everything is working, but here's an example message sent using the new CreateMessageDetailed, and the code that made it.

image
(replies without mentioning me, doesn't trigger @everyone, and also text-to-speech)

let opts = def { R.messageDetailedContent = "Pong! @everyone"
               , R.messageDetailedTTS = True
               , R.messageDetailedAllowedMentions = Just $ def { R.mentionEveryone = False
                                                               , R.mentionRepliedUser = False}
               , R.messageDetailedReference = Just $ def { referenceMessageId = Just $ messageId m}
               }
_ <- restCall (R.CreateMessageDetailed (messageChannel m) opts)

I defined a new MessageDetailedOpts type (inspired by ModifyChannelOpts), and also a FileUpload and AllowedMentions type. Ideally, I would've made the Opts an instance of ToJSON, but the HTTP request json doesn't have the same structure as the datatypes (e.g. all the fields except for file have to go into payload_json). As a result, around lines 326-340, I had to manually create the request structure.

@aquarial
Copy link
Collaborator

aquarial commented Mar 26, 2021

I like the detailed ADT for AllowedMentions and MessageDetailedOpts a lot

@yutotakano
Copy link
Member Author

I like the detailed ADT for AllowedMentions and MessageDetailedOpts a lot

Thanks! I've manually tested things to the best of my ability now, so it's ready for review/merge!

@yutotakano yutotakano marked this pull request as ready for review March 28, 2021 19:17
@yutotakano yutotakano changed the title Add support for Discord native replies Add CreateMessageDetailed and support for Discord native replies Mar 28, 2021
@aquarial aquarial merged commit b5c33cd into discord-haskell:master Mar 31, 2021
@aquarial
Copy link
Collaborator

👍

@yutotakano yutotakano deleted the feature-reply branch June 11, 2021 09:47
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.

None yet

2 participants