Add initial support for bot accounts. Fixes #12

This commit is contained in:
Tulir Asokan
2023-02-27 00:43:11 +02:00
parent efd22e33b5
commit 60c260a471
2 changed files with 77 additions and 4 deletions

View File

@@ -19,6 +19,7 @@ package main
import (
"bytes"
"context"
"encoding/base64"
"errors"
"fmt"
"html"
@@ -80,12 +81,45 @@ var cmdLoginToken = &commands.FullHandler{
Help: commands.HelpMeta{
Section: commands.HelpSectionAuth,
Description: "Link the bridge to your Discord account by extracting the access token manually.",
Args: "<user/bot/oauth> <_token_>",
},
}
const discordTokenEpoch = 1293840000
func decodeToken(token string) (userID int64, err error) {
parts := strings.Split(token, ".")
if len(parts) != 3 {
err = fmt.Errorf("invalid number of parts in token")
return
}
var userIDStr []byte
userIDStr, err = base64.RawURLEncoding.DecodeString(parts[0])
if err != nil {
err = fmt.Errorf("invalid base64 in user ID part: %w", err)
return
}
_, err = base64.RawURLEncoding.DecodeString(parts[1])
if err != nil {
err = fmt.Errorf("invalid base64 in random part: %w", err)
return
}
_, err = base64.RawURLEncoding.DecodeString(parts[2])
if err != nil {
err = fmt.Errorf("invalid base64 in checksum part: %w", err)
return
}
userID, err = strconv.ParseInt(string(userIDStr), 10, 64)
if err != nil {
err = fmt.Errorf("invalid number in decoded user ID part: %w", err)
return
}
return
}
func fnLoginToken(ce *WrappedCommandEvent) {
if len(ce.Args) == 0 {
ce.Reply("**Usage**: `$cmdprefix login-token <token>`")
if len(ce.Args) != 2 {
ce.Reply("**Usage**: `$cmdprefix login-token <user/bot/oauth> <token>`")
return
}
ce.MarkRead()
@@ -94,7 +128,25 @@ func fnLoginToken(ce *WrappedCommandEvent) {
ce.Reply("You're already logged in")
return
}
if err := ce.User.Login(ce.Args[0]); err != nil {
token := ce.Args[1]
userID, err := decodeToken(token)
if err != nil {
ce.Reply("Invalid token")
return
}
switch strings.ToLower(ce.Args[0]) {
case "user":
// Token is used as-is
case "bot":
token = "Bot " + token
case "oauth":
token = "Bearer " + token
default:
ce.Reply("Token type must be `user`, `bot` or `oauth`")
return
}
ce.Reply("Connecting to Discord as user ID %d", userID)
if err = ce.User.Login(token); err != nil {
ce.Reply("Error connecting to Discord: %v", err)
return
}

23
user.go
View File

@@ -487,6 +487,24 @@ func (user *User) Connected() bool {
return user.Session != nil
}
const BotIntents = discordgo.IntentGuilds |
discordgo.IntentGuildMessages |
discordgo.IntentGuildMessageReactions |
discordgo.IntentGuildMessageTyping |
discordgo.IntentGuildBans |
discordgo.IntentGuildEmojis |
discordgo.IntentGuildIntegrations |
discordgo.IntentGuildInvites |
//discordgo.IntentGuildVoiceStates |
//discordgo.IntentGuildScheduledEvents |
discordgo.IntentDirectMessages |
discordgo.IntentDirectMessageTyping |
discordgo.IntentDirectMessageTyping |
// Privileged intents
discordgo.IntentMessageContent |
//discordgo.IntentGuildPresences |
discordgo.IntentGuildMembers
func (user *User) Connect() error {
user.Lock()
defer user.Unlock()
@@ -505,6 +523,9 @@ func (user *User) Connect() error {
if os.Getenv("DISCORD_DEBUG") == "1" {
session.LogLevel = discordgo.LogDebug
}
if !session.IsUser {
session.Identify.Intents = BotIntents
}
user.Session = session
@@ -593,7 +614,7 @@ func (user *User) readyHandler(_ *discordgo.Session, r *discordgo.Ready) {
}
user.PrunePortalList(updateTS)
if r.ReadState.Version > user.ReadStateVersion {
if r.ReadState != nil && r.ReadState.Version > user.ReadStateVersion {
// TODO can we figure out which read states are actually new?
for _, entry := range r.ReadState.Entries {
user.messageAckHandler(nil, &discordgo.MessageAck{