-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
config.go
160 lines (147 loc) · 4.34 KB
/
config.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package main
import (
"encoding/json"
"fmt"
"github.com/go-playground/validator/v10"
"github.com/samgozman/fin-thread/journalist"
)
// Env is a structure that holds all the environment variables that are used in the app.
type Env struct {
TelegramChannelID string `mapstructure:"TELEGRAM_CHANNEL_ID" validate:"required"`
TelegramBotToken string `mapstructure:"TELEGRAM_BOT_TOKEN" validate:"required"`
OpenAiToken string `mapstructure:"OPENAI_TOKEN" validate:"required"`
TogetherAIToken string `mapstructure:"TOGETHER_AI_TOKEN" validate:"required"`
GoogleGeminiToken string `mapstructure:"GOOGLE_GEMINI_TOKEN"`
PostgresDSN string `mapstructure:"POSTGRES_DSN" validate:"required"`
SentryDSN string `mapstructure:"SENTRY_DSN" validate:"required"`
StockSymbols string `mapstructure:"STOCK_SYMBOLS" validate:"required"`
MarketJournalists string `mapstructure:"MARKET_JOURNALISTS" validate:"required,json"`
BroadJournalists string `mapstructure:"BROAD_JOURNALISTS" validate:"required,json"`
ServerName string `mapstructure:"SERVER_NAME"`
ShouldPublish bool `mapstructure:"SHOULD_PUBLISH" validate:"boolean"`
}
type Config struct {
env *Env // Holds all the environment variables that are used in the app
suspiciousKeywords []string // Used to "flag" suspicious news by the journalist.Journalist
rssProviders struct {
marketJournalists []journalist.NewsProvider // Market news journalists
broadJournalists []journalist.NewsProvider // Broad news journalists
}
}
// NewConfig creates a new Config object with the given Env and default values from DefaultConfig.
func NewConfig(env *Env) (*Config, error) {
c := DefaultConfig()
c.env = env
// unmarshal rss providers and validate them
marketJournalists, err := unmarshalRssProviders(env.MarketJournalists)
if err != nil {
return nil, fmt.Errorf("marketJournalists: %w", err)
}
broadJournalists, err := unmarshalRssProviders(env.BroadJournalists)
if err != nil {
return nil, fmt.Errorf("broadJournalists: %w", err)
}
c.rssProviders.marketJournalists = marketJournalists
c.rssProviders.broadJournalists = broadJournalists
return c, nil
}
// DefaultConfig creates a new Config object with default values.
func DefaultConfig() *Config {
return &Config{
env: &Env{},
suspiciousKeywords: []string{
"sign up",
"buy now",
"climate",
"activists",
"activism",
"advice",
"covid-19",
"study",
"humanitarian",
"award",
"research",
"human rights",
"united nations",
"adult content",
"pornography",
"porn",
"sexually",
"gender",
"sexuality",
"class action lawsuit",
"class-action lawsuit",
"subscribe",
"ark invest",
"cathie wood",
"bitcoin",
"ethereum",
"btc",
"eth",
"dogecoin",
"nft",
"technical charts",
"technical chart",
"technical analysis",
"technical indicator",
"technical pattern",
"golden cross",
"death cross",
"50-day",
"200-day",
"50 day",
"200 day",
"moving average",
"rsi",
"analysts say",
"analyst says",
"retirement",
"retire",
"401k",
"pension",
"i", // e.g. "I think"
"i'm", // e.g. "I'm thinking"
"me", // e.g. "me and my friends"
"my", // e.g. "my friends"
"?", // Question mark in the title is usually a bad sign (clickbait)
"if you",
"your money",
"your portfolio",
"your investments",
"this analyst",
"one analyst",
"some analysts",
"one expert",
"some experts",
"husband",
"wife",
"spouse",
"marriage",
"divorce",
"woke",
},
}
}
type rssProvider struct {
Name string `validate:"required"`
URL string `validate:"required,url"`
}
// unmarshalRssProviders unmarshal a JSON string into a slice of rssProvider objects.
func unmarshalRssProviders(str string) ([]journalist.NewsProvider, error) {
var rssProviderList []rssProvider
err := json.Unmarshal([]byte(str), &rssProviderList)
if err != nil {
return nil, fmt.Errorf("error unmarshalling journalists: %w", err)
}
for _, item := range rssProviderList {
err := validator.New().Struct(item)
if err != nil {
return nil, fmt.Errorf("error validating journalist: %w", err)
}
}
result := make([]journalist.NewsProvider, 0, len(rssProviderList))
for _, item := range rssProviderList {
result = append(result, journalist.NewRssProvider(item.Name, item.URL))
}
return result, nil
}