-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
130 lines (107 loc) · 3.71 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"fmt"
"log"
"os"
"github.com/St0iK/go-quote-bot/dao"
"github.com/dghubble/go-twitter/twitter"
"github.com/dghubble/oauth1"
)
// Config holds the application configuration including Twitter credentials
type Config struct {
TwitterCreds TwitterCredentials
}
// TwitterCredentials stores Twitter API authentication tokens
type TwitterCredentials struct {
ConsumerKey string
ConsumerSecret string
AccessToken string
AccessTokenSecret string
}
// TwitterClient wraps the Twitter client and provides application-specific functionality
type TwitterClient struct {
client *twitter.Client
}
// NewConfig creates a new Config instance from environment variables
func NewConfig() (*Config, error) {
creds := TwitterCredentials{
AccessToken: os.Getenv("ACCESS_TOKEN"),
AccessTokenSecret: os.Getenv("ACCESS_TOKEN_SECRET"),
ConsumerKey: os.Getenv("CONSUMER_KEY"),
ConsumerSecret: os.Getenv("CONSUMER_SECRET"),
}
// Validate credentials
if creds.AccessToken == "" || creds.AccessTokenSecret == "" ||
creds.ConsumerKey == "" || creds.ConsumerSecret == "" {
return nil, fmt.Errorf("missing required Twitter credentials in environment variables")
}
return &Config{
TwitterCreds: creds,
}, nil
}
// NewTwitterClient creates and authenticates a new Twitter client
func NewTwitterClient(creds TwitterCredentials) (*TwitterClient, error) {
config := oauth1.NewConfig(creds.ConsumerKey, creds.ConsumerSecret)
token := oauth1.NewToken(creds.AccessToken, creds.AccessTokenSecret)
httpClient := config.Client(oauth1.NoContext, token)
client := twitter.NewClient(httpClient)
// Verify credentials
verifyParams := &twitter.AccountVerifyParams{
SkipStatus: twitter.Bool(true),
IncludeEmail: twitter.Bool(true),
}
user, _, err := client.Accounts.VerifyCredentials(verifyParams)
if err != nil {
return nil, fmt.Errorf("failed to verify Twitter credentials: %w", err)
}
log.Printf("Authenticated as Twitter user: @%s", user.ScreenName)
return &TwitterClient{
client: client,
}, nil
}
// PostQuote posts a quote to Twitter
func (t *TwitterClient) PostQuote(quote *dao.Quote) error {
if quote == nil {
return fmt.Errorf("cannot post nil quote")
}
tweetText := formatTweet(quote)
tweet, _, err := t.client.Statuses.Update(tweetText, nil)
if err != nil {
return fmt.Errorf("failed to post tweet: %w", err)
}
log.Printf("Successfully posted tweet with ID: %d", tweet.ID)
return nil
}
// formatTweet creates a properly formatted tweet from a quote
func formatTweet(quote *dao.Quote) string {
return fmt.Sprintf("%s - %s #quotes #quote #inspiration",
quote.QuoteText,
quote.Author)
}
func main() {
log.Println("Starting Twitter Quote Bot v0.02")
// Initialize configuration
config, err := NewConfig()
if err != nil {
log.Fatalf("Failed to initialize configuration: %v", err)
}
// Initialize database connection
if err := dao.Connect(); err != nil {
log.Fatalf("Failed to connect to database: %v", err)
}
// Get random quote
quote, err := dao.GetRandomQuote()
if err != nil {
log.Fatalf("Failed to get random quote: %v", err)
}
// Initialize Twitter client
client, err := NewTwitterClient(config.TwitterCreds)
if err != nil {
log.Fatalf("Failed to initialize Twitter client: %v", err)
}
// Post quote to Twitter
if err := client.PostQuote(quote); err != nil {
log.Fatalf("Failed to post quote: %v", err)
}
log.Println("Quote successfully posted to Twitter")
}