package main
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"log"
"os"
"strings"
"git.fromouter.space/hamcha/tg"
"github.com/mattn/go-mastodon"
)
type mastodonConfig struct {
Server string
ClientID string
ClientSecret string
Email string
Password string
Chats []int64
}
var mastodonClient *mastodon.Client
var mastodonChats map[int64]bool
func mastodon_init() {
file, err := os.Open(*mastodonconf)
if err != nil {
return
}
defer file.Close()
var cfg mastodonConfig
err = json.NewDecoder(file).Decode(&cfg)
if err != nil {
log.Fatalf("[mastodon] ERR: Could not load mastodon config file (malformed or unreadable file): " + err.Error())
}
mastodonClient = mastodon.NewClient(&mastodon.Config{
Server: cfg.Server,
ClientID: cfg.ClientID,
ClientSecret: cfg.ClientSecret,
})
err = mastodonClient.Authenticate(context.Background(), cfg.Email, cfg.Password)
if err != nil {
log.Fatalf("[mastodon] ERR: Error authenticating: " + err.Error())
}
mastodonChats = make(map[int64]bool)
for _, chatid := range cfg.Chats {
mastodonChats[chatid] = true
}
log.Println("[mastodon] Loaded and ready!")
}
func mastodon_message(broker *tg.Broker, update tg.APIMessage) {
if isCommand(update, "post") {
// Make sure only whitelisted chats can post
if _, ok := mastodonChats[update.Chat.ChatID]; !ok {
broker.SendTextMessage(update.Chat, "Mi spiace, non puoi postare stati da qui!", &tg.MessageOptions{
ReplyID: &update.MessageID,
})
return
}
// Make replies work
if update.ReplyTo != nil {
update.User = update.ReplyTo.User
update.Text = update.ReplyTo.Text
if update.Text != nil && update.ReplyTo.Photo != nil {
update.Photo = update.ReplyTo.Photo
update.Caption = update.Text
}
}
// Check for media
if update.Photo != nil && update.Caption != nil {
maxsz := 0
photo := tg.APIPhotoSize{}
for _, curphoto := range update.Photo {
if curphoto.Width > maxsz {
maxsz = curphoto.Width
photo = curphoto
}
}
go broker.GetFile(photo.FileID, func(broker *tg.Broker, data tg.BrokerUpdate) {
if data.Type == tg.BError {
log.Printf("[mastodon] Received error from broker: %s\n", *data.Error)
broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &tg.MessageOptions{
ReplyID: &update.MessageID,
})
return
}
pbytes, err := base64.StdEncoding.DecodeString(*data.Bytes)
if err != nil {
log.Printf("[mastodon] Base64 decode error: %s\n", err.Error())
broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &tg.MessageOptions{
ReplyID: &update.MessageID,
})
return
}
imgreader := bytes.NewReader(pbytes)
broker.SendChatAction(update.Chat, tg.ActionUploadingPhoto)
attach, err := mastodonClient.UploadMediaFromReader(context.Background(), imgreader)
if err != nil {
log.Printf("[mastodon] Upload failed: %s\n", err.Error())
broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &tg.MessageOptions{
ReplyID: &update.MessageID,
})
return
}
status, err := sendToot(strings.TrimSpace(fmt.Sprintf("%s\n(da %s)", *(update.Caption), update.User.FirstName)), attach.ID)
if err != nil {
log.Printf("[mastodon] Send toot failed: %s\n", err.Error())
broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &tg.MessageOptions{
ReplyID: &update.MessageID,
})
return
}
broker.SendTextMessage(update.Chat, fmt.Sprintf("Fatto!", status.URL), &tg.MessageOptions{
ReplyID: &update.MessageID,
})
})
return
}
status, err := sendToot(fmt.Sprintf("%s\n(da %s)", *(update.Text), update.User.FirstName), "")
if err != nil {
log.Printf("[mastodon] Send toot failed: %s\n", err.Error())
broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &tg.MessageOptions{
ReplyID: &update.MessageID,
})
return
}
broker.SendTextMessage(update.Chat, fmt.Sprintf("Fatto!", status.URL), &tg.MessageOptions{
ReplyID: &update.MessageID,
})
}
}
func sendToot(status string, media mastodon.ID) (*mastodon.Status, error) {
var medialist []mastodon.ID
if media != "" {
medialist = []mastodon.ID{media}
}
return mastodonClient.PostStatus(context.Background(), &mastodon.Toot{
Status: status,
MediaIDs: medialist,
Sensitive: false,
Visibility: "public",
})
}