1
0
Fork 0

Decouple layers 🚀

This commit is contained in:
Daniele Tricoli 2022-03-13 02:19:57 +01:00
parent 0ccb1226fc
commit a1b10758cd
7 changed files with 180 additions and 104 deletions

52
cfg/environ.go Normal file
View File

@ -0,0 +1,52 @@
package cfg
import (
"os"
"sort"
"strconv"
"strings"
)
const (
MASTODON_ACCESS_TOKEN = "MASTODON_ACCESS_TOKEN"
MASTODON_SERVER_ADDRESS = "MASTODON_SERVER_ADDRESS"
MASTODON_TOOT_FOOTER = "MASTODON_TOOT_FOOTER"
MASTODON_TOOT_MAX_CHARACTERS = "MASTODON_TOOT_MAX_CHARACTERS"
MASTODON_TOOT_VISIBILITY = "MASTODON_TOOT_VISIBILITY"
TELEGRAM_BOT_TOKEN = "TELEGRAM_BOT_TOKEN"
TELEGRAM_CHAT_ID = "TELEGRAM_CHAT_ID"
TELEGRAM_DEBUG = "TELEGRAM_DEBUG"
)
// Check the specified Mastodon visibility and return it if valid or return
// unlisted if it's not valid.
// The specified string will be cheched case unsensitive.
func parseMastodonVisibility(s string) string {
s = strings.ToLower(s)
// Keep sorted since we search inside.
visibilities := []string{"direct", "private", "public", "unlisted"}
r := sort.SearchStrings(visibilities, s)
if r < len(visibilities) && visibilities[r] == s {
return s
}
return "unlisted"
}
// Return configured Mastodon visibility for toot.
func GetMastodonVisibility() string {
return parseMastodonVisibility(os.Getenv(MASTODON_TOOT_VISIBILITY))
}
// Parse Mastodon max characters and return 500 as default in case of errors.
func parseMastodonMaxCharacters(s string) int {
if n, err := strconv.ParseUint(s, 10, 32); err == nil {
return int(n)
}
return 500
}
func GetMastodonMaxCharacters() int {
return parseMastodonMaxCharacters(os.Getenv(MASTODON_TOOT_MAX_CHARACTERS))
}

30
cfg/environ_test.go Normal file
View File

@ -0,0 +1,30 @@
package cfg
import (
"testing"
"github.com/alecthomas/assert"
)
func TestParseMastodonVisibility(t *testing.T) {
assert.Equal(t, parseMastodonVisibility("public"), "public")
assert.Equal(t, parseMastodonVisibility("direct"), "direct")
assert.Equal(t, parseMastodonVisibility("unlisted"), "unlisted")
assert.Equal(t, parseMastodonVisibility("private"), "private")
assert.Equal(t, parseMastodonVisibility("Public"), "public")
assert.Equal(t, parseMastodonVisibility("diRect"), "direct")
assert.Equal(t, parseMastodonVisibility("unlisTED"), "unlisted")
assert.Equal(t, parseMastodonVisibility("PRIVATE"), "private")
assert.Equal(t, parseMastodonVisibility("True"), "unlisted")
assert.Equal(t, parseMastodonVisibility("eriol"), "unlisted")
assert.Equal(t, parseMastodonVisibility(""), "unlisted")
assert.Equal(t, parseMastodonVisibility(" "), "unlisted")
}
func TestParseMastodonMaxCharacters(t *testing.T) {
assert.Equal(t, parseMastodonMaxCharacters("42"), 42)
assert.Equal(t, parseMastodonMaxCharacters("-42"), 500)
assert.Equal(t, parseMastodonMaxCharacters("hello"), 500)
}

View File

@ -1,20 +1,19 @@
package cmd package cmd
import ( import (
"context"
"fmt" "fmt"
"io" "io"
"log" "log"
"net/http" "net/http"
"os" "os"
"sort"
"strconv" "strconv"
"strings"
"github.com/cking/go-mastodon" mastodonapi "github.com/cking/go-mastodon"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"noa.mornie.org/eriol/telegram-group2mastodon/cfg"
"noa.mornie.org/eriol/telegram-group2mastodon/mastodon"
"noa.mornie.org/eriol/telegram-group2mastodon/utils" "noa.mornie.org/eriol/telegram-group2mastodon/utils"
) )
@ -23,7 +22,6 @@ const (
MASTODON_SERVER_ADDRESS = "MASTODON_SERVER_ADDRESS" MASTODON_SERVER_ADDRESS = "MASTODON_SERVER_ADDRESS"
MASTODON_TOOT_FOOTER = "MASTODON_TOOT_FOOTER" MASTODON_TOOT_FOOTER = "MASTODON_TOOT_FOOTER"
MASTODON_TOOT_MAX_CHARACTERS = "MASTODON_TOOT_MAX_CHARACTERS" MASTODON_TOOT_MAX_CHARACTERS = "MASTODON_TOOT_MAX_CHARACTERS"
MASTODON_TOOT_VISIBILITY = "MASTODON_TOOT_VISIBILITY"
TELEGRAM_BOT_TOKEN = "TELEGRAM_BOT_TOKEN" TELEGRAM_BOT_TOKEN = "TELEGRAM_BOT_TOKEN"
TELEGRAM_CHAT_ID = "TELEGRAM_CHAT_ID" TELEGRAM_CHAT_ID = "TELEGRAM_CHAT_ID"
TELEGRAM_DEBUG = "TELEGRAM_DEBUG" TELEGRAM_DEBUG = "TELEGRAM_DEBUG"
@ -38,15 +36,14 @@ var runCmd = &cobra.Command{
Every messages posted in the Telegram groups the bot is in will be posted into Every messages posted in the Telegram groups the bot is in will be posted into
the specified Mastodon account.`, the specified Mastodon account.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
mastodon_instance := os.Getenv(MASTODON_SERVER_ADDRESS) mastodonInstance := os.Getenv(MASTODON_SERVER_ADDRESS)
c := mastodon.NewClient(&mastodon.Config{ c := mastodonapi.NewClient(&mastodonapi.Config{
Server: mastodon_instance, Server: mastodonInstance,
AccessToken: os.Getenv(MASTODON_ACCESS_TOKEN), AccessToken: os.Getenv(MASTODON_ACCESS_TOKEN),
}) })
log.Println("Crating a new client for mastondon istance:", mastodon_instance) log.Println("Crating a new client for mastondon istance:", mastodonInstance)
max_characters := parseMastodonMaxCharacters(os.Getenv(MASTODON_TOOT_MAX_CHARACTERS)) allowedTelegramChat := parseTelegramChatID(os.Getenv(TELEGRAM_CHAT_ID))
allowed_telegram_chat := parseTelegramChatID(os.Getenv(TELEGRAM_CHAT_ID)) log.Println("Allowed telegram chat id:", allowedTelegramChat)
log.Println("Allowed telegram chat id:", allowed_telegram_chat)
bot, err := tgbotapi.NewBotAPI(os.Getenv(TELEGRAM_BOT_TOKEN)) bot, err := tgbotapi.NewBotAPI(os.Getenv(TELEGRAM_BOT_TOKEN))
if err != nil { if err != nil {
@ -62,39 +59,26 @@ the specified Mastodon account.`,
for update := range updates { for update := range updates {
chatID := update.Message.Chat.ID chatID := update.Message.Chat.ID
if chatID != allowed_telegram_chat { if chatID != allowedTelegramChat {
log.Printf("Error: telegram chat %d is not the allowed one: %d\n", log.Printf("Error: telegram chat %d is not the allowed one: %d\n",
chatID, chatID,
allowed_telegram_chat, allowedTelegramChat,
) )
continue continue
} }
if update.Message != nil { if update.Message != nil {
messageID := update.Message.MessageID messageID := update.Message.MessageID
maxChars := cfg.GetMastodonMaxCharacters()
tootVisibility := cfg.GetMastodonVisibility()
tootFooter := os.Getenv(MASTODON_TOOT_FOOTER)
if update.Message.Text != "" { if update.Message.Text != "" {
log.Printf("Text message received. Message id: %d\n", messageID) log.Printf("Text message received. Message id: %d\n", messageID)
text := update.Message.Text text := update.Message.Text
in_reply_to := "" messages := utils.SplitTextAtChunk(text, maxChars, tootFooter)
mastodon.PostToots(c, messages, tootVisibility)
toot_footer := os.Getenv(MASTODON_TOOT_FOOTER)
messages := utils.SplitTextAtChunk(text, max_characters, toot_footer)
for _, message := range messages {
status, err := c.PostStatus(context.Background(), &mastodon.Toot{
Status: message,
Visibility: parseMastodonVisibility(os.Getenv(MASTODON_TOOT_VISIBILITY)),
InReplyToID: mastodon.ID(in_reply_to),
})
if err != nil {
log.Printf("Could not post status: %v", err)
continue
}
log.Printf("Posted status %s", status.URL)
in_reply_to = string(status.ID)
}
} else if update.Message.Photo != nil { } else if update.Message.Photo != nil {
log.Printf("Photo received. Message id: %d\n", messageID) log.Printf("Photo received. Message id: %d\n", messageID)
@ -116,32 +100,14 @@ the specified Mastodon account.`,
log.Printf("Could not download file: %v", err) log.Printf("Could not download file: %v", err)
continue continue
} }
attachment, err := c.UploadMediaFromReader(
context.Background(), file)
if err != nil {
log.Printf("Could not upload media: %v", err)
continue
}
file.Close()
log.Printf("Posted attachment %s", attachment.TextURL)
mediaIds := [...]mastodon.ID{attachment.ID} mastodon.PostPhoto(
caption := update.Message.Caption c,
if len(caption) > max_characters { file,
caption = caption[:max_characters] update.Message.Caption,
} maxChars,
status, err := c.PostStatus(context.Background(), &mastodon.Toot{ tootVisibility,
// Write the caption in the toot because it almost probably )
// doesn't describe the image.
Status: caption,
MediaIDs: mediaIds[:],
Visibility: parseMastodonVisibility(os.Getenv(MASTODON_TOOT_VISIBILITY)),
})
if err != nil {
log.Printf("Could not post status: %v", err)
continue
}
log.Printf("Posted status %s", status.URL)
} }
} }
} }
@ -161,21 +127,6 @@ func parseBoolOrFalse(s string) bool {
return r return r
} }
// Check the specified Mastodon visibility and return it if valid or return
// unlisted if it's not valid.
// The specified string will be cheched case unsensitive.
func parseMastodonVisibility(s string) string {
s = strings.ToLower(s)
// Keep sorted since we search inside.
visibilities := []string{"direct", "private", "public", "unlisted"}
r := sort.SearchStrings(visibilities, s)
if r < len(visibilities) && visibilities[r] == s {
return s
}
return "unlisted"
}
func downloadFile(url string) (io.ReadCloser, error) { func downloadFile(url string) (io.ReadCloser, error) {
response, err := http.Get(url) response, err := http.Get(url)
if err != nil { if err != nil {
@ -189,15 +140,6 @@ func downloadFile(url string) (io.ReadCloser, error) {
return response.Body, nil return response.Body, nil
} }
// Parse Mastodon max characters and return 500 as default in case of errors.
func parseMastodonMaxCharacters(s string) int {
if n, err := strconv.ParseUint(s, 10, 32); err == nil {
return int(n)
}
return 500
}
func parseTelegramChatID(s string) int64 { func parseTelegramChatID(s string) int64 {
r, err := strconv.ParseInt(s, 10, 64) r, err := strconv.ParseInt(s, 10, 64)
if err != nil { if err != nil {

View File

@ -15,26 +15,3 @@ func TestParseBoolOrFalse(t *testing.T) {
assert.Equal(t, parseBoolOrFalse("FALSE"), false) assert.Equal(t, parseBoolOrFalse("FALSE"), false)
assert.Equal(t, parseBoolOrFalse("false"), false) assert.Equal(t, parseBoolOrFalse("false"), false)
} }
func TestParseMastodonVisibility(t *testing.T) {
assert.Equal(t, parseMastodonVisibility("public"), "public")
assert.Equal(t, parseMastodonVisibility("direct"), "direct")
assert.Equal(t, parseMastodonVisibility("unlisted"), "unlisted")
assert.Equal(t, parseMastodonVisibility("private"), "private")
assert.Equal(t, parseMastodonVisibility("Public"), "public")
assert.Equal(t, parseMastodonVisibility("diRect"), "direct")
assert.Equal(t, parseMastodonVisibility("unlisTED"), "unlisted")
assert.Equal(t, parseMastodonVisibility("PRIVATE"), "private")
assert.Equal(t, parseMastodonVisibility("True"), "unlisted")
assert.Equal(t, parseMastodonVisibility("eriol"), "unlisted")
assert.Equal(t, parseMastodonVisibility(""), "unlisted")
assert.Equal(t, parseMastodonVisibility(" "), "unlisted")
}
func TestParseMastodonMaxCharacters(t *testing.T) {
assert.Equal(t, parseMastodonMaxCharacters("42"), 42)
assert.Equal(t, parseMastodonMaxCharacters("-42"), 500)
assert.Equal(t, parseMastodonMaxCharacters("hello"), 500)
}

6
go.mod
View File

@ -3,6 +3,7 @@ module noa.mornie.org/eriol/telegram-group2mastodon
go 1.17 go 1.17
require ( require (
github.com/alecthomas/assert v1.0.0
github.com/cking/go-mastodon v0.0.6 github.com/cking/go-mastodon v0.0.6
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
github.com/spf13/cobra v1.3.0 github.com/spf13/cobra v1.3.0
@ -10,11 +11,16 @@ require (
) )
require ( require (
github.com/alecthomas/colour v0.1.0 // indirect
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gorilla/websocket v1.4.1 // indirect github.com/gorilla/websocket v1.4.1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
) )

10
go.sum
View File

@ -51,6 +51,12 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/alecthomas/assert v1.0.0 h1:3XmGh/PSuLzDbK3W2gUbRXwgW5lqPkuqvRgeQ30FI5o=
github.com/alecthomas/assert v1.0.0/go.mod h1:va/d2JC+M7F6s+80kl/R3G7FUiW6JzUO+hPhLyJ36ZY=
github.com/alecthomas/colour v0.1.0 h1:nOE9rJm6dsZ66RGWYSFrXw461ZIt9A6+nHgL7FRrDUk=
github.com/alecthomas/colour v0.1.0/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48=
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -263,6 +269,7 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
@ -310,6 +317,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@ -536,6 +545,7 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

59
mastodon/post.go Normal file
View File

@ -0,0 +1,59 @@
package mastodon
import (
"context"
"io"
"log"
mastodonapi "github.com/cking/go-mastodon"
)
// Post one or more toots.
func PostToots(client *mastodonapi.Client, messages []string, visibility string) {
in_reply_to := ""
for _, message := range messages {
status, err := client.PostStatus(context.Background(), &mastodonapi.Toot{
Status: message,
Visibility: visibility,
InReplyToID: mastodonapi.ID(in_reply_to),
})
if err != nil {
log.Printf("Could not post status: %v", err)
continue
}
log.Printf("Posted status %s", status.URL)
in_reply_to = string(status.ID)
}
}
// Post a photo on mastodon with caption.
func PostPhoto(
client *mastodonapi.Client,
file io.ReadCloser,
caption string,
maxCharacters int,
visibility string) {
attachment, err := client.UploadMediaFromReader(
context.Background(), file)
if err != nil {
log.Printf("Could not upload media: %v", err)
}
file.Close()
log.Printf("Posted attachment %s", attachment.TextURL)
mediaIds := [...]mastodonapi.ID{attachment.ID}
if len(caption) > maxCharacters {
caption = caption[:maxCharacters]
}
status, err := client.PostStatus(context.Background(), &mastodonapi.Toot{
// Write the caption in the toot because it almost probably
// doesn't describe the image.
Status: caption,
MediaIDs: mediaIds[:],
Visibility: visibility,
})
if err != nil {
log.Printf("Could not post status: %v", err)
}
log.Printf("Posted status %s", status.URL)
}