mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
Discord: Start bot, add !start and pin validity check
The bot should be created by the admin and added to a discord server mutual to the intended new user(s). On !start in the server, communication is moved to DMs. Currently !start works, and validity of a given PIN is checked although nothing it done with this yet.
This commit is contained in:
parent
4b11bbe21f
commit
d928df7ab2
@ -14,6 +14,7 @@ import (
|
|||||||
var emailEnabled = false
|
var emailEnabled = false
|
||||||
var messagesEnabled = false
|
var messagesEnabled = false
|
||||||
var telegramEnabled = false
|
var telegramEnabled = false
|
||||||
|
var discordEnabled = false
|
||||||
|
|
||||||
func (app *appContext) GetPath(sect, key string) (fs.FS, string) {
|
func (app *appContext) GetPath(sect, key string) (fs.FS, string) {
|
||||||
val := app.config.Section(sect).Key(key).MustString("")
|
val := app.config.Section(sect).Key(key).MustString("")
|
||||||
@ -42,7 +43,7 @@ func (app *appContext) loadConfig() error {
|
|||||||
key.SetValue(key.MustString(filepath.Join(app.dataPath, (key.Name() + ".json"))))
|
key.SetValue(key.MustString(filepath.Join(app.dataPath, (key.Name() + ".json"))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, key := range []string{"user_configuration", "user_displayprefs", "user_profiles", "ombi_template", "invites", "emails", "user_template", "custom_emails", "users", "telegram_users"} {
|
for _, key := range []string{"user_configuration", "user_displayprefs", "user_profiles", "ombi_template", "invites", "emails", "user_template", "custom_emails", "users", "telegram_users", "discord_users"} {
|
||||||
app.config.Section("files").Key(key).SetValue(app.config.Section("files").Key(key).MustString(filepath.Join(app.dataPath, (key + ".json"))))
|
app.config.Section("files").Key(key).SetValue(app.config.Section("files").Key(key).MustString(filepath.Join(app.dataPath, (key + ".json"))))
|
||||||
}
|
}
|
||||||
app.URLBase = strings.TrimSuffix(app.config.Section("ui").Key("url_base").MustString(""), "/")
|
app.URLBase = strings.TrimSuffix(app.config.Section("ui").Key("url_base").MustString(""), "/")
|
||||||
@ -87,15 +88,17 @@ func (app *appContext) loadConfig() error {
|
|||||||
app.config.Section("jellyfin").Key("device_id").SetValue(fmt.Sprintf("jfa-go-%s-%s", version, commit))
|
app.config.Section("jellyfin").Key("device_id").SetValue(fmt.Sprintf("jfa-go-%s-%s", version, commit))
|
||||||
messagesEnabled = app.config.Section("messages").Key("enabled").MustBool(false)
|
messagesEnabled = app.config.Section("messages").Key("enabled").MustBool(false)
|
||||||
telegramEnabled = app.config.Section("telegram").Key("enabled").MustBool(false)
|
telegramEnabled = app.config.Section("telegram").Key("enabled").MustBool(false)
|
||||||
|
discordEnabled = app.config.Section("discord").Key("enabled").MustBool(false)
|
||||||
if !messagesEnabled {
|
if !messagesEnabled {
|
||||||
emailEnabled = false
|
emailEnabled = false
|
||||||
telegramEnabled = false
|
telegramEnabled = false
|
||||||
|
discordEnabled = false
|
||||||
} else if app.config.Section("email").Key("method").MustString("") == "" {
|
} else if app.config.Section("email").Key("method").MustString("") == "" {
|
||||||
emailEnabled = false
|
emailEnabled = false
|
||||||
} else {
|
} else {
|
||||||
emailEnabled = true
|
emailEnabled = true
|
||||||
}
|
}
|
||||||
if !emailEnabled && !telegramEnabled {
|
if !emailEnabled && !telegramEnabled && !discordEnabled {
|
||||||
messagesEnabled = false
|
messagesEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,6 +546,62 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"discord": {
|
||||||
|
"order": [],
|
||||||
|
"meta": {
|
||||||
|
"name": "Discord",
|
||||||
|
"description": "Settings for Discord invites/signup/notifications"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"enabled": {
|
||||||
|
"name": "Enabled",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": true,
|
||||||
|
"type": "bool",
|
||||||
|
"value": false,
|
||||||
|
"description": "Enable signup verification through Discord and the sending of notifications through it.\nSee the jfa-go wiki for setting up a bot."
|
||||||
|
},
|
||||||
|
"required": {
|
||||||
|
"name": "Require on sign-up",
|
||||||
|
"required": false,
|
||||||
|
"required_restart": true,
|
||||||
|
"depends_true": "enabled",
|
||||||
|
"type": "bool",
|
||||||
|
"value": false,
|
||||||
|
"description": "Require Discord connection on sign-up."
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"name": "API Token",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": true,
|
||||||
|
"depends_true": "enabled",
|
||||||
|
"type": "text",
|
||||||
|
"value": "",
|
||||||
|
"description": "Discord Bot API Token."
|
||||||
|
},
|
||||||
|
"start_command": {
|
||||||
|
"name": "Start command",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": true,
|
||||||
|
"depends_true": "enabled",
|
||||||
|
"type": "text",
|
||||||
|
"value": "!start",
|
||||||
|
"description": "Command to start the user verification process."
|
||||||
|
},
|
||||||
|
"language": {
|
||||||
|
"name": "Language",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": false,
|
||||||
|
"depends_true": "enabled",
|
||||||
|
"type": "select",
|
||||||
|
"options": [
|
||||||
|
["en-us", "English (US)"]
|
||||||
|
],
|
||||||
|
"value": "en-us",
|
||||||
|
"description": "Default Discord message language. Visit weblate if you'd like to translate."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"telegram": {
|
"telegram": {
|
||||||
"order": [],
|
"order": [],
|
||||||
"meta": {
|
"meta": {
|
||||||
@ -565,6 +621,7 @@
|
|||||||
"name": "Require on sign-up",
|
"name": "Require on sign-up",
|
||||||
"required": false,
|
"required": false,
|
||||||
"required_restart": true,
|
"required_restart": true,
|
||||||
|
"depends_true": "enabled",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"value": false,
|
"value": false,
|
||||||
"description": "Require telegram connection on sign-up."
|
"description": "Require telegram connection on sign-up."
|
||||||
@ -1140,6 +1197,14 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"value": "",
|
"value": "",
|
||||||
"description": "Stores telegram user IDs and language preferences."
|
"description": "Stores telegram user IDs and language preferences."
|
||||||
|
},
|
||||||
|
"discord_users": {
|
||||||
|
"name": "Discord users",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": false,
|
||||||
|
"type": "text",
|
||||||
|
"value": "",
|
||||||
|
"description": "Stores discord user IDs and language preferences."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
146
discord.go
Normal file
146
discord.go
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
dg "github.com/bwmarrin/discordgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DiscordToken struct {
|
||||||
|
Token string
|
||||||
|
ChannelID string
|
||||||
|
UserID string
|
||||||
|
Username string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscordDaemon struct {
|
||||||
|
Stopped bool
|
||||||
|
ShutdownChannel chan string
|
||||||
|
bot *dg.Session
|
||||||
|
username string
|
||||||
|
tokens map[string]DiscordToken // map of user IDs to tokens.
|
||||||
|
verifiedTokens []DiscordToken
|
||||||
|
languages map[string]string // Store of languages for user channelIDs. Added to on first interaction, and loaded from app.storage.discord on start.
|
||||||
|
app *appContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDiscordDaemon(app *appContext) (*DiscordDaemon, error) {
|
||||||
|
token := app.config.Section("discord").Key("token").String()
|
||||||
|
if token == "" {
|
||||||
|
return nil, fmt.Errorf("token was blank")
|
||||||
|
}
|
||||||
|
bot, err := dg.New("Bot " + token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dd := &DiscordDaemon{
|
||||||
|
Stopped: false,
|
||||||
|
ShutdownChannel: make(chan string),
|
||||||
|
bot: bot,
|
||||||
|
tokens: map[string]DiscordToken{},
|
||||||
|
verifiedTokens: []DiscordToken{},
|
||||||
|
languages: map[string]string{},
|
||||||
|
app: app,
|
||||||
|
}
|
||||||
|
for _, user := range app.storage.discord {
|
||||||
|
if user.Lang != "" {
|
||||||
|
dd.languages[user.ChannelID] = user.Lang
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiscordDaemon) NewAuthToken(channelID, userID, username string) DiscordToken {
|
||||||
|
pin := genAuthToken()
|
||||||
|
token := DiscordToken{
|
||||||
|
Token: pin,
|
||||||
|
ChannelID: channelID,
|
||||||
|
UserID: userID,
|
||||||
|
Username: username,
|
||||||
|
}
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiscordDaemon) run() {
|
||||||
|
d.bot.AddHandler(d.messageHandler)
|
||||||
|
d.bot.Identify.Intents = dg.IntentsGuildMessages | dg.IntentsDirectMessages
|
||||||
|
if err := d.bot.Open(); err != nil {
|
||||||
|
d.app.err.Printf("Discord: Failed to start daemon: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.username = d.bot.State.User.Username
|
||||||
|
defer d.bot.Close()
|
||||||
|
<-d.ShutdownChannel
|
||||||
|
d.ShutdownChannel <- "Down"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiscordDaemon) Shutdown() {
|
||||||
|
d.Stopped = true
|
||||||
|
d.ShutdownChannel <- "Down"
|
||||||
|
<-d.ShutdownChannel
|
||||||
|
close(d.ShutdownChannel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiscordDaemon) messageHandler(s *dg.Session, m *dg.MessageCreate) {
|
||||||
|
if m.Author.ID == s.State.User.ID {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sects := strings.Split(m.Content, " ")
|
||||||
|
if len(sects) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lang := d.app.storage.lang.chosenTelegramLang
|
||||||
|
if storedLang, ok := d.languages[m.Author.ID]; ok {
|
||||||
|
lang = storedLang
|
||||||
|
}
|
||||||
|
switch msg := sects[0]; msg {
|
||||||
|
case d.app.config.Section("telegram").Key("start_command").MustString("!start"):
|
||||||
|
d.commandStart(s, m, lang)
|
||||||
|
default:
|
||||||
|
d.commandPIN(s, m, lang)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiscordDaemon) commandStart(s *dg.Session, m *dg.MessageCreate, lang string) {
|
||||||
|
channel, err := s.UserChannelCreate(m.Author.ID)
|
||||||
|
if err != nil {
|
||||||
|
d.app.err.Printf("Discord: Failed to create private channel with \"%s\": %v", m.Author.Username, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
token := d.NewAuthToken(channel.ID, m.Author.ID, m.Author.Username)
|
||||||
|
d.tokens[m.Author.ID] = token
|
||||||
|
content := d.app.storage.lang.Telegram[lang].Strings.get("startMessage") + "\n"
|
||||||
|
content += d.app.storage.lang.Telegram[lang].Strings.get("languageMessage")
|
||||||
|
_, err = s.ChannelMessageSend(channel.ID, content)
|
||||||
|
if err != nil {
|
||||||
|
d.app.err.Printf("Discord: Failed to send message to \"%s\": %v", m.Author.Username, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiscordDaemon) commandPIN(s *dg.Session, m *dg.MessageCreate, lang string) {
|
||||||
|
token, ok := d.tokens[m.Author.ID]
|
||||||
|
if !ok || token.Token != m.Content {
|
||||||
|
_, err := s.ChannelMessageSendReply(
|
||||||
|
m.ChannelID,
|
||||||
|
d.app.storage.lang.Telegram[lang].Strings.get("invalidPIN"),
|
||||||
|
m.Reference(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
d.app.err.Printf("Discord: Failed to send message to \"%s\": %v", m.Author.Username, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err := s.ChannelMessageSendReply(
|
||||||
|
m.ChannelID,
|
||||||
|
d.app.storage.lang.Telegram[lang].Strings.get("pinSuccess"),
|
||||||
|
m.Reference(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
d.app.err.Printf("Discord: Failed to send message to \"%s\": %v", m.Author.Username, err)
|
||||||
|
}
|
||||||
|
d.verifiedTokens = append(d.verifiedTokens, token)
|
||||||
|
delete(d.tokens, m.Author.ID)
|
||||||
|
}
|
1
go.mod
1
go.mod
@ -11,6 +11,7 @@ replace github.com/hrfee/jfa-go/ombi => ./ombi
|
|||||||
replace github.com/hrfee/jfa-go/logger => ./logger
|
replace github.com/hrfee/jfa-go/logger => ./logger
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/bwmarrin/discordgo v0.23.2 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a // indirect
|
github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a // indirect
|
||||||
|
5
go.sum
5
go.sum
@ -11,6 +11,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV
|
|||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4=
|
||||||
|
github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
|
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||||
@ -148,6 +150,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa
|
|||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
|
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||||
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/hrfee/mediabrowser v0.3.3 h1:7E05uiol8hh2ytKn3WVLrUIvHAyifYEIy3Y5qtuNh8I=
|
github.com/hrfee/mediabrowser v0.3.3 h1:7E05uiol8hh2ytKn3WVLrUIvHAyifYEIy3Y5qtuNh8I=
|
||||||
github.com/hrfee/mediabrowser v0.3.3/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U=
|
github.com/hrfee/mediabrowser v0.3.3/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U=
|
||||||
github.com/itchyny/timefmt-go v0.1.2 h1:q0Xa4P5it6K6D7ISsbLAMwx1PnWlixDcJL6/sFs93Hs=
|
github.com/itchyny/timefmt-go v0.1.2 h1:q0Xa4P5it6K6D7ISsbLAMwx1PnWlixDcJL6/sFs93Hs=
|
||||||
@ -265,6 +269,7 @@ github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs=
|
|||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead h1:jeP6FgaSLNTMP+Yri3qjlACywQLye+huGLmNGhBzm6k=
|
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead h1:jeP6FgaSLNTMP+Yri3qjlACywQLye+huGLmNGhBzm6k=
|
||||||
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
|
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
|
||||||
|
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
14
main.go
14
main.go
@ -96,6 +96,7 @@ type appContext struct {
|
|||||||
validator Validator
|
validator Validator
|
||||||
email *Emailer
|
email *Emailer
|
||||||
telegram *TelegramDaemon
|
telegram *TelegramDaemon
|
||||||
|
discord *DiscordDaemon
|
||||||
info, debug, err logger.Logger
|
info, debug, err logger.Logger
|
||||||
host string
|
host string
|
||||||
port int
|
port int
|
||||||
@ -341,6 +342,10 @@ func start(asDaemon, firstCall bool) {
|
|||||||
if err := app.storage.loadTelegramUsers(); err != nil {
|
if err := app.storage.loadTelegramUsers(); err != nil {
|
||||||
app.err.Printf("Failed to load Telegram users: %v", err)
|
app.err.Printf("Failed to load Telegram users: %v", err)
|
||||||
}
|
}
|
||||||
|
app.storage.discord_path = app.config.Section("files").Key("discord_users").String()
|
||||||
|
if err := app.storage.loadDiscordUsers(); err != nil {
|
||||||
|
app.err.Printf("Failed to load Discord users: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
app.storage.profiles_path = app.config.Section("files").Key("user_profiles").String()
|
app.storage.profiles_path = app.config.Section("files").Key("user_profiles").String()
|
||||||
app.storage.loadProfiles()
|
app.storage.loadProfiles()
|
||||||
@ -567,6 +572,15 @@ func start(asDaemon, firstCall bool) {
|
|||||||
defer app.telegram.Shutdown()
|
defer app.telegram.Shutdown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if discordEnabled {
|
||||||
|
app.discord, err = newDiscordDaemon(app)
|
||||||
|
if err != nil {
|
||||||
|
app.err.Printf("Failed to authenticate with Discord: %v", err)
|
||||||
|
} else {
|
||||||
|
go app.discord.run()
|
||||||
|
defer app.discord.Shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
debugMode = false
|
debugMode = false
|
||||||
address = "0.0.0.0:8056"
|
address = "0.0.0.0:8056"
|
||||||
|
42
storage.go
42
storage.go
@ -15,19 +15,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Storage struct {
|
type Storage struct {
|
||||||
timePattern string
|
timePattern string
|
||||||
invite_path, emails_path, policy_path, configuration_path, displayprefs_path, ombi_path, profiles_path, customEmails_path, users_path, telegram_path string
|
invite_path, emails_path, policy_path, configuration_path, displayprefs_path, ombi_path, profiles_path, customEmails_path, users_path, telegram_path, discord_path string
|
||||||
users map[string]time.Time
|
users map[string]time.Time
|
||||||
invites Invites
|
invites Invites
|
||||||
profiles map[string]Profile
|
profiles map[string]Profile
|
||||||
defaultProfile string
|
defaultProfile string
|
||||||
emails, displayprefs, ombi_template map[string]interface{}
|
emails, displayprefs, ombi_template map[string]interface{}
|
||||||
telegram map[string]TelegramUser // Map of Jellyfin User IDs to telegram users.
|
telegram map[string]TelegramUser // Map of Jellyfin User IDs to telegram users.
|
||||||
customEmails customEmails
|
discord map[string]DiscordUser // Map of Jellyfin user IDs to discord users.
|
||||||
policy mediabrowser.Policy
|
customEmails customEmails
|
||||||
configuration mediabrowser.Configuration
|
policy mediabrowser.Policy
|
||||||
lang Lang
|
configuration mediabrowser.Configuration
|
||||||
invitesLock, usersLock sync.Mutex
|
lang Lang
|
||||||
|
invitesLock, usersLock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type TelegramUser struct {
|
type TelegramUser struct {
|
||||||
@ -37,6 +38,13 @@ type TelegramUser struct {
|
|||||||
Contact bool // Whether to contact through telegram or not
|
Contact bool // Whether to contact through telegram or not
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DiscordUser struct {
|
||||||
|
ChannelID string
|
||||||
|
Username string
|
||||||
|
Lang string
|
||||||
|
Contact bool
|
||||||
|
}
|
||||||
|
|
||||||
type customEmails struct {
|
type customEmails struct {
|
||||||
UserCreated customEmail `json:"userCreated"`
|
UserCreated customEmail `json:"userCreated"`
|
||||||
InviteExpiry customEmail `json:"inviteExpiry"`
|
InviteExpiry customEmail `json:"inviteExpiry"`
|
||||||
@ -765,6 +773,14 @@ func (st *Storage) storeTelegramUsers() error {
|
|||||||
return storeJSON(st.telegram_path, st.telegram)
|
return storeJSON(st.telegram_path, st.telegram)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (st *Storage) loadDiscordUsers() error {
|
||||||
|
return loadJSON(st.discord_path, &st.discord)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *Storage) storeDiscordUsers() error {
|
||||||
|
return storeJSON(st.discord_path, st.discord)
|
||||||
|
}
|
||||||
|
|
||||||
func (st *Storage) loadCustomEmails() error {
|
func (st *Storage) loadCustomEmails() error {
|
||||||
return loadJSON(st.customEmails_path, &st.customEmails)
|
return loadJSON(st.customEmails_path, &st.customEmails)
|
||||||
}
|
}
|
||||||
|
24
telegram.go
24
telegram.go
@ -9,7 +9,7 @@ import (
|
|||||||
tg "github.com/go-telegram-bot-api/telegram-bot-api"
|
tg "github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
)
|
)
|
||||||
|
|
||||||
type VerifiedToken struct {
|
type TelegramVerifiedToken struct {
|
||||||
Token string
|
Token string
|
||||||
ChatID int64
|
ChatID int64
|
||||||
Username string
|
Username string
|
||||||
@ -21,7 +21,7 @@ type TelegramDaemon struct {
|
|||||||
bot *tg.BotAPI
|
bot *tg.BotAPI
|
||||||
username string
|
username string
|
||||||
tokens []string
|
tokens []string
|
||||||
verifiedTokens []VerifiedToken
|
verifiedTokens []TelegramVerifiedToken
|
||||||
languages map[int64]string // Store of languages for chatIDs. Added to on first interaction, and loaded from app.storage.telegram on start.
|
languages map[int64]string // Store of languages for chatIDs. Added to on first interaction, and loaded from app.storage.telegram on start.
|
||||||
link string
|
link string
|
||||||
app *appContext
|
app *appContext
|
||||||
@ -37,12 +37,11 @@ func newTelegramDaemon(app *appContext) (*TelegramDaemon, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
td := &TelegramDaemon{
|
td := &TelegramDaemon{
|
||||||
Stopped: false,
|
|
||||||
ShutdownChannel: make(chan string),
|
ShutdownChannel: make(chan string),
|
||||||
bot: bot,
|
bot: bot,
|
||||||
username: bot.Self.UserName,
|
username: bot.Self.UserName,
|
||||||
tokens: []string{},
|
tokens: []string{},
|
||||||
verifiedTokens: []VerifiedToken{},
|
verifiedTokens: []TelegramVerifiedToken{},
|
||||||
languages: map[int64]string{},
|
languages: map[int64]string{},
|
||||||
link: "https://t.me/" + bot.Self.UserName,
|
link: "https://t.me/" + bot.Self.UserName,
|
||||||
app: app,
|
app: app,
|
||||||
@ -55,10 +54,7 @@ func newTelegramDaemon(app *appContext) (*TelegramDaemon, error) {
|
|||||||
return td, nil
|
return td, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var runes = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
func genAuthToken() string {
|
||||||
|
|
||||||
// NewAuthToken generates an 8-character pin in the form "A1-2B-CD".
|
|
||||||
func (t *TelegramDaemon) NewAuthToken() string {
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
pin := make([]rune, 8)
|
pin := make([]rune, 8)
|
||||||
for i := range pin {
|
for i := range pin {
|
||||||
@ -68,10 +64,18 @@ func (t *TelegramDaemon) NewAuthToken() string {
|
|||||||
pin[i] = runes[rand.Intn(len(runes))]
|
pin[i] = runes[rand.Intn(len(runes))]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.tokens = append(t.tokens, string(pin))
|
|
||||||
return string(pin)
|
return string(pin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var runes = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||||
|
|
||||||
|
// NewAuthToken generates an 8-character pin in the form "A1-2B-CD".
|
||||||
|
func (t *TelegramDaemon) NewAuthToken() string {
|
||||||
|
pin := genAuthToken()
|
||||||
|
t.tokens = append(t.tokens, pin)
|
||||||
|
return pin
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TelegramDaemon) run() {
|
func (t *TelegramDaemon) run() {
|
||||||
t.app.info.Println("Starting Telegram bot daemon")
|
t.app.info.Println("Starting Telegram bot daemon")
|
||||||
u := tg.NewUpdate(0)
|
u := tg.NewUpdate(0)
|
||||||
@ -222,7 +226,7 @@ func (t *TelegramDaemon) commandPIN(upd *tg.Update, sects []string, lang string)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.app.err.Printf("Telegram: Failed to send message to \"%s\": %v", upd.Message.From.UserName, err)
|
t.app.err.Printf("Telegram: Failed to send message to \"%s\": %v", upd.Message.From.UserName, err)
|
||||||
}
|
}
|
||||||
t.verifiedTokens = append(t.verifiedTokens, VerifiedToken{
|
t.verifiedTokens = append(t.verifiedTokens, TelegramVerifiedToken{
|
||||||
Token: upd.Message.Text,
|
Token: upd.Message.Text,
|
||||||
ChatID: upd.Message.Chat.ID,
|
ChatID: upd.Message.Chat.ID,
|
||||||
Username: upd.Message.Chat.UserName,
|
Username: upd.Message.Chat.UserName,
|
||||||
|
Loading…
Reference in New Issue
Block a user