Add card requests
This commit is contained in:
parent
6f4a7e7b66
commit
5e64c3120f
2 changed files with 132 additions and 56 deletions
175
main.go
175
main.go
|
@ -6,15 +6,17 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hamcha/tg"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Token string
|
||||
Bind string
|
||||
WebhookURL string
|
||||
WebhookPath string
|
||||
Token string
|
||||
Bind string
|
||||
WebhookURL string
|
||||
WebhookPath string
|
||||
MaxRequestsPerMessage int
|
||||
}
|
||||
|
||||
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 cfg Config
|
||||
|
||||
func main() {
|
||||
cfgpath := flag.String("config", "stappa.conf", "Path to config file")
|
||||
|
@ -34,73 +37,133 @@ func main() {
|
|||
cfgfile, err := os.Open(*cfgpath)
|
||||
checkErr(err, "Could not open config file")
|
||||
|
||||
var cfg Config
|
||||
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) {
|
||||
// Ignore everything that isn't an inline query (for now)
|
||||
if update.Inline == nil {
|
||||
return
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
||||
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 {
|
||||
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 := ""
|
||||
if results.HasMore {
|
||||
nextcard = strconv.Itoa(offset + len(results.Data))
|
||||
}
|
||||
photos := make([]tg.APIInlineQueryResultPhoto, len(results.Data))
|
||||
for i, card := range results.Data {
|
||||
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,
|
||||
},
|
||||
}},
|
||||
},
|
||||
err = api.AnswerInlineQuery(tg.InlineQueryResponse{
|
||||
QueryID: update.Inline.QueryID,
|
||||
Results: photos,
|
||||
NextOffset: nextcard,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
// DO SOMETHING
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
|
13
scryfall.go
13
scryfall.go
|
@ -73,3 +73,16 @@ func scryfallSearch(query string, offset int) (results CardSearchResults, err er
|
|||
results.Data = results.Data[cardoffset:maxoffset]
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue