2018-09-17 10:26:24 +00:00
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
2018-09-17 13:15:19 +00:00
"strconv"
2018-10-16 13:33:48 +00:00
"strings"
2018-09-17 10:26:24 +00:00
"github.com/hamcha/tg"
)
type Config struct {
2018-10-16 13:33:48 +00:00
Token string
Bind string
WebhookURL string
WebhookPath string
MaxRequestsPerMessage int
2018-09-17 10:26:24 +00:00
}
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
2018-10-16 13:33:48 +00:00
var cfg Config
2018-09-17 10:26:24 +00:00
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 ( )
2018-10-16 13:33:48 +00:00
// Set default maxreq
if cfg . MaxRequestsPerMessage < 1 {
cfg . MaxRequestsPerMessage = 5
}
2018-09-17 10:26:24 +00:00
api = tg . MakeAPIClient ( cfg . Token )
api . SetWebhook ( cfg . WebhookURL )
api . HandleWebhook ( cfg . Bind , cfg . WebhookPath , webhook )
}
func webhook ( update tg . APIUpdate ) {
2018-10-16 13:33:48 +00:00
// 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
}
2018-09-17 10:26:24 +00:00
2018-10-16 13:33:48 +00:00
nextcard := ""
if results . HasMore {
nextcard = strconv . Itoa ( offset + len ( results . Data ) )
}
photos := make ( [ ] tg . APIInlineQueryResultPhoto , len ( results . Data ) )
for i , card := range results . Data {
2018-12-13 10:22:10 +00:00
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 ) )
}
2018-12-13 11:01:24 +00:00
face := card . ImageUris
2018-12-13 11:05:25 +00:00
if card . ImageUris . Large == "" && card . CardFaces != nil {
2018-12-13 11:01:24 +00:00
face = card . CardFaces [ 0 ] . ImageUris
}
2018-10-16 13:33:48 +00:00
photos [ i ] = tg . APIInlineQueryResultPhoto {
Type : "photo" ,
ResultID : card . ID ,
2018-12-13 11:01:24 +00:00
PhotoURL : face . Large ,
ThumbURL : face . Normal ,
2018-10-16 13:33:48 +00:00
Title : card . Name ,
2018-12-13 10:22:10 +00:00
Caption : strings . Join ( captions , " - " ) ,
2018-10-16 13:33:48 +00:00
Width : 672 ,
Height : 936 ,
ReplyMarkup : & tg . APIInlineKeyboardMarkup {
2018-12-13 10:22:10 +00:00
InlineKeyboard : [ ] [ ] tg . APIInlineKeyboardButton { buttons } ,
2018-10-16 13:33:48 +00:00
} ,
}
}
2018-09-17 10:26:24 +00:00
2018-10-16 13:33:48 +00:00
err = api . AnswerInlineQuery ( tg . InlineQueryResponse {
QueryID : update . Inline . QueryID ,
Results : photos ,
NextOffset : nextcard ,
} )
if err != nil {
fmt . Println ( err )
// DO SOMETHING
return
}
2018-09-17 13:52:18 +00:00
}
2018-10-16 13:33:48 +00:00
// 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 {
2018-12-13 11:05:25 +00:00
if card . ImageUris . Large == "" && card . CardFaces != nil {
2018-12-13 11:01:24 +00:00
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 ,
} )
}
2018-10-16 13:33:48 +00:00
}
}
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 ,
} )
2018-09-17 10:26:24 +00:00
}
2018-09-17 13:52:18 +00:00
}
2018-10-16 13:33:48 +00:00
}
2018-09-17 10:26:24 +00:00
2018-10-16 13:33:48 +00:00
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 : ]
2018-09-17 13:52:18 +00:00
}
2018-10-16 13:33:48 +00:00
return
2018-09-17 10:26:24 +00:00
}