2018-09-17 10:26:24 +00:00
package main
import (
"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
2018-12-13 12:42:46 +00:00
"git.fromouter.space/hamcha/tg"
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
2020-01-29 11:46:04 +00:00
var MaxRequestsPerMessage int
2018-09-17 10:26:24 +00:00
func main ( ) {
2020-01-29 11:46:04 +00:00
MaxRequestsPerMessage , _ = strconv . Atoi ( os . Getenv ( "STAPPA_MAXREQ" ) )
2018-09-17 10:26:24 +00:00
2018-10-16 13:33:48 +00:00
// Set default maxreq
2020-01-29 11:46:04 +00:00
if MaxRequestsPerMessage < 1 {
MaxRequestsPerMessage = 5
2018-10-16 13:33:48 +00:00
}
2020-01-29 11:46:04 +00:00
api = tg . MakeAPIClient ( os . Getenv ( "STAPPA_TOKEN" ) )
api . SetWebhook ( os . Getenv ( "STAPPA_WEBHOOK" ) )
api . HandleWebhook ( os . Getenv ( "STAPPA_BIND" ) , os . Getenv ( "STAPPA_PATH" ) , webhook )
2018-09-17 10:26:24 +00:00
}
2018-12-13 12:40:46 +00:00
type CardFaceFlipPics struct {
Normal string
Flipped string
Scryfall string
Edhrec string
MCM string
}
2018-09-17 10:26:24 +00:00
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 12:55:39 +00:00
face , caption , buttons := getCardEntry ( card , 0 )
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 12:55:39 +00:00
Caption : caption ,
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 )
2020-01-29 11:46:04 +00:00
if len ( requests ) > MaxRequestsPerMessage {
2018-10-16 13:33:48 +00:00
api . SendTextMessage ( tg . ClientTextMessageData {
ChatID : update . Message . Chat . ChatID ,
2020-01-29 11:46:04 +00:00
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 ) , MaxRequestsPerMessage ) ,
2018-10-16 13:33:48 +00:00
ReplyID : & update . Message . MessageID ,
} )
return
}
cardmedia := [ ] tg . APIInputMediaPhoto { }
errlist := [ ] string { }
for _ , cardname := range requests {
2018-12-13 12:55:39 +00:00
card , err := scryfallGetCardByName ( cardname )
2018-10-16 13:33:48 +00:00
if err != nil {
errlist = append ( errlist , cardname )
} else {
2018-12-13 11:17:18 +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-12-13 12:40:46 +00:00
// Handle inline callback requests (flipped cards)
if update . Callback != nil {
2018-12-13 12:55:39 +00:00
if update . Callback . Data != nil && strings . HasPrefix ( * update . Callback . Data , "FLIP" ) {
parts := strings . SplitN ( * update . Callback . Data , "," , 3 )
card , err := scryfallGetCardByID ( parts [ 1 ] )
facenum , _ := strconv . Atoi ( parts [ 2 ] )
if err == nil {
2018-12-13 13:24:27 +00:00
face , caption , buttons := getCardEntry ( card , facenum )
2018-12-13 12:55:39 +00:00
api . EditMedia ( tg . ClientEditMediaData {
2018-12-13 13:03:49 +00:00
InlineID : * update . Callback . InlineID ,
2018-12-13 12:55:39 +00:00
Media : tg . APIInputMediaPhoto {
Type : "photo" ,
Media : face . Large ,
} ,
2018-12-13 13:24:27 +00:00
} )
api . EditCaption ( tg . ClientEditCaptionData {
InlineID : * update . Callback . InlineID ,
Caption : caption ,
2018-12-13 12:55:39 +00:00
ReplyMarkup : & tg . APIInlineKeyboardMarkup {
InlineKeyboard : [ ] [ ] tg . APIInlineKeyboardButton { buttons } ,
} ,
2018-12-13 12:40:46 +00:00
} )
}
} else {
fmt . Println ( "Unknown callback: " , * update . Callback . Data )
}
api . AnswerCallback ( tg . ClientCallbackQueryData {
QueryID : update . Callback . ID ,
} )
}
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
}
2018-12-13 12:55:39 +00:00
func getCardEntry ( card CardData , facenum int ) ( CardImage , string , [ ] tg . APIInlineKeyboardButton ) {
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 [ facenum ] . ImageUris
num := 1
if facenum != 0 {
num = 0
}
buttons = append ( buttons , tg . APIInlineKeyboardButton {
Text : "🔄" ,
CallbackData : fmt . Sprintf ( "FLIP,%s,%d" , card . ID , num ) ,
} )
}
return face , strings . Join ( captions , " - " ) , buttons
}