Add card requests

This commit is contained in:
Hamcha 2018-10-16 15:33:48 +02:00
parent 6f4a7e7b66
commit 5e64c3120f
Signed by: hamcha
GPG key ID: A40413D21021EAEE
2 changed files with 132 additions and 56 deletions

175
main.go
View file

@ -6,15 +6,17 @@ import (
"fmt" "fmt"
"os" "os"
"strconv" "strconv"
"strings"
"github.com/hamcha/tg" "github.com/hamcha/tg"
) )
type Config struct { type Config struct {
Token string Token string
Bind string Bind string
WebhookURL string WebhookURL string
WebhookPath string WebhookPath string
MaxRequestsPerMessage int
} }
func checkErr(err error, msg string, args ...interface{}) { func checkErr(err error, msg string, args ...interface{}) {
@ -26,6 +28,7 @@ func checkErr(err error, msg string, args ...interface{}) {
} }
var api *tg.Telegram var api *tg.Telegram
var cfg Config
func main() { func main() {
cfgpath := flag.String("config", "stappa.conf", "Path to config file") cfgpath := flag.String("config", "stappa.conf", "Path to config file")
@ -34,73 +37,133 @@ func main() {
cfgfile, err := os.Open(*cfgpath) cfgfile, err := os.Open(*cfgpath)
checkErr(err, "Could not open config file") checkErr(err, "Could not open config file")
var cfg Config
err = json.NewDecoder(cfgfile).Decode(&cfg) err = json.NewDecoder(cfgfile).Decode(&cfg)
checkErr(err, "Could not decode JSON from config file contents") checkErr(err, "Could not decode JSON from config file contents")
cfgfile.Close() cfgfile.Close()
// Set default maxreq
if cfg.MaxRequestsPerMessage < 1 {
cfg.MaxRequestsPerMessage = 5
}
api = tg.MakeAPIClient(cfg.Token) api = tg.MakeAPIClient(cfg.Token)
api.SetWebhook(cfg.WebhookURL) api.SetWebhook(cfg.WebhookURL)
api.HandleWebhook(cfg.Bind, cfg.WebhookPath, webhook) api.HandleWebhook(cfg.Bind, cfg.WebhookPath, webhook)
} }
func webhook(update tg.APIUpdate) { func webhook(update tg.APIUpdate) {
// Ignore everything that isn't an inline query (for now) // Handle inline queries (99% of the usage I hope)
if update.Inline == nil { if update.Inline != nil {
return query := update.Inline.Query
} offset, _ := strconv.Atoi(update.Inline.Offset)
results, err := scryfallSearch(query, offset)
if err != nil {
fmt.Println(err)
// DO SOMETHING
return
}
query := update.Inline.Query nextcard := ""
offset, _ := strconv.Atoi(update.Inline.Offset) if results.HasMore {
results, err := scryfallSearch(query, offset) nextcard = strconv.Itoa(offset + len(results.Data))
if err != nil { }
fmt.Println(err) photos := make([]tg.APIInlineQueryResultPhoto, len(results.Data))
// DO SOMETHING for i, card := range results.Data {
return caption := fmt.Sprintf("EDHREC rank: #%d - cardmarket: € %s", card.EdhrecRank, card.Eur)
} photos[i] = tg.APIInlineQueryResultPhoto{
Type: "photo",
ResultID: card.ID,
PhotoURL: card.ImageUris.Large,
ThumbURL: card.ImageUris.Normal,
Title: card.Name,
Caption: caption,
Width: 672,
Height: 936,
ReplyMarkup: &tg.APIInlineKeyboardMarkup{
InlineKeyboard: [][]tg.APIInlineKeyboardButton{{
{
Text: "Scryfall",
URL: card.ScryfallURI,
}, {
Text: "EDHREC",
URL: card.RelatedUris.Edhrec,
}, {
Text: "MCM",
URL: card.PurchaseUris.Magiccardmarket,
},
}},
},
}
}
nextcard := "" err = api.AnswerInlineQuery(tg.InlineQueryResponse{
if results.HasMore { QueryID: update.Inline.QueryID,
nextcard = strconv.Itoa(offset + len(results.Data)) Results: photos,
} NextOffset: nextcard,
photos := make([]tg.APIInlineQueryResultPhoto, len(results.Data)) })
for i, card := range results.Data { if err != nil {
caption := fmt.Sprintf("EDHREC rank: #%d - cardmarket: € %s", card.EdhrecRank, card.Eur) fmt.Println(err)
photos[i] = tg.APIInlineQueryResultPhoto{ // DO SOMETHING
Type: "photo", return
ResultID: card.ID,
PhotoURL: card.ImageUris.Large,
ThumbURL: card.ImageUris.Normal,
Title: card.Name,
Caption: caption,
Width: 672,
Height: 936,
ReplyMarkup: &tg.APIInlineKeyboardMarkup{
InlineKeyboard: [][]tg.APIInlineKeyboardButton{{
{
Text: "Scryfall",
URL: card.ScryfallURI,
}, {
Text: "EDHREC",
URL: card.RelatedUris.Edhrec,
}, {
Text: "MCM",
URL: card.PurchaseUris.Magiccardmarket,
},
}},
},
} }
} }
err = api.AnswerInlineQuery(tg.InlineQueryResponse{ // Check for card requests
QueryID: update.Inline.QueryID, if update.Message != nil && update.Message.Text != nil {
Results: photos, requests := getCardRequests(*update.Message.Text)
NextOffset: nextcard, if len(requests) > cfg.MaxRequestsPerMessage {
}) api.SendTextMessage(tg.ClientTextMessageData{
if err != nil { ChatID: update.Message.Chat.ChatID,
fmt.Println(err) 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),
// DO SOMETHING ReplyID: &update.Message.MessageID,
return })
return
}
cardmedia := []tg.APIInputMediaPhoto{}
errlist := []string{}
for _, cardname := range requests {
card, err := scryfallGetCard(cardname)
if err != nil {
errlist = append(errlist, cardname)
} 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
}

View file

@ -73,3 +73,16 @@ func scryfallSearch(query string, offset int) (results CardSearchResults, err er
results.Data = results.Data[cardoffset:maxoffset] results.Data = results.Data[cardoffset:maxoffset]
return return
} }
func scryfallGetCard(cardname string) (card CardData, err error) {
cardname = url.QueryEscape(cardname)
requrl := fmt.Sprintf("https://api.scryfall.com/cards/named?fuzzy=%s")
response, err := netClient.Get(requrl)
if err != nil {
return
}
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&card)
return
}