package main import ( "bytes" "encoding/json" "fmt" "log" "net/http" "os" "github.com/ip2location/ip2location-go/v9" "github.com/joho/godotenv" ) var MATRIX_WEBHOOK_URL string var MATRIX_WEBHOOK_API_KEY string var MATRIX_ACCOUNT_CHANNEL string var MATRIX_REPORT_CHANNEL string var PORT string var IP2LOCATION_FILE string var MASTODON_INSTANCE string func init() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } MATRIX_WEBHOOK_URL = os.Getenv("MATRIX_WEBHOOK_URL") if MATRIX_WEBHOOK_URL == "" { log.Fatal("MATRIX_WEBHOOK_URL empty or invalid") } MATRIX_WEBHOOK_API_KEY = os.Getenv("MATRIX_WEBHOOK_API_KEY") if MATRIX_WEBHOOK_API_KEY == "" { log.Fatal("MATRIX_WEBHOOK_API_KEY empty or invalid") } MATRIX_ACCOUNT_CHANNEL = os.Getenv("MATRIX_ACCOUNT_CHANNEL") if MATRIX_ACCOUNT_CHANNEL == "" { log.Fatal("MATRIX_ACCOUNT_CHANNEL empty or invalid") } MATRIX_REPORT_CHANNEL = os.Getenv("MATRIX_REPORT_CHANNEL") if MATRIX_REPORT_CHANNEL == "" { log.Fatal("MATRIX_REPORT_CHANNEL empty or invalid") } MASTODON_INSTANCE = os.Getenv("MASTODON_INSTANCE") if MASTODON_INSTANCE == "" { log.Fatal("MASTODON_INSTANCE is empty or invalid") } PORT = os.Getenv("PORT") if PORT == "" { log.Fatal("PORT empty or invalid") } IP2LOCATION_FILE = os.Getenv("IP2LOCATION_FILE") } func main() { http.HandleFunc("/", handler) if err := http.ListenAndServe(":"+PORT, nil); err != nil { log.Fatal(err) } } // Handle requests func handler(w http.ResponseWriter, r *http.Request) { if r.Body != nil { var i MastodonEvent err := json.NewDecoder(r.Body).Decode(&i) if err != nil { log.Println(err.Error()) return } if i.Event == "report.created" { // Build message msg := fmt.Sprintf( "[New Report](%s): **%s** has reported **%s**: %s", fmt.Sprintf( "https://%s/admin/reports/%s", MASTODON_INSTANCE, i.Object.ID, ), i.Object.Account.Username, i.Object.TargetAccount.Username, i.Object.Comment, ) // Log to stdout log.Println(msg) // Send to matrix err = sendWebhook( msg, MATRIX_REPORT_CHANNEL, ) if err != nil { log.Println(err.Error()) return } } else if i.Event == "account.created" { // Build message country := ipLookup(i.Object.IP) msg := fmt.Sprintf( "[New Signup](%s) %s: **%s** (%s). %s", fmt.Sprintf( "https://%s/admin/accounts/%s", MASTODON_INSTANCE, i.Object.ID, ), country, i.Object.Username, i.Object.Email, fmt.Sprintf( "Notes: %s", i.Object.Notes, ), ) // Log to stdout log.Println(msg) // Send to matrix err = sendWebhook( msg, MATRIX_ACCOUNT_CHANNEL, ) if err != nil { log.Println(err.Error()) return } } else if i.Event == "account.approved" { msg := fmt.Sprintf( "[Signup Approved](%s): %s", fmt.Sprintf( "https://%s/admin/accounts/%s", MASTODON_INSTANCE, i.Object.ID, ), i.Object.Username, ) // Log to stdout log.Println(msg) // Send to Matrix err = sendWebhook( msg, MATRIX_ACCOUNT_CHANNEL, ) if err != nil { log.Println(err.Error()) return } } else { log.Printf("Unknown event %s", i.Event) } } } // sendWebhook - takes msg, sends to matrix func sendWebhook(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 } // log.Printf("Sending %s to %s", b, MATRIX_WEBHOOK_URL+"/"+channel) 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 } // Lookup to country! func ipLookup(ip string) string { if IP2LOCATION_FILE == "" { return "" } db, err := ip2location.OpenDB(IP2LOCATION_FILE) if err != nil { log.Print(err) return "" } results, err := db.Get_all(ip) if err != nil { log.Print(err) return "" } return " from " + results.Country_long }