-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathmain.go
140 lines (117 loc) · 3.32 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
131
132
133
134
135
136
137
138
139
140
package main
import (
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/francoispqt/onelog"
"github.com/go-chi/chi"
"github.com/joeirimpan/listmonk-messenger/messenger"
"github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/toml"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/providers/posflag"
flag "github.com/spf13/pflag"
)
var (
logger = log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile)
ko = koanf.New(".")
// Version of the build injected at build time.
buildString = "unknown"
)
type MessengerCfg struct {
Config string `koanf:"config"`
}
type App struct {
logger *onelog.Logger
messengers map[string]messenger.Messenger
}
func init() {
f := flag.NewFlagSet("config", flag.ContinueOnError)
f.Usage = func() {
fmt.Println(f.FlagUsages())
os.Exit(0)
}
f.StringSlice("config", []string{"config.toml"},
"Path to one or more TOML config files to load in order")
f.StringSlice("msgr", []string{"pinpoint"},
"Name of messenger. Can specify multiple values.")
f.Bool("version", false, "Show build version")
if err := f.Parse(os.Args[1:]); err != nil {
log.Fatalf("error parsing flags: %v", err)
}
// Display version.
if ok, _ := f.GetBool("version"); ok {
fmt.Println(buildString)
os.Exit(0)
}
// Read the config files.
cFiles, _ := f.GetStringSlice("config")
for _, f := range cFiles {
log.Printf("reading config: %s", f)
if err := ko.Load(file.Provider(f), toml.Parser()); err != nil {
log.Printf("error reading config: %v", err)
}
}
if err := ko.Load(posflag.Provider(f, ".", ko), nil); err != nil {
log.Fatalf("error loading flags: %v", err)
}
}
// loadMessengers loads all messages mentioned in posflag into application.
func loadMessengers(msgrs []string, app *App) {
app.messengers = make(map[string]messenger.Messenger)
for _, m := range msgrs {
var cfg MessengerCfg
if err := ko.Unmarshal("messenger."+m, &cfg); err != nil {
log.Fatalf("error reading %s messenger config: %v", m, err)
}
var (
msgr messenger.Messenger
err error
)
switch m {
case "pinpoint":
msgr, err = messenger.NewPinpoint([]byte(cfg.Config), app.logger)
case "ses":
msgr, err = messenger.NewAWSSES([]byte(cfg.Config), app.logger)
case "twilio":
msgr, err = messenger.NewTwilio([]byte(cfg.Config), app.logger)
default:
log.Fatalf("invalid provider: %s", m)
}
if err != nil {
log.Fatalf("error creating %s messenger: %v", m, err)
}
app.messengers[m] = msgr
log.Printf("loaded %s\n", m)
}
}
func main() {
logLevels := onelog.INFO | onelog.WARN | onelog.ERROR | onelog.FATAL
if ko.String("log_level") == "debug" {
logLevels |= onelog.DEBUG
}
// setup logger
l := onelog.NewContext(os.Stderr, logLevels, "p")
l.Hook(func(e onelog.Entry) {
e.String("ts", time.Now().Format(time.RFC3339Nano))
e.String("line", l.Caller(5))
})
// load messengers
app := &App{logger: l}
loadMessengers(ko.Strings("msgr"), app)
r := chi.NewRouter()
r.Post("/webhook/{provider}", wrap(app, handlePostback))
// HTTP Server.
srv := &http.Server{
Addr: ko.String("server.address"),
ReadTimeout: ko.Duration("server.read_timeout"),
WriteTimeout: ko.Duration("server.write_timeout"),
Handler: r,
}
logger.Printf("starting on %s", srv.Addr)
if err := srv.ListenAndServe(); err != nil {
logger.Fatalf("couldn't start server: %v", err)
}
}