196 lines
4.8 KiB
Go
196 lines
4.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/hamcha/tg"
|
|
)
|
|
|
|
type Config struct {
|
|
Token string
|
|
Bind string
|
|
WebhookURL string
|
|
WebhookPath string
|
|
MaxRequestsPerMessage int
|
|
}
|
|
|
|
func checkErr(err error, msg string, args ...interface{}) {
|
|
if err != nil {
|
|
fmt.Printf("FATAL ERROR\n"+msg+":\n ", args...)
|
|
fmt.Println(err.Error())
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
var api *tg.Telegram
|
|
var cfg Config
|
|
|
|
func main() {
|
|
cfgpath := flag.String("config", "stappa.conf", "Path to config file")
|
|
flag.Parse()
|
|
|
|
cfgfile, err := os.Open(*cfgpath)
|
|
checkErr(err, "Could not open config file")
|
|
|
|
err = json.NewDecoder(cfgfile).Decode(&cfg)
|
|
checkErr(err, "Could not decode JSON from config file contents")
|
|
|
|
cfgfile.Close()
|
|
|
|
// Set default maxreq
|
|
if cfg.MaxRequestsPerMessage < 1 {
|
|
cfg.MaxRequestsPerMessage = 5
|
|
}
|
|
|
|
api = tg.MakeAPIClient(cfg.Token)
|
|
api.SetWebhook(cfg.WebhookURL)
|
|
api.HandleWebhook(cfg.Bind, cfg.WebhookPath, webhook)
|
|
}
|
|
|
|
func webhook(update tg.APIUpdate) {
|
|
// Handle inline queries (99% of the usage I hope)
|
|
if update.Inline != nil {
|
|
query := update.Inline.Query
|
|
offset, _ := strconv.Atoi(update.Inline.Offset)
|
|
results, err := scryfallSearch(query, offset)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
// DO SOMETHING
|
|
return
|
|
}
|
|
|
|
nextcard := ""
|
|
if results.HasMore {
|
|
nextcard = strconv.Itoa(offset + len(results.Data))
|
|
}
|
|
photos := make([]tg.APIInlineQueryResultPhoto, len(results.Data))
|
|
for i, card := range results.Data {
|
|
buttons := []tg.APIInlineKeyboardButton{
|
|
{
|
|
Text: "Scryfall",
|
|
URL: card.ScryfallURI,
|
|
},
|
|
}
|
|
if card.RelatedUris.Edhrec != "" {
|
|
buttons = append(buttons, tg.APIInlineKeyboardButton{
|
|
Text: "EDHREC",
|
|
URL: card.RelatedUris.Edhrec,
|
|
})
|
|
}
|
|
if card.PurchaseUris.Cardmarket != "" {
|
|
buttons = append(buttons, tg.APIInlineKeyboardButton{
|
|
Text: "MCM",
|
|
URL: card.PurchaseUris.Cardmarket,
|
|
})
|
|
}
|
|
|
|
captions := []string{}
|
|
if card.EdhrecRank != nil {
|
|
captions = append(captions, fmt.Sprintf("EDHREC rank: #%d", *card.EdhrecRank))
|
|
}
|
|
if card.Eur != "" {
|
|
captions = append(captions, fmt.Sprintf("cardmarket: € %s", card.Eur))
|
|
}
|
|
face := card.ImageUris
|
|
if card.ImageUris.Large == "" && card.CardFaces != nil {
|
|
face = card.CardFaces[0].ImageUris
|
|
}
|
|
photos[i] = tg.APIInlineQueryResultPhoto{
|
|
Type: "photo",
|
|
ResultID: card.ID,
|
|
PhotoURL: face.Large,
|
|
ThumbURL: face.Normal,
|
|
Title: card.Name,
|
|
Caption: strings.Join(captions, " - "),
|
|
Width: 672,
|
|
Height: 936,
|
|
ReplyMarkup: &tg.APIInlineKeyboardMarkup{
|
|
InlineKeyboard: [][]tg.APIInlineKeyboardButton{buttons},
|
|
},
|
|
}
|
|
}
|
|
|
|
err = api.AnswerInlineQuery(tg.InlineQueryResponse{
|
|
QueryID: update.Inline.QueryID,
|
|
Results: photos,
|
|
NextOffset: nextcard,
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
// DO SOMETHING
|
|
return
|
|
}
|
|
}
|
|
|
|
// Check for card requests
|
|
if update.Message != nil && update.Message.Text != nil {
|
|
requests := getCardRequests(*update.Message.Text)
|
|
if len(requests) > cfg.MaxRequestsPerMessage {
|
|
api.SendTextMessage(tg.ClientTextMessageData{
|
|
ChatID: update.Message.Chat.ChatID,
|
|
Text: fmt.Sprintf("You asked for way too many cards (%d!), please only ask me for at most %d cards in a single message.", len(requests), cfg.MaxRequestsPerMessage),
|
|
ReplyID: &update.Message.MessageID,
|
|
})
|
|
return
|
|
}
|
|
cardmedia := []tg.APIInputMediaPhoto{}
|
|
errlist := []string{}
|
|
for _, cardname := range requests {
|
|
card, err := scryfallGetCard(cardname)
|
|
if err != nil {
|
|
errlist = append(errlist, cardname)
|
|
} else {
|
|
if card.ImageUris.Large == "" && card.CardFaces != nil {
|
|
for _, cardface := range card.CardFaces {
|
|
cardmedia = append(cardmedia, tg.APIInputMediaPhoto{
|
|
Type: "photo",
|
|
Media: cardface.ImageUris.Large,
|
|
})
|
|
}
|
|
} else {
|
|
cardmedia = append(cardmedia, tg.APIInputMediaPhoto{
|
|
Type: "photo",
|
|
Media: card.ImageUris.Large,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
if len(cardmedia) > 0 {
|
|
api.SendAlbum(tg.ClientAlbumData{
|
|
ChatID: update.Message.Chat.ChatID,
|
|
Media: cardmedia,
|
|
Silent: true,
|
|
ReplyID: &update.Message.MessageID,
|
|
})
|
|
}
|
|
if len(errlist) > 0 {
|
|
api.SendTextMessage(tg.ClientTextMessageData{
|
|
ChatID: update.Message.Chat.ChatID,
|
|
Text: "I couldn't find these cards you mentioned: " + strings.Join(errlist, ", "),
|
|
ReplyID: &update.Message.MessageID,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func getCardRequests(str string) (out []string) {
|
|
remaining := str
|
|
for len(remaining) > 1 {
|
|
nextToken := strings.Index(remaining, "[[")
|
|
if nextToken < 0 {
|
|
break
|
|
}
|
|
endToken := strings.Index(remaining[nextToken:], "]]")
|
|
if endToken < 0 {
|
|
break
|
|
}
|
|
out = append(out, remaining[nextToken+2:nextToken+endToken])
|
|
remaining = remaining[nextToken+2+endToken:]
|
|
}
|
|
return
|
|
}
|