Add initial support for bot accounts. Fixes #12
This commit is contained in:
58
commands.go
58
commands.go
@@ -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
23
user.go
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user