Add Mastodon, authenticated Twitter support.
This commit is contained in:
parent
44ba18063c
commit
2f4f6d8009
|
@ -4,3 +4,4 @@ README.md
|
|||
telegram-furryimgbot*
|
||||
.env
|
||||
*.json
|
||||
*.db*
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
telegram-furryimgbot*
|
||||
.env
|
||||
*.json
|
||||
*.db*
|
||||
|
|
|
@ -5,6 +5,9 @@ RUN apk add git g++
|
|||
RUN go build -o main
|
||||
|
||||
FROM alpine
|
||||
RUN apk add ca-certificates
|
||||
WORKDIR /app
|
||||
RUN mkdir /app/db
|
||||
COPY --from=builder /app/main .
|
||||
VOLUME /app/db
|
||||
CMD ["./main"]
|
||||
|
|
|
@ -6,10 +6,16 @@ After being configured (optional, will only do SFW images from FurAffinity thoug
|
|||
|
||||
## Configuration
|
||||
|
||||
Items either need to be set in config.json as lowercase or environment variables.
|
||||
|
||||
* `TOKEN` - Telegram Bot API token from Botfather
|
||||
* `DEBUG` - If debugging information should be printed
|
||||
* `FA_A` - FurAffinity cookie 'a'
|
||||
* `FA_B` - FurAffinity cookie 'b'
|
||||
* `TWITTER_CONSUMER_KEY` - Twitter application consumer access key
|
||||
* `TWITTER_SECRET_KEY` - Twitter application consumer secret key
|
||||
|
||||
If using Twitter credentials from users, the `db` folder must be persistent.
|
||||
|
||||
## Supported Sites
|
||||
|
||||
|
|
2
bot.go
2
bot.go
|
@ -23,7 +23,7 @@ func main() {
|
|||
f.API.Debug = false
|
||||
}
|
||||
|
||||
if f.Config.Get("debug") == "true" {
|
||||
if f.API.Debug {
|
||||
logger.Log.SetLevel(logrus.DebugLevel)
|
||||
} else {
|
||||
logger.Log.SetLevel(logrus.InfoLevel)
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Syfaro/finch"
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
|
||||
"huefox.com/syfaro/telegram-furryimgbot/data"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/dghubble/go-twitter/twitter"
|
||||
"github.com/dghubble/oauth1"
|
||||
twitterOAuth1 "github.com/dghubble/oauth1/twitter"
|
||||
)
|
||||
|
||||
type twitterAuthCommand struct {
|
||||
finch.CommandBase
|
||||
|
||||
oauthConfig *oauth1.Config
|
||||
|
||||
credentials map[int][]string
|
||||
credentialsSync *sync.Mutex
|
||||
}
|
||||
|
||||
func (cmd *twitterAuthCommand) Init(c *finch.CommandState, f *finch.Finch) error {
|
||||
cmd.CommandState = c
|
||||
cmd.Finch = f
|
||||
|
||||
config := &oauth1.Config{
|
||||
ConsumerKey: f.Config.Get("twitter_consumer_key").(string),
|
||||
ConsumerSecret: f.Config.Get("twitter_secret_key").(string),
|
||||
CallbackURL: "oob",
|
||||
Endpoint: twitterOAuth1.AuthorizeEndpoint,
|
||||
}
|
||||
|
||||
cmd.oauthConfig = config
|
||||
|
||||
cmd.credentials = make(map[int][]string)
|
||||
cmd.credentialsSync = &sync.Mutex{}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (twitterAuthCommand) Help() finch.Help {
|
||||
return finch.Help{
|
||||
Name: "Twitter Auth",
|
||||
Description: "Authorize with your Twitter account to get locked posts",
|
||||
Botfather: [][]string{
|
||||
[]string{"twitter", "Authorize your Twitter account"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (twitterAuthCommand) ShouldExecute(message tgbotapi.Message) bool {
|
||||
return finch.SimpleCommand("twitter", message.Text)
|
||||
}
|
||||
|
||||
func (cmd *twitterAuthCommand) Execute(message tgbotapi.Message) error {
|
||||
if !message.Chat.IsPrivate() {
|
||||
return cmd.QuickReply(message, "You may only use this command in a private chat")
|
||||
}
|
||||
|
||||
token, secret, err := cmd.oauthConfig.RequestToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.credentialsSync.Lock()
|
||||
cmd.credentials[message.From.ID] = []string{token, secret}
|
||||
cmd.credentialsSync.Unlock()
|
||||
|
||||
cmd.SetWaiting(message.From.ID)
|
||||
|
||||
authURL, err := cmd.oauthConfig.AuthorizationURL(token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := &strings.Builder{}
|
||||
|
||||
b.WriteString("Please visit the following URL to authorize your Twitter account, then tell me the returned code.\n\n")
|
||||
b.WriteString(authURL.String())
|
||||
|
||||
msg := tgbotapi.NewMessage(message.Chat.ID, b.String())
|
||||
msg.ReplyMarkup = tgbotapi.ForceReply{ForceReply: true, Selective: true}
|
||||
|
||||
cmd.SendMessage(msg)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *twitterAuthCommand) ExecuteWaiting(message tgbotapi.Message) error {
|
||||
cmd.ReleaseWaiting(message.From.ID)
|
||||
|
||||
code := strings.Trim(message.Text, " ")
|
||||
|
||||
cmd.credentialsSync.Lock()
|
||||
creds := cmd.credentials[message.From.ID]
|
||||
cmd.credentialsSync.Unlock()
|
||||
|
||||
access, secret, err := cmd.oauthConfig.AccessToken(creds[0], creds[1], code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = data.DB.Update(func(tx *bolt.Tx) error {
|
||||
b, err := tx.CreateBucketIfNotExists([]byte("twittercreds"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := json.Marshal(data.UserCred{
|
||||
AccessToken: access,
|
||||
SecretToken: secret,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return b.Put([]byte(strconv.Itoa(message.From.ID)), bytes)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
token := oauth1.NewToken(access, secret)
|
||||
|
||||
client := twitter.NewClient(cmd.oauthConfig.Client(oauth1.NoContext, token))
|
||||
|
||||
user, _, err := client.Accounts.VerifyCredentials(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmd.QuickReply(message, "Thank you, @"+user.ScreenName)
|
||||
}
|
||||
|
||||
func init() {
|
||||
finch.RegisterCommand(&twitterAuthCommand{})
|
||||
}
|
|
@ -25,7 +25,7 @@ func (i inline) Execute(f *finch.Finch, query tgbotapi.InlineQuery) error {
|
|||
for _, site := range sites.KnownSites {
|
||||
queryStr := strings.Trim(query.Query, " ")
|
||||
if site.IsSupportedURL(queryStr) {
|
||||
posts, e := site.GetImageURLs(queryStr)
|
||||
posts, e := site.GetImageURLs(queryStr, *query.From)
|
||||
err = e
|
||||
if posts != nil && len(posts) != 0 {
|
||||
for _, post := range posts {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"huefox.com/syfaro/telegram-furryimgbot/sites"
|
||||
)
|
||||
|
||||
var urlFinder = xurls.Strict
|
||||
var urlFinder = xurls.Strict()
|
||||
|
||||
func init() {
|
||||
finch.RegisterCommand(&messageCommand{})
|
||||
|
@ -42,7 +42,7 @@ func (messageCommand) Help() finch.Help {
|
|||
}
|
||||
|
||||
func (cmd messageCommand) processURL(site sites.Site, message tgbotapi.Message, url string) error {
|
||||
posts, err := site.GetImageURLs(url)
|
||||
posts, err := site.GetImageURLs(url, *message.From)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package data
|
||||
|
||||
import "github.com/boltdb/bolt"
|
||||
|
||||
// DB is a database for storing information.
|
||||
var DB *bolt.DB
|
||||
|
||||
// UserCred is user credentials for Twitter.
|
||||
type UserCred struct {
|
||||
AccessToken string `json:"access"`
|
||||
SecretToken string `json:"secret"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
d, err := bolt.Open("db/app.db", 0600, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
DB = d
|
||||
}
|
4
go.mod
4
go.mod
|
@ -4,9 +4,11 @@ require (
|
|||
github.com/PuerkitoBio/goquery v1.4.1
|
||||
github.com/Syfaro/finch v0.0.0-20181005000040-65a305514294
|
||||
github.com/andybalholm/cascadia v1.0.0 // indirect
|
||||
github.com/boltdb/bolt v1.3.1
|
||||
github.com/cenkalti/backoff v2.0.0+incompatible // indirect
|
||||
github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2 // indirect
|
||||
github.com/dghubble/go-twitter v0.0.0-20180817201112-a34e9059cd58
|
||||
github.com/dghubble/oauth1 v0.4.0
|
||||
github.com/dghubble/sling v1.1.0 // indirect
|
||||
github.com/getsentry/raven-go v0.0.0-20180903072508-084a9de9eb03 // indirect
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.3-0.20180922012028-898e79fe47da+incompatible
|
||||
|
@ -21,5 +23,5 @@ require (
|
|||
golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced
|
||||
golang.org/x/sys v0.0.0-20181005133103-4497e2df6f9e // indirect
|
||||
huefox.com/syfaro/go-e621 v1.0.0
|
||||
mvdan.cc/xurls v1.1.0
|
||||
mvdan.cc/xurls v1.1.1-0.20180901190342-70405f5eab51
|
||||
)
|
||||
|
|
10
go.sum
10
go.sum
|
@ -6,6 +6,8 @@ github.com/Syfaro/finch v0.0.0-20181005000040-65a305514294 h1:8UnlS1KsRGLiWGHjC1
|
|||
github.com/Syfaro/finch v0.0.0-20181005000040-65a305514294/go.mod h1:MQMvy4IFRZVDSFhjuAI3FYrvNxcgvKCJNl83wUxCyTI=
|
||||
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/cenkalti/backoff v2.0.0+incompatible h1:5IIPUHhlnUZbcHQsQou5k1Tn58nJkeJL9U+ig5CHJbY=
|
||||
github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2 h1:MmeatFT1pTPSVb4nkPmBFN/LRZ97vPjsFKsZrU3KKTs=
|
||||
|
@ -14,6 +16,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dghubble/go-twitter v0.0.0-20180817201112-a34e9059cd58 h1:wnxH1Y1QLw60flg8Cv8nmlnud57a9GqgzOvDMSIm1i4=
|
||||
github.com/dghubble/go-twitter v0.0.0-20180817201112-a34e9059cd58/go.mod h1:6beqTZaXeBPti9pDBcBEqxfJc7uCbSafqZPRDPQOKoM=
|
||||
github.com/dghubble/oauth1 v0.4.0 h1:+MpOsgByu02lzT4pRGei5d2p6nAgj8yDwF3RASrgNPQ=
|
||||
github.com/dghubble/oauth1 v0.4.0/go.mod h1:8V8BMV9DJRREZx/lUaHtrs7GUMXpzbMqJxINCasxYug=
|
||||
github.com/dghubble/sling v1.1.0 h1:DLu20Bq2qsB9cI5Hldaxj+TMPEaPpPE8IR2kvD22Atg=
|
||||
github.com/dghubble/sling v1.1.0/go.mod h1:ZcPRuLm0qrcULW2gOrjXrAWgf76sahqSyxXyVOvkunE=
|
||||
github.com/getsentry/raven-go v0.0.0-20180903072508-084a9de9eb03 h1:G/9fPivTr5EiyqE9OlW65iMRUxFXMGRHgZFGo50uG8Q=
|
||||
|
@ -28,6 +32,10 @@ github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f26
|
|||
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/mvdan/xurls v1.1.0 h1:OpuDelGQ1R1ueQ6sSryzi6P+1RtBpfQHM8fJwlE45ww=
|
||||
github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU=
|
||||
github.com/mvdan/xurls v1.1.1-0.20180901190342-70405f5eab51 h1:sOrGoHmQZ7SOhmPRzivxGfkAvEKWR0Pul+lCSI11sMM=
|
||||
github.com/mvdan/xurls v1.1.1-0.20180901190342-70405f5eab51/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
@ -57,3 +65,5 @@ huefox.com/syfaro/go-e621 v1.0.0 h1:DJrA8EfkXqzKasB4PKqy36gIONjpB0W5ZeV6Bi3tu3Y=
|
|||
huefox.com/syfaro/go-e621 v1.0.0/go.mod h1:8E1exlEIJz+yCtdIH6rqPtV9h5TcVTFOpyORBFzcP6A=
|
||||
mvdan.cc/xurls v1.1.0 h1:kj0j2lonKseISJCiq1Tfk+iTv65dDGCl0rTbanXJGGc=
|
||||
mvdan.cc/xurls v1.1.0/go.mod h1:TNWuhvo+IqbUCmtUIb/3LJSQdrzel8loVpgFm0HikbI=
|
||||
mvdan.cc/xurls v1.1.1-0.20180901190342-70405f5eab51 h1:hlah4i0IrBjAiDiEn0sVVk1bi2rHxWPpKcMfAT2Uot0=
|
||||
mvdan.cc/xurls v1.1.1-0.20180901190342-70405f5eab51/go.mod h1:TNWuhvo+IqbUCmtUIb/3LJSQdrzel8loVpgFm0HikbI=
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/Syfaro/finch"
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"huefox.com/syfaro/telegram-furryimgbot/logger"
|
||||
|
@ -58,7 +59,7 @@ func (direct) IsSupportedURL(url string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (d direct) GetImageURLs(postURL string) ([]PostInfo, error) {
|
||||
func (d direct) GetImageURLs(postURL string, _ tgbotapi.User) ([]PostInfo, error) {
|
||||
return []PostInfo{PostInfo{
|
||||
FileType: "something",
|
||||
URL: postURL,
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/Syfaro/finch"
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
goe621 "huefox.com/syfaro/go-e621"
|
||||
)
|
||||
|
||||
|
@ -16,7 +17,7 @@ func (e621) IsSupportedURL(url string) bool {
|
|||
return goe621.ParsePostURL(url) != nil || goe621.ParseDirectURL(url) != nil
|
||||
}
|
||||
|
||||
func (e e621) GetImageURLs(url string) ([]PostInfo, error) {
|
||||
func (e e621) GetImageURLs(url string, _ tgbotapi.User) ([]PostInfo, error) {
|
||||
var post *goe621.Post
|
||||
var err error
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/Syfaro/finch"
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
)
|
||||
|
||||
type fa struct {
|
||||
|
@ -27,7 +28,7 @@ func (fa) IsSupportedURL(url string) bool {
|
|||
return strings.Contains(url, "furaffinity.net/view/") || strings.Contains(url, "furaffinity.net/full/")
|
||||
}
|
||||
|
||||
func (f fa) GetImageURLs(postURL string) ([]PostInfo, error) {
|
||||
func (f fa) GetImageURLs(postURL string, _ tgbotapi.User) ([]PostInfo, error) {
|
||||
u, err := url.Parse(postURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/Syfaro/finch"
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
)
|
||||
|
||||
type mastodon struct {
|
||||
|
@ -62,7 +63,7 @@ type mastodonUsefulInfo struct {
|
|||
} `json:"media_attachments"`
|
||||
}
|
||||
|
||||
func (m mastodon) GetImageURLs(postURL string) ([]PostInfo, error) {
|
||||
func (m mastodon) GetImageURLs(postURL string, _ tgbotapi.User) ([]PostInfo, error) {
|
||||
match := mastodonExtractor.FindStringSubmatch(postURL)
|
||||
if match == nil {
|
||||
return nil, nil
|
||||
|
|
|
@ -5,14 +5,13 @@ import (
|
|||
"encoding/hex"
|
||||
|
||||
"github.com/Syfaro/finch"
|
||||
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
)
|
||||
|
||||
// Site is a supported site to load an image from.
|
||||
type Site interface {
|
||||
IsSupportedURL(url string) bool
|
||||
GetImageURLs(url string) ([]PostInfo, error)
|
||||
GetImageURLs(url string, from tgbotapi.User) ([]PostInfo, error)
|
||||
loadConfig(*finch.Finch)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
package sites
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/Syfaro/finch"
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"huefox.com/syfaro/telegram-furryimgbot/data"
|
||||
"huefox.com/syfaro/telegram-furryimgbot/logger"
|
||||
|
||||
"github.com/dghubble/go-twitter/twitter"
|
||||
"github.com/dghubble/oauth1"
|
||||
twitterOAuth1 "github.com/dghubble/oauth1/twitter"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/clientcredentials"
|
||||
)
|
||||
|
@ -13,13 +21,18 @@ import (
|
|||
var twitMatch = regexp.MustCompile(`https?:\/\/twitter\.com\/(?P<username>\w+)\/status\/(?P<id>\d+)`)
|
||||
|
||||
type twit struct {
|
||||
consumerKey, secretKey string
|
||||
|
||||
client *twitter.Client
|
||||
}
|
||||
|
||||
func (t *twit) loadConfig(f *finch.Finch) {
|
||||
t.consumerKey = f.Config.Get("twitter_consumer_key").(string)
|
||||
t.secretKey = f.Config.Get("twitter_secret_key").(string)
|
||||
|
||||
config := &clientcredentials.Config{
|
||||
ClientID: f.Config.Get("twitter_consumer_key").(string),
|
||||
ClientSecret: f.Config.Get("twitter_consumer_secret").(string),
|
||||
ClientID: t.consumerKey,
|
||||
ClientSecret: t.secretKey,
|
||||
TokenURL: "https://api.twitter.com/oauth2/token",
|
||||
}
|
||||
|
||||
|
@ -31,7 +44,7 @@ func (twit) IsSupportedURL(url string) bool {
|
|||
return twitMatch.MatchString(url)
|
||||
}
|
||||
|
||||
func (t twit) GetImageURLs(postURL string) ([]PostInfo, error) {
|
||||
func (t twit) GetImageURLs(postURL string, user tgbotapi.User) ([]PostInfo, error) {
|
||||
match := twitMatch.FindStringSubmatch(postURL)
|
||||
if match == nil {
|
||||
return nil, nil
|
||||
|
@ -40,13 +53,59 @@ func (t twit) GetImageURLs(postURL string) ([]PostInfo, error) {
|
|||
tweetIDStr := match[2]
|
||||
tweetID, _ := strconv.ParseInt(tweetIDStr, 10, 64)
|
||||
|
||||
status, _, err := t.client.Statuses.Show(tweetID, &twitter.StatusShowParams{
|
||||
TweetMode: "extended",
|
||||
var cred *data.UserCred
|
||||
|
||||
err := data.DB.View(func(t *bolt.Tx) error {
|
||||
b := t.Bucket([]byte("twittercreds"))
|
||||
if b == nil {
|
||||
logger.Log.Debug("twitter bucket does not exist")
|
||||
return nil
|
||||
}
|
||||
|
||||
bytes := b.Get([]byte(strconv.Itoa(user.ID)))
|
||||
if bytes == nil {
|
||||
logger.Log.WithField("user_id", user.ID).Debug("do not have credentials for user")
|
||||
return nil
|
||||
}
|
||||
|
||||
err := json.Unmarshal(bytes, &cred)
|
||||
if err != nil {
|
||||
logger.Log.WithField("user_id", user.ID).Debug("unable to get saved credentials")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var status *twitter.Tweet
|
||||
|
||||
if cred == nil {
|
||||
status, _, err = t.client.Statuses.Show(tweetID, &twitter.StatusShowParams{
|
||||
TweetMode: "extended",
|
||||
})
|
||||
} else {
|
||||
config := &oauth1.Config{
|
||||
ConsumerKey: t.consumerKey,
|
||||
ConsumerSecret: t.secretKey,
|
||||
Endpoint: twitterOAuth1.AuthorizeEndpoint,
|
||||
}
|
||||
token := oauth1.NewToken(cred.AccessToken, cred.SecretToken)
|
||||
client := twitter.NewClient(config.Client(oauth1.NoContext, token))
|
||||
|
||||
logger.Log.Debug("Using saved Twitter credentials")
|
||||
|
||||
status, _, err = client.Statuses.Show(tweetID, &twitter.StatusShowParams{
|
||||
TweetMode: "extended",
|
||||
})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if status == nil ||
|
||||
status.ExtendedEntities == nil ||
|
||||
status.ExtendedEntities.Media == nil ||
|
||||
|
|
Loading…
Reference in New Issue