82 lines
1.9 KiB
Go
82 lines
1.9 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
"github.com/sirupsen/logrus"
|
||
|
)
|
||
|
|
||
|
const discordRequestTimeout = 2 * time.Second
|
||
|
|
||
|
type (
|
||
|
createChannelInviteReq struct {
|
||
|
MaxAge int64 `json:"max_age"`
|
||
|
MaxUses int64 `json:"max_uses"`
|
||
|
Temporary bool `json:"temporary"`
|
||
|
Unique bool `json:"unique"`
|
||
|
// more unsupported params
|
||
|
}
|
||
|
|
||
|
createChannelInviteResp struct {
|
||
|
Code string `json:"code"`
|
||
|
// more unsupported params
|
||
|
}
|
||
|
)
|
||
|
|
||
|
func createInvite() (string, error) {
|
||
|
ctx, cancel := context.WithTimeout(context.Background(), discordRequestTimeout)
|
||
|
defer cancel()
|
||
|
|
||
|
var (
|
||
|
body = new(bytes.Buffer)
|
||
|
err error
|
||
|
reqURL = fmt.Sprintf("https://discord.com/api/channels/%s/invites", cfg.ChannelID)
|
||
|
)
|
||
|
|
||
|
if err = json.NewEncoder(body).Encode(createChannelInviteReq{
|
||
|
MaxAge: int64(cfg.ExpireIn / time.Second),
|
||
|
MaxUses: cfg.Uses,
|
||
|
Temporary: false,
|
||
|
Unique: true,
|
||
|
}); err != nil {
|
||
|
return "", errors.Wrap(err, "encoding request body")
|
||
|
}
|
||
|
|
||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqURL, body)
|
||
|
if err != nil {
|
||
|
return "", errors.Wrap(err, "creating request")
|
||
|
}
|
||
|
|
||
|
req.Header.Set("Authorization", strings.Join([]string{"Bot", cfg.DiscordBotToken}, " "))
|
||
|
req.Header.Set("Content-Type", "application/json")
|
||
|
req.Header.Set("X-Audit-Log-Reason", fmt.Sprintf("twitch-bot-tools/dc-invite requested for %s", cfg.SendTo))
|
||
|
|
||
|
resp, err := http.DefaultClient.Do(req)
|
||
|
if err != nil {
|
||
|
return "", errors.Wrap(err, "executing request")
|
||
|
}
|
||
|
defer func() {
|
||
|
if err := resp.Body.Close(); err != nil {
|
||
|
logrus.WithError(err).Error("closing response body (leaked fd)")
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
if resp.StatusCode != http.StatusOK {
|
||
|
return "", errors.Errorf("unexpected status %d", resp.StatusCode)
|
||
|
}
|
||
|
|
||
|
var invite createChannelInviteResp
|
||
|
if err = json.NewDecoder(resp.Body).Decode(&invite); err != nil {
|
||
|
return "", errors.Wrap(err, "decoding invite response")
|
||
|
}
|
||
|
|
||
|
return invite.Code, nil
|
||
|
}
|