Skip to content

Commit

Permalink
feat: createMessage (#30)
Browse files Browse the repository at this point in the history
* start message impl

* fix CreateMessage and add example
  • Loading branch information
karitham authored Oct 8, 2022
1 parent c659cfe commit f764f97
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 20 deletions.
39 changes: 39 additions & 0 deletions 0_example/create-message/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"log"
"os"

"github.com/Karitham/corde"
)

func main() {
token := os.Getenv("DISCORD_BOT_TOKEN")
if token == "" {
log.Fatalln("DISCORD_BOT_TOKEN not set")
}

chID := corde.SnowflakeFromString(os.Getenv("DISCORD_CHANNEL_ID"))
if chID == 0 {
log.Fatalln("DISCORD_CHANNEL_ID not set")
}

m := corde.NewMux("", 0, token)

message := corde.Message{
Embeds: []corde.Embed{
{
Title: "hello corde!",
URL: "https://github.com/Karitham/corde",
Description: "corde is awesome :knot:",
},
},
}

msg, err := m.CreateMessage(chID, message)
if err != nil {
log.Fatalln("error creating message: ", err)
}

log.Printf("message created: %s", msg.ID)
}
56 changes: 38 additions & 18 deletions interactions-api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,50 @@ import (
)

// returns the body and its content-type
func toBody(i *InteractionRespData) (*bytes.Buffer, string) {
body := new(bytes.Buffer)
func toBody(w io.Writer, m *InteractionRespData) (string, error) {
contentType := "application/json"

payloadJSON := &bytes.Buffer{}
err := json.NewEncoder(payloadJSON).Encode(i)
err := json.NewEncoder(payloadJSON).Encode(m)
if err != nil {
return nil, ""
return "", err
}

if len(i.Attachments) < 1 {
payloadJSON.WriteTo(body)
return body, contentType
if len(m.Attachments) < 1 {
payloadJSON.WriteTo(w)
return contentType, nil
}

mw := multipart.NewWriter(body)
mw := multipart.NewWriter(w)
defer mw.Close()

contentType = mw.FormDataContentType()
mw.WriteField("payload_json", payloadJSON.String())

for i, f := range i.Attachments {
if err := writeAttachments(mw, m.Attachments); err != nil {
return contentType, err
}

return contentType, nil
}

func writeAttachments(mw *multipart.Writer, attachments []Attachment) error {
for i, f := range attachments {
if f.ID == 0 {
f.ID = Snowflake(i)
}

ff, CFerr := mw.CreateFormFile(fmt.Sprintf("files[%d]", i), f.Filename)
if CFerr != nil {
return body, contentType
return CFerr
}

if _, CopyErr := io.Copy(ff, f.Body); CopyErr != nil {
return body, contentType
return CopyErr
}
}
return body, contentType

return nil
}

// GetOriginalInteraction returns the original response to an Interaction
Expand All @@ -66,9 +74,13 @@ func (m *Mux) GetOriginalInteraction(token string) (*InteractionRespData, error)
//
// https://discord.com/developers/docs/interactions/receiving-and-responding#edit-original-interaction-response
func (m *Mux) EditOriginalInteraction(token string, data InteractionResponder) error {
body, contentType := toBody(data.InteractionRespData())
body := &bytes.Buffer{}
contentType, err := toBody(body, data.InteractionRespData())
if err != nil {
return err
}

_, err := m.Client.Do(
_, err = m.Client.Do(
rest.Req("/webhooks", m.AppID, token, "messages/@original").
AnyBody(body).Patch(m.authorize, rest.ContentType(contentType)),
)
Expand Down Expand Up @@ -97,9 +109,13 @@ func (m *Mux) DeleteOriginalInteraction(token string) error {
//
// https://discord.com/developers/docs/interactions/receiving-and-responding#followup-messages
func (m *Mux) FollowUpInteraction(token string, data InteractionResponder) error {
body, contentType := toBody(data.InteractionRespData())
body := &bytes.Buffer{}
contentType, err := toBody(body, data.InteractionRespData())
if err != nil {
return err
}

_, err := m.Client.Do(
_, err = m.Client.Do(
rest.Req("/webhooks", m.AppID, token).
AnyBody(body).Post(m.authorize, rest.ContentType(contentType)),
)
Expand All @@ -126,9 +142,13 @@ func (m *Mux) GetFollowUpInteraction(token string, messageID Snowflake) (*Intera
//
// https://discord.com/developers/docs/interactions/receiving-and-responding#edit-followup-message
func (m *Mux) EditFollowUpInteraction(token string, messageID Snowflake, data InteractionResponder) error {
body, contentType := toBody(data.InteractionRespData())
body := &bytes.Buffer{}
contentType, err := toBody(body, data.InteractionRespData())
if err != nil {
return err
}

_, err := m.Client.Do(
_, err = m.Client.Do(
rest.Req("/webhooks", m.AppID, token, "messages", messageID).
AnyBody(body).Patch(m.authorize, rest.ContentType(contentType)),
)
Expand Down
70 changes: 70 additions & 0 deletions messages-api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package corde

import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"

"github.com/Karitham/corde/internal/rest"
)

// returns the content-type
func toBodyMessage(w io.Writer, m Message) (string, error) {
contentType := "application/json"

payloadJSON := &bytes.Buffer{}
err := json.NewEncoder(payloadJSON).Encode(m)
if err != nil {
return "", err
}

if len(m.Attachments) < 1 {
payloadJSON.WriteTo(w)
return contentType, nil
}

mw := multipart.NewWriter(w)
defer mw.Close()

contentType = mw.FormDataContentType()
mw.WriteField("payload_json", payloadJSON.String())

if err := writeAttachments(mw, m.Attachments); err != nil {
return contentType, err
}

return contentType, nil
}

// CreateMessage creates a new message in a channel
//
// https://discord.com/developers/docs/resources/channel#create-message
func (m *Mux) CreateMessage(channelID Snowflake, data Message) (*Message, error) {
body := &bytes.Buffer{}
contentType, err := toBodyMessage(body, data)
if err != nil {
return nil, err
}

resp, err := m.Client.Do(
rest.Req("/channels", channelID, "messages").
AnyBody(body).Post(m.authorize, rest.ContentType(contentType)),
)
if err != nil {
return nil, fmt.Errorf("failed to create message: %w", err)
}
defer resp.Body.Close()

if resp.StatusCode > 299 {
anyerr := map[string]any{}
json.NewDecoder(resp.Body).Decode(&anyerr)
return nil, fmt.Errorf("failed to create message: %+v", anyerr)
}

msg := &Message{}
json.NewDecoder(resp.Body).Decode(msg)
return msg, nil

}
2 changes: 1 addition & 1 deletion messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Message struct {
Activity Activity `json:"activity,omitempty"`
Application Application `json:"application,omitempty"`
ApplicationID Snowflake `json:"application_id,omitempty"`
MessageReference MessageReference `json:"message_reference,omitempty"`
MessageReference *MessageReference `json:"message_reference,omitempty"`
Flags MessageFlag `json:"flags,omitempty"`
ReferencedMessage *Message `json:"referenced_message,omitempty"`
Interaction *Interaction[JsonRaw] `json:"interaction,omitempty"`
Expand Down
2 changes: 1 addition & 1 deletion router.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,5 +169,5 @@ func routeRequest[IntReqData InteractionDataConstraint](
return nil
}

return fmt.Errorf("No handler for interaction type: %d", it)
return fmt.Errorf("no handler for interaction type: %d", it)
}

0 comments on commit f764f97

Please sign in to comment.