diff --git a/.env.example b/.env.example index bc2f903..116e8e0 100644 --- a/.env.example +++ b/.env.example @@ -9,3 +9,7 @@ MATRIX_DB_SCHEMA=matrix MASTODON_DB_SCHEMA=mastodon_production MOBILIZON_DB_SCHEMA=mobilizon_prod PEERTUBE_DB_SCHEMA=peertube_prod + +MATRIX_WEBHOOK_URL="" +MATRIX_WEBHOOK_API_KEY="" +MATRIX_WEBHOOK_CHANNEL="" \ No newline at end of file diff --git a/README.md b/README.md index 74c25f1..56334bb 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ CREATE TABLE IF NOT EXISTS statsdb ( metric_value INT NOT NULL, PRIMARY KEY (id) ); -CREATE INDEX service_lookup ON statsdb USING btree (service,metric_name, metric_time); +CREATE UNIQUE INDEX service_lookup ON statsdb USING btree (service,metric_name, metric_time); GRANT ALL ON ALL TABLES IN SCHEMA public TO gomastodonstats; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO gomastodonstats; diff --git a/cmd/gomastodonstats/main.go b/cmd/gomastodonstats/main.go index 8b5ac2c..d42ac46 100644 --- a/cmd/gomastodonstats/main.go +++ b/cmd/gomastodonstats/main.go @@ -36,6 +36,19 @@ func main() { } + // Load matrix data if exists, else set URL blank + gms.MATRIX_WEBHOOK_URL = os.Getenv("MATRIX_WEBHOOK_URL") + gms.MATRIX_WEBHOOK_API_KEY = os.Getenv("MATRIX_WEBHOOK_API_KEY") + gms.MATRIX_WEBHOOK_CHANNEL = os.Getenv("MATRIX_ACCOUNT_CHANNEL") + if gms.MATRIX_WEBHOOK_URL == "" || + gms.MATRIX_WEBHOOK_API_KEY == "" || + gms.MATRIX_WEBHOOK_CHANNEL == "" { + log.Println("MATRIX_WEBHOOK info incompelete. Skipping") + + // Set URL empty so we can check this later on + gms.MATRIX_WEBHOOK_URL = "" + } + // Load schemas if set gms.PIXELFED_DB_SCHEMA = os.Getenv("PIXELFED_DB_SCHEMA") gms.MATRIX_DB_SCHEMA = os.Getenv("MATRIX_DB_SCHEMA") diff --git a/internal/gomastodonstats/consts.go b/internal/gomastodonstats/consts.go index c5261c1..1f2c089 100644 --- a/internal/gomastodonstats/consts.go +++ b/internal/gomastodonstats/consts.go @@ -10,6 +10,10 @@ var ( TIMEZONE string + MATRIX_WEBHOOK_URL string + MATRIX_WEBHOOK_API_KEY string + MATRIX_WEBHOOK_CHANNEL string + // UserCount metric name METRICNAME_USERCOUNT = "userCount" diff --git a/internal/gomastodonstats/main.go b/internal/gomastodonstats/main.go index 1d7ce89..1157f27 100644 --- a/internal/gomastodonstats/main.go +++ b/internal/gomastodonstats/main.go @@ -12,7 +12,7 @@ func Run() { } // Write to DB - persistMetrics(metrics) + updatedMetrics := persistMetrics(metrics) - // Output example + sendToMatrix(updatedMetrics) } diff --git a/internal/gomastodonstats/matrix.go b/internal/gomastodonstats/matrix.go new file mode 100644 index 0000000..535f296 --- /dev/null +++ b/internal/gomastodonstats/matrix.go @@ -0,0 +1,60 @@ +package gomastodonstats + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + "net/http" +) + +type MatrixWebhook struct { + Body string `json:"body"` + Key string `json:"key"` +} + +func sendToMatrix(m []metric) { + + startOfDay := getStartofDay() + msg := fmt.Sprintf( + "*User stats for %d:*\n\n", + startOfDay, + getPrintableString(m), + ) + + err := sendMatrixWebhook(msg, MATRIX_WEBHOOK_CHANNEL) + if err != nil { + log.Print(err) + } +} + +// sendMatrixWebhook - takes msg, sends to matrix +func sendMatrixWebhook(msgText string, channel string) error { + // log.Println(msgText) + data := MatrixWebhook{ + Key: MATRIX_WEBHOOK_API_KEY, + } + data.Body = msgText + b, err := json.Marshal(data) + if err != nil { + return err + } + + req, err := http.NewRequest("POST", MATRIX_WEBHOOK_URL+"/"+channel, bytes.NewBuffer(b)) + if err != nil { + return err + } + + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Print(err) + return nil + } + + defer resp.Body.Close() + + return nil +} diff --git a/internal/gomastodonstats/metrics.go b/internal/gomastodonstats/metrics.go index fa959c4..8a4ad92 100644 --- a/internal/gomastodonstats/metrics.go +++ b/internal/gomastodonstats/metrics.go @@ -1,6 +1,7 @@ package gomastodonstats import ( + "fmt" "log" "time" ) @@ -13,15 +14,22 @@ type metric struct { MetricValue int `json:"metric_value"` } -func persistMetrics(metrics []metric) { +// persistMetrics - return any updated +func persistMetrics(metrics []metric) []metric { + var updatedMetrics []metric + startOfDay := getStartofDay() for _, v := range metrics { v.MetricTime = startOfDay err := insertValues(v) if err != nil { log.Println(err) + } else { + updatedMetrics = append(updatedMetrics, v) } } + + return updatedMetrics } func getUserCounts() ([]metric, error) { @@ -104,3 +112,13 @@ func getUserCounts() ([]metric, error) { return metrics, nil } + +func getPrintableString(m []metric) string { + output := "" + + for _, v := range m { + output = fmt.Sprintf("%s\n%s: %d", output, v.Service, v.MetricValue) + } + + return output +}