fafomo/fafomo.go
2025-06-16 10:27:06 +02:00

126 lines
3.5 KiB
Go

// Copyright (C) 2024 Leah Neukirchen
//
// based on mautrix-go example code:
//
// Copyright (C) 2017 Tulir Asokan
// Copyright (C) 2018-2020 Luca Weiss
// Copyright (C) 2023 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package main
import (
"context"
"errors"
"flag"
"os"
"os/signal"
"strings"
"time"
"k8s.io/klog"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/id"
)
var (
flagMatrixHomeserver = "matrix.org"
flagMatrixUsername = "@fafomo:matrix.org"
flagMatrixPasswordFile = "password.txt"
flagPresenceMatrixRoom string
flagPresenceBackendURL string
flagStreamMatrixRoom string
)
func main() {
flag.StringVar(&flagMatrixHomeserver, "matrix_homeserver", flagMatrixHomeserver, "Address of Matrix homeserver")
flag.StringVar(&flagMatrixUsername, "matrix_username", flagMatrixUsername, "Matrix login username")
flag.StringVar(&flagMatrixPasswordFile, "matrix_password_file", flagMatrixPasswordFile, "Path to file containing matrix login password")
flag.StringVar(&flagPresenceMatrixRoom, "presence_matrix_room", flagPresenceMatrixRoom, "Matrix room MXID")
flag.StringVar(&flagPresenceBackendURL, "presence_backend_url", flagPresenceBackendURL, "Checkinator (backend) addresss")
flag.StringVar(&flagStreamMatrixRoom, "stream_matrix_room", flagStreamMatrixRoom, "Matrix room MXID")
flag.Parse()
for _, s := range []struct {
value string
name string
}{
{flagMatrixHomeserver, "matrix_homeserver"},
{flagMatrixUsername, "matrix_username"},
{flagMatrixPasswordFile, "matrix_password_file"},
} {
if s.value == "" {
klog.Exitf("-%s must be set", s.name)
}
}
startCtx, startCtxC := context.WithTimeout(context.Background(), 20*time.Second)
defer startCtxC()
client, err := mautrix.NewClient(flagMatrixHomeserver, id.UserID(flagMatrixUsername), "")
if err != nil {
klog.Exitf("NewClient failed: %v", err)
}
passwordBytes, err := os.ReadFile(flagMatrixPasswordFile)
if err != nil {
klog.Exitf("Could not read password file: %v", err)
}
password := strings.TrimSpace(string(passwordBytes))
klog.Infof("Logging in...")
login, err := client.Login(startCtx, &mautrix.ReqLogin{
Type: mautrix.AuthTypePassword,
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: flagMatrixUsername},
Password: password,
})
if err != nil {
klog.Exitf("Failed to log in: %v", err)
}
client.AccessToken = login.AccessToken
klog.Infof("Now running...")
ctx, ctxC := signal.NotifyContext(context.Background(), os.Interrupt)
defer ctxC()
// Run Matrix sync process in the background.
syncDone := make(chan struct{})
go func() {
err := client.SyncWithContext(ctx)
defer close(syncDone)
if err != nil && !errors.Is(err, ctx.Err()) {
klog.Exitf("Sync failed: %v", err)
}
}()
if flagPresenceMatrixRoom != "" || flagPresenceBackendURL != "" {
if flagPresenceMatrixRoom == "" || flagPresenceBackendURL == "" {
klog.Exitf("If presence_matrix_room is set, presence_backend_url must be set (and vice versa)")
}
klog.Infof("Starting presence module.")
go presence(ctx, client)
} else {
klog.Infof("NOT starting presence module.")
}
if flagStreamMatrixRoom != "" {
klog.Infof("Starting streaming module.")
go streaming(ctx, client)
} else {
klog.Infof("NOT starting streaming module.")
}
<-ctx.Done()
klog.Infof("Waiting for graceful sync before exiting...")
<-syncDone
klog.Infof("Done.")
}