README ¶
DwHooks
DwHooks is a minimal library for sending discord webhook messages with no external dependencies outside of the discord service itself
for more info about webhooks see: https://discord.com/developers/docs/resources/webhook#execute-webhook
Feature support
- Message content
- Custom Usernames and avatars
- Embeds
- Allowed mentions
- Sending files
- Editing webhook messages
- Deleting webhook messages
- Ratelimits (Partal, X-Ratelimit-Bucket is not supported)
Usage examples
Some examples on how it works, full runnable code is included in the first simple example, but the function and package body will be left out of the following examples
Simple
for little things you can use the global functions to send a quick message, best used for little things
package main
import "codeberg.org/eviedelta/dwhook"
func main() {
url := "WEBHOOK URL HERE"
msg := dwhook.Message{
Content: "This is an example for dwhook",
}
dwhook.SendTo(url, msg)
}
Custom Webhook object
for heavy use and/or use with more than one webhook it is recommended to create a seperate object with New or NewFromID, due to the default ratelimiting code not being able to take into account x-ratelimit-bucket
hook, err := dwhook.New("WEBHOOK URL")
if err != nil {
fmt.Println("Invalid Webhook URL: ", err)
return
}
msg := dwhook.Message{
Content: "Custom embed var",
}
hook.Send(msg)
Custom Username or Avatar
msg := dwhook.Message{
Content: "This is has a custom name and icon",
Username: "CustomName",
AvatarURL: "https://discord.com/assets/2c21aeda16de354ba5334551a883b481.png", // discord icon
}
hook.Send(msg)
Embeds
msg := dwhook.Message{
Embeds: []dwhook.Embed{{
Title: "DwHook Example Embed",
URL: "codeberg.org/eviedelta/dwhook",
Description: "This is an embed constructed for example purposes",
Fields: []dwhook.EmbedField{{
Name: "this is an embed field",
Value: "Hello world",
}},
Footer: dwhook.EmbedFooter{
Text: "Footer",
},
}},
}
hook.Send(msg)
Delete message
hook.Delete(msgID)
Edit message
msg := dwhook.Message{
Content: "This is an example edited message for dwhook",
}
hook.Edit(msg, msgID)
Documentation ¶
Index ¶
- Constants
- Variables
- func DeleteTo(url, target string) ([]byte, error)
- func DeleteToToken(id, token string, target string) ([]byte, error)
- func EditTo(url string, message Message, target string) ([]byte, error)
- func EditToToken(id, token string, message Message, target string) ([]byte, error)
- func ParseWebhookURL(url string) (id, token string, err error)
- func SendFileTo(url string, message Message, filename, contentType string, file []byte) ([]byte, error)
- func SendFileToToken(id, token string, message Message, filename, contentType string, file []byte) ([]byte, error)
- func SendFileToTokenWait(id, token string, message Message, filename, contentType string, file []byte) ([]byte, error)
- func SendFileToWait(url string, message Message, filename, contentType string, file []byte) ([]byte, error)
- func SendTo(url string, message Message) ([]byte, error)
- func SendToToken(id, token string, message Message) ([]byte, error)
- func SendToTokenWait(id, token string, message Message) ([]byte, error)
- func SendToWait(url string, message Message) ([]byte, error)
- func URLFromIDToken(id, token string) string
- type AllowedMentions
- type Attachment
- type Author
- type DefaultRatelimitHandler
- type Embed
- type EmbedAuthor
- type EmbedField
- type EmbedFooter
- type EmbedImage
- type EmbedThumbnail
- type EmbedVideo
- type Emoji
- type FullMessage
- func EditToUnmarshal(url string, message Message, target string) (*FullMessage, error)
- func SendFileToUnmarshal(url string, message Message, filename, contentType string, file []byte) (*FullMessage, error)
- func SendToUnmarshal(url string, message Message) (*FullMessage, error)
- func UnmarshalResponse(b []byte, err error) (*FullMessage, error)
- type Message
- type RatelimitHandler
- type Reaction
- type Webhook
- func (w *Webhook) ActiveCount() int
- func (w *Webhook) Delete(message string) ([]byte, error)
- func (w *Webhook) Edit(contents Message, messageID string) ([]byte, error)
- func (w *Webhook) EditUnmarshal(contents Message, messageID string) (*FullMessage, error)
- func (w *Webhook) InitCheck() error
- func (w *Webhook) Send(contents Message) ([]byte, error)
- func (w *Webhook) SendFile(contents Message, filename, contentType string, file []byte) ([]byte, error)
- func (w *Webhook) SendFileUnmarshal(contents Message, filename, contentType string, file []byte) (*FullMessage, error)
- func (w *Webhook) SendFileWait(contents Message, filename, contentType string, file []byte) ([]byte, error)
- func (w *Webhook) SendUnmarshal(contents Message) (*FullMessage, error)
- func (w *Webhook) SendWait(contents Message) ([]byte, error)
Constants ¶
const ( APIEndpoint = connProtocol + "discord.com/api/v8/" APIEndpointWebhook = APIEndpoint + "webhooks/" )
API Endpoints used internally
const ( MentionRoles = "roles" MentionUsers = "users" MentionEveryone = "everyone" )
Allowed mention types as based off of https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mention-types
Variables ¶
var ( MaxMessages = 30 MaxPeriod = time.Minute )
apparently there is a thing in the webhook api where you can only send 30 messages per minute to a channel but for whatever reason this is neither mentioned in the ratelimit headers nor the discord documentation, so unfortunetely i have to hard code this and hope for the best
var ErrorInvalidURL = errors.New("URL was invalid or could not be parsed")
ErrorInvalidURL is the error given when a URL does not pass validation regex
Functions ¶
func DeleteToToken ¶
DeleteToToken deletes a message from a specifed webhook
func EditToToken ¶
EditToToken edits a message from a specified discord webhook
func ParseWebhookURL ¶
ParseWebhookURL parses a webhook url into its ID and token
func SendFileTo ¶
func SendFileTo(url string, message Message, filename, contentType string, file []byte) ([]byte, error)
SendFileTo sends a message with a file to a specified discord webhook, for heavy use and/or use with more than one webhook it is recommended to create a seperate object with New or NewFromID due to how the ratelimiting code works
func SendFileToToken ¶
func SendFileToToken(id, token string, message Message, filename, contentType string, file []byte) ([]byte, error)
SendFileToToken sends a message with a file to a specified discord webhook, for heavy use and/or use with more than one webhook it is recommended to create a seperate object with New or NewFromID due to how the ratelimiting code works
func SendFileToTokenWait ¶
func SendFileToTokenWait(id, token string, message Message, filename, contentType string, file []byte) ([]byte, error)
SendFileToTokenWait sends a message with a file to a specified discord webhook and waits for the message data response
func SendFileToWait ¶
func SendFileToWait(url string, message Message, filename, contentType string, file []byte) ([]byte, error)
SendFileToWait sends a message with a file to a specified discord webhook and waits for the message data response
func SendTo ¶
SendTo sends a message to a specified discord webhook, for heavy use and/or use with more than one webhook it is recommended to create a seperate object with New or NewFromID due to how the ratelimiting code works
func SendToToken ¶
SendToToken sends a message to a specified discord webhook, for heavy use and/or use with more than one webhook it is recommended to create a seperate object with New or NewFromID due to how the ratelimiting code works
func SendToTokenWait ¶
SendToTokenWait sends a message to a specified discord webhook and waits for the message data response
func SendToWait ¶
SendToWait sends a message to a specified discord webhook and waits for the message data response
func URLFromIDToken ¶
URLFromIDToken takes a webhook ID and token and returns an endpoint url for it
Types ¶
type AllowedMentions ¶
type AllowedMentions struct { // Allowed mention types, can use the consts MentionRoles MentionUsers or MentionEveryone here Parse []string `json:"parse"` // Users and Roles respectively take a list of User or Role IDs that are allowed to be mentioned Users []string `json:"users,omitempty"` Roles []string `json:"roles,omitempty"` }
AllowedMentions allows more control over setting what can be mentioned within a message Original Documentation about how it works here https://discord.com/developers/docs/resources/channel#allowed-mentions-object
type Attachment ¶
type Attachment struct { ID string `json:"id"` Filename string `json:"filename"` Size int `json:"size"` URL string `json:"url"` ProxyURL string `json:"proxy_url"` Height int `json:"height"` Width int `json:"width"` }
Attachment object used for decoding full message objects
type Author ¶
type Author struct { ID string `json:"id"` Username string `json:"username"` Discriminator string `json:"discriminator"` Avatar string `json:"avatar,omitempty"` Bot bool `json:"bot"` System bool `json:"system"` Locale string `json:"locale,omitempty"` Verified bool `json:"verified"` Flags int `json:"flags,omitempty"` PremiumType int `json:"premium_type,omitempty"` PublicFlags int `json:"public_flags,omitempty"` }
Author object used only for decoding full message objects, basically a copy of the docs
type DefaultRatelimitHandler ¶
type DefaultRatelimitHandler struct { // ResetTime and remaining reflect the standard ratelimit headers ResetTime time.Time Remaining int // mutual exclusion lock, technically redundent since the webhook itself is mutex'ed now but it is here just in case sync.RWMutex // contains filtered or unexported fields }
DefaultRatelimitHandler is a default implementation of a ratelimit handler
type Embed ¶
type Embed struct { Title string `json:"title,omitempty"` Description string `json:"description,omitempty"` URL string `json:"url,omitempty"` Timestamp string `json:"timestamp,omitempty"` // an ISO8601 or RFC3339 timestamp to mark the embed with Color int `json:"color,omitempty"` // A color in RGB integer format (basically an RGB hex code converted to decimal) Image EmbedImage `json:"image,omitempty"` Thumbnail EmbedThumbnail `json:"thumbnail,omitempty"` Video EmbedVideo `json:"video,omitempty"` Author EmbedAuthor `json:"author,omitempty"` Fields []EmbedField `json:"fields,omitempty"` }
Embed is the data for all discord embed fields
type EmbedAuthor ¶
type EmbedAuthor struct { Name string `json:"name,omitempty"` URL string `json:"url,omitempty"` IconURL string `json:"icon_url,omitempty"` }
EmbedAuthor contains data for the discord embed author field
type EmbedField ¶
type EmbedField struct { Name string `json:"name,omitempty"` Value string `json:"value,omitempty"` Inline bool `json:"inline,omitempty"` }
EmbedField contains data for a discord embed field
type EmbedFooter ¶
type EmbedFooter struct {}
EmbedFooter contains data for a discord embed footer field
type EmbedImage ¶
type EmbedImage struct { URL string `json:"url,omitempty"` Height int `json:"height,omitempty"` Width int `json:"width,omitempty"` }
EmbedImage contains data for a discord embed image field
type EmbedThumbnail ¶
type EmbedThumbnail struct { URL string `json:"url,omitempty"` Height int `json:"height,omitempty"` Width int `json:"width,omitempty"` }
EmbedThumbnail contains data for a discord embed thumbnail field
type EmbedVideo ¶
type EmbedVideo struct { URL string `json:"url,omitempty"` Height int `json:"height,omitempty"` Width int `json:"width,omitempty"` }
EmbedVideo contains data for a discord embed video field
type Emoji ¶
type Emoji struct { ID string `json:"id"` Name string `json:"name"` // roles // user // require colons // managed Animated bool `json:"animated"` Available bool `json:"available"` }
Emoji object used for decoding full message objects
type FullMessage ¶
type FullMessage struct { ID string `json:"id,omitempty"` ChannelID string `json:"channel_id,omitempty"` GuildID string `json:"guild_id,omitempty"` Author *Author `json:"author,omitempty"` // Member *Member `json:"member,omitempty"` Content string `json:"content,omitempty"` Timestamp string `json:"timestamp,omitempty"` EditedTimestamp string `json:"edited_timestamp,omitempty"` // TTS bool `json:"tts"` MentionEveryone bool `json:"mention_everyone"` // Mentions // Mention roles // Mention channels Attachments []*Attachment `json:"attachments,omitempty"` Reactions []*Reaction `json:"reactions,omitempty"` // Nonce Pinned bool `json:"pinned"` WebhookID string `json:"webhook_id,omitempty"` }
FullMessage this is only used for being able to decode the response if hook.SendWait is used without needing to define ones own structs or import something else Not all these fields may be useful or used, its just a copy of the reference in the discord docs If this lib is used in addition to another discord lib you can also unmarshal the response to the message structs offered by those
func EditToUnmarshal ¶
func EditToUnmarshal(url string, message Message, target string) (*FullMessage, error)
EditToUnmarshal is like EditTo but it passes through UnmarshalResponse to give a message struct instead of bytes
func SendFileToUnmarshal ¶
func SendFileToUnmarshal(url string, message Message, filename, contentType string, file []byte) (*FullMessage, error)
SendFileToUnmarshal is like SendFileTo but it passes through UnmarshalResponse to give a message struct instead of bytes
func SendToUnmarshal ¶
func SendToUnmarshal(url string, message Message) (*FullMessage, error)
SendToUnmarshal is like SendToWait but it passes through UnmarshalResponse to give a message struct instead of bytes
func UnmarshalResponse ¶
func UnmarshalResponse(b []byte, err error) (*FullMessage, error)
UnmarshalResponse is a utility function that one can chain the SendWait, SendFileWait or Edit function into to get a struct instead of just bytes Ex, dwhook.UnmarshalResponse(hook.SendWait(msg))
type Message ¶
type Message struct { // The main message content Content string `json:"content,omitempty"` // Use a custom username, this can be left blank and it'll use the webhook name set on discords end Username string `json:"username,omitempty"` // URL to a custom avatar, this can be left blank and it'll use the avatar set on discords end AvatarURL string `json:"avatar_url,omitempty"` // A list of discord message embeds to include with the webhook Embeds []Embed `json:"embeds,omitempty"` // Discord allowed mentions object to allow more granular control over what can be mentioned AllowedMentions *AllowedMentions `json:"allowed_mentions,omitempty"` }
Message defines the message format used by discords webhooks, almost all fields are entirely optional except for either content or embeds which at least one or the other must be set (you may have an embed but no content or content and no embed, however you cannot have neither)
type RatelimitHandler ¶
type RatelimitHandler interface { // Check determines if a webhook should be limited or not // note that when not ratelimited it can only return 0 or less // a return of anything above 0 will cause the request loop to wait that amount of time and then reset to the beginning and check for limits again after the wait Check(ctx context.Context, webhookID string) (wait time.Duration) // Update gives an update to the ratelimit information Update(ctx context.Context, webhookID string, h http.Header) error }
RatelimitHandler is the interface for implementations of a ratelimit handler
type Reaction ¶
Reaction object used for decoding full message objects probably useless since reactions won't be on a newly posted message but here for completeness
type Webhook ¶
type Webhook struct { Client *http.Client ID, Token string R RatelimitHandler sync.Mutex // contains filtered or unexported fields }
Webhook is a webhook client, its recommended you use New or NewFromID but you can create one directly if initiating one from a literal instead of the New functions it is required to call InitCheck at least once before using as that'll ensure a private var is set that would otherwise cause a panic if unset
func (*Webhook) ActiveCount ¶
ActiveCount gets whether there are currently webhook requests waiting to be sent
func (*Webhook) EditUnmarshal ¶
func (w *Webhook) EditUnmarshal(contents Message, messageID string) (*FullMessage, error)
EditUnmarshal is like Edit but it passes through UnmarshalResponse to give a message struct instead of just bytes
func (*Webhook) InitCheck ¶
InitCheck just verifies some private variables are set and sets them if they are not
func (*Webhook) SendFile ¶
func (w *Webhook) SendFile(contents Message, filename, contentType string, file []byte) ([]byte, error)
SendFile a Message with file to the webhook
func (*Webhook) SendFileUnmarshal ¶
func (w *Webhook) SendFileUnmarshal(contents Message, filename, contentType string, file []byte) (*FullMessage, error)
SendFileUnmarshal is like SendFileWait but it passes through UnmarshalResponse to give a message struct instead of bytes
func (*Webhook) SendFileWait ¶
func (w *Webhook) SendFileWait(contents Message, filename, contentType string, file []byte) ([]byte, error)
SendFileWait a Message with file to the webhook URL in the Webhook client and wait to get the response
func (*Webhook) SendUnmarshal ¶
func (w *Webhook) SendUnmarshal(contents Message) (*FullMessage, error)
SendUnmarshal is like SendWait but it passes through UnmarshalResponse to give a message struct instead of bytes