Live video on the AT Protocol
1package discord
2
3import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "fmt"
8 "io"
9 "net/http"
10 "strings"
11
12 "golang.org/x/net/context/ctxhttp"
13 "stream.place/streamplace/pkg/aqhttp"
14 "stream.place/streamplace/pkg/integrations/discord/discordtypes"
15 "stream.place/streamplace/pkg/log"
16 "stream.place/streamplace/pkg/model"
17 "stream.place/streamplace/pkg/streamplace"
18)
19
20func SendChat(ctx context.Context, w *discordtypes.Webhook, r *model.Repo, scm *streamplace.ChatDefs_MessageView) error {
21
22 msg, ok := scm.Record.Val.(*streamplace.ChatMessage)
23 if !ok {
24 return fmt.Errorf("failed to cast chat message to streamplace chat message")
25 }
26
27 avatarURL, err := getAvatarURL(ctx, r)
28 if err != nil {
29 log.Warn(ctx, "failed to get avatar URL", "err", err)
30 }
31
32 payload := discordtypes.Payload{
33 Username: fmt.Sprintf("@%s", scm.Author.Handle),
34 Content: fmt.Sprintf("%s%s%s", w.Prefix, msg.Text, w.Suffix),
35 }
36 if avatarURL != "" {
37 payload.AvatarURL = avatarURL
38 }
39
40 for _, rewrite := range w.Rewrite {
41 payload.Content = strings.ReplaceAll(payload.Content, rewrite.From, rewrite.To)
42 }
43
44 jsonPayload, err := json.Marshal(payload)
45 if err != nil {
46 return fmt.Errorf("failed to marshal payload: %w", err)
47 }
48
49 log.Warn(ctx, "sending chat to discord", "payload", string(jsonPayload))
50
51 req, err := http.NewRequestWithContext(ctx, "POST", w.URL, bytes.NewReader(jsonPayload))
52 if err != nil {
53 return fmt.Errorf("failed to create request: %w", err)
54 }
55 req.Header.Set("Content-Type", "application/json")
56
57 resp, err := ctxhttp.Do(ctx, &aqhttp.Client, req)
58 if err != nil {
59 return fmt.Errorf("failed to send request: %w", err)
60 }
61 defer resp.Body.Close()
62
63 body, err := io.ReadAll(resp.Body)
64 if err != nil {
65 return fmt.Errorf("failed to read response body: %w", err)
66 }
67
68 if resp.StatusCode != 204 {
69 return fmt.Errorf("failed to send chat to discord: %s", string(body))
70 }
71
72 log.Warn(ctx, "chat sent to discord", "payload", string(body))
73
74 return nil
75}