179 lines
4.3 KiB
Go
179 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
|
|
"code.ivysaur.me/libnmdc"
|
|
telegram "github.com/go-telegram-bot-api/telegram-bot-api"
|
|
)
|
|
|
|
// NTFServer methods all run on the same thread, so no mutexes are needed for field access
|
|
type NTFServer struct {
|
|
bot *telegram.BotAPI
|
|
upstream chan upstreamMessage
|
|
chatName string
|
|
inviteLink string
|
|
configFile string
|
|
config NTFConfig
|
|
}
|
|
|
|
type upstreamMessage struct {
|
|
telegramUserId int64
|
|
evt libnmdc.HubEvent
|
|
}
|
|
|
|
func NewNTFServer(configFile string) (*NTFServer, error) {
|
|
ret := NTFServer{
|
|
configFile: configFile,
|
|
}
|
|
|
|
cfg, err := LoadConfig(configFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ret.config = cfg
|
|
|
|
if len(cfg.BotAPIKey) == 0 {
|
|
return nil, errors.New("No bot API key supplied (register with BotFather first)")
|
|
}
|
|
|
|
bot, err := telegram.NewBotAPI(cfg.BotAPIKey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Connecting to Telegram: %s", err.Error())
|
|
}
|
|
|
|
ret.bot = bot
|
|
|
|
bot.Debug = true
|
|
|
|
log.Printf("Connected to telegram as '%s'", bot.Self.UserName)
|
|
|
|
if ret.IsSetupMode() {
|
|
log.Println("Group chat ID unknown, running in setup mode only - find the groupchat ID then re-run")
|
|
|
|
} else {
|
|
chatInfo, err := bot.GetChat(telegram.ChatConfig{ChatID: ret.config.GroupChatID})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Couldn't get supergroup properties: %s", err.Error())
|
|
}
|
|
|
|
inviteLink, err := bot.GetInviteLink(telegram.ChatConfig{ChatID: ret.config.GroupChatID})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Couldn't get supergroup invite link: %s", err.Error())
|
|
}
|
|
|
|
log.Printf("Group chat: %s", chatInfo.Title)
|
|
log.Printf("Invite link: %s", inviteLink)
|
|
|
|
ret.chatName = chatInfo.Title
|
|
ret.inviteLink = inviteLink
|
|
|
|
}
|
|
|
|
// Spawn upstream connections for all known users
|
|
ret.upstream = make(chan upstreamMessage, 0)
|
|
for k, v := range ret.config.KnownUsers {
|
|
ret.LaunchUpstreamWorker(k, v)
|
|
}
|
|
|
|
return &ret, nil
|
|
}
|
|
|
|
func (this *NTFServer) LaunchUpstreamWorker(telegramUserId int64, hubUsername string) {
|
|
ctx := context.Background()
|
|
|
|
// Open NMDC connection
|
|
go upstreamWorker()
|
|
}
|
|
|
|
func (this *NTFServer) IsSetupMode() bool {
|
|
return this.config.GroupChatID == 0
|
|
}
|
|
|
|
func (this *NTFServer) Run() error {
|
|
updateProps := telegram.NewUpdate(0)
|
|
updateProps.Timeout = 60 // seconds
|
|
|
|
updateChan, err := this.bot.GetUpdatesChan(updateProps)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for update := range updateChan {
|
|
this.HandleMessage(update)
|
|
}
|
|
|
|
return nil // Update channel was closed
|
|
}
|
|
|
|
func (this *NTFServer) HandleMessage(update telegram.Update) {
|
|
if update.Message == nil {
|
|
return
|
|
}
|
|
|
|
if this.IsSetupMode() {
|
|
log.Printf("Message from '%s': '%s', chat ID '%d'\n", update.Message.From.UserName, update.Message.Text, update.Message.Chat.ID)
|
|
|
|
} else if update.Message.Chat.ID == this.config.GroupChatID {
|
|
err := this.HandleGroupMessage(update)
|
|
if err != nil {
|
|
log.Printf("Handling group message: %s", err.Error())
|
|
}
|
|
|
|
} else if update.Message.Chat.IsPrivate() {
|
|
err := this.HandleDirectMessage(update)
|
|
if err != nil {
|
|
log.Printf("Handling private message: %s", err.Error())
|
|
}
|
|
|
|
} else {
|
|
log.Printf("Message from unknown chat %d (not our supergroup, not a PM, ...)", update.Message.Chat.ID)
|
|
}
|
|
|
|
fmt.Printf("%#v\n", update.Message)
|
|
|
|
log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
|
|
}
|
|
|
|
func (this *NTFServer) HandleGroupMessage(update telegram.Update) error {
|
|
|
|
// Joins: ????
|
|
if update.Message.NewChatMembers != nil && len(*update.Message.NewChatMembers) > 0 {
|
|
// Users joining
|
|
// Ensure that they have a valid user mapping
|
|
// Create upstream NMDC connection for them
|
|
}
|
|
|
|
if update.Message.LeftChatMember != nil {
|
|
// User parted
|
|
// Close upstream NMDC connection for them
|
|
}
|
|
|
|
// Parts:
|
|
/*
|
|
&tgbotapi.Message{
|
|
MessageID:9, From:(*tgbotapi.User)(0xc420304000), Date:1527989178, Chat:(*tgbotapi.Chat)(0xc4201dc120), [...]
|
|
NewChatMembers:(*[]tgbotapi.User)(nil),
|
|
LeftChatMember:(*tgbotapi.User)(0xc420304050),
|
|
}
|
|
*/
|
|
|
|
return nil
|
|
}
|
|
|
|
func (this *NTFServer) HandleDirectMessage(update telegram.Update) error {
|
|
|
|
// Registration workflow
|
|
// Find out the current status for this chat ID... etc.
|
|
|
|
msg := telegram.NewMessage(update.Message.Chat.ID, "Hi user, join the group chat at "+this.inviteLink)
|
|
msg.ReplyToMessageID = update.Message.MessageID
|
|
this.bot.Send(msg)
|
|
|
|
return nil
|
|
}
|