2024-02-28 10:30:20 -05:00
|
|
|
|
package chat
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"encoding/json"
|
2024-03-07 19:41:05 -05:00
|
|
|
|
"fmt"
|
2024-02-28 10:30:20 -05:00
|
|
|
|
"io"
|
|
|
|
|
"net/http"
|
2024-03-07 20:52:42 -05:00
|
|
|
|
|
|
|
|
|
"go.fifitido.net/twitch/api/endpoint"
|
2024-02-28 10:30:20 -05:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type SendChatMessageRequest struct {
|
|
|
|
|
// The ID of the broadcaster whose chat room the message will be sent to.
|
|
|
|
|
BroadcasterID string `json:"broadcaster_id"`
|
|
|
|
|
|
|
|
|
|
// The ID of the user sending the message. This ID must match the user ID in the user access token.
|
|
|
|
|
SenderID string `json:"sender_id"`
|
|
|
|
|
|
|
|
|
|
// The message to send. The message is limited to a maximum of 500 characters. Chat messages can also include emoticons.
|
|
|
|
|
// To include emoticons, use the name of the emote. The names are case sensitive. Don’t include colons around the name (e.g., :bleedPurple:).
|
|
|
|
|
// If Twitch recognizes the name, Twitch converts the name to the emote before writing the chat message to the chat room
|
|
|
|
|
Message string `json:"message"`
|
|
|
|
|
|
|
|
|
|
// The ID of the chat message being replied to.
|
|
|
|
|
ReplyParentMessageID *string `json:"reply_parent_message_id,omitempty"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type SendChatMessageResponse struct {
|
|
|
|
|
Data []SendChatMessageData `json:"data"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type SendChatMessageData struct {
|
|
|
|
|
// The message id for the message that was sent.
|
|
|
|
|
MessageID string `json:"message_id"`
|
|
|
|
|
|
|
|
|
|
// If the message passed all checks and was sent
|
|
|
|
|
IsSent bool `json:"is_sent"`
|
|
|
|
|
|
|
|
|
|
// The reason the message was dropped, if any.
|
|
|
|
|
DropReason []DropReason `json:"drop_reason,omitempty"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type DropReason struct {
|
|
|
|
|
// Code for why the message was dropped.
|
|
|
|
|
Code string `json:"code"`
|
|
|
|
|
|
|
|
|
|
// Message for why the message was dropped.
|
|
|
|
|
Message string `json:"message"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sends a message to the broadcaster’s chat room.
|
|
|
|
|
//
|
|
|
|
|
// Requires an app access token or user access token that includes the user:write:chat scope.
|
|
|
|
|
// If app access token used, then additionally requires user:bot scope from chatting user,
|
|
|
|
|
// and either channel:bot scope from broadcaster or moderator status.
|
|
|
|
|
func (c *Chat) SendChatMessage(ctx context.Context, body *SendChatMessageRequest) (*SendChatMessageResponse, error) {
|
|
|
|
|
r, w := io.Pipe()
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
if err := json.NewEncoder(w).Encode(body); err != nil {
|
|
|
|
|
w.CloseWithError(err)
|
|
|
|
|
} else {
|
|
|
|
|
w.Close()
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
2024-03-07 20:52:42 -05:00
|
|
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(c.baseUrl, "chat/messages"), r)
|
2024-02-28 10:30:20 -05:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res, err := c.client.Do(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer res.Body.Close()
|
|
|
|
|
|
2024-03-07 19:41:05 -05:00
|
|
|
|
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
|
|
|
|
|
if !statusOK {
|
|
|
|
|
return nil, fmt.Errorf("failed to send chat message (%d)", res.StatusCode)
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-28 10:30:20 -05:00
|
|
|
|
var data SendChatMessageResponse
|
|
|
|
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &data, nil
|
|
|
|
|
}
|