mirror-nourybot-matrix/main.go

140 lines
3.5 KiB
Go
Raw Normal View History

2023-05-04 05:57:44 +02:00
package main
import (
"context"
"errors"
"flag"
"fmt"
"os"
"sync"
"time"
"github.com/chzyer/readline"
_ "github.com/mattn/go-sqlite3"
"github.com/rs/zerolog"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/crypto/cryptohelper"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
var homeserver = flag.String("homeserver", "", "Matrix homeserver")
var username = flag.String("username", "", "Matrix username localpart")
var password = flag.String("password", "", "Matrix passsword")
var database = flag.String("database", "mautrix-example.db", "SQLite database path")
var debug = flag.Bool("debug", false, "Enable debug logs")
func main() {
flag.Parse()
if *username == "" || *password == "" || *homeserver == "" {
_, _ = fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
flag.PrintDefaults()
os.Exit(1)
}
client, err := mautrix.NewClient(*homeserver, "", "")
if err != nil {
panic(err)
}
rl, err := readline.New("[no room]> ")
if err != nil {
panic(err)
}
defer rl.Close()
log := zerolog.New(zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) {
w.Out = rl.Stdout()
w.TimeFormat = time.Stamp
})).With().Timestamp().Logger()
if !*debug {
log = log.Level(zerolog.InfoLevel)
}
client.Log = log
var lastRoomID id.RoomID
syncer := client.Syncer.(*mautrix.DefaultSyncer)
syncer.OnEventType(event.EventMessage, func(source mautrix.EventSource, evt *event.Event) {
lastRoomID = evt.RoomID
rl.SetPrompt(fmt.Sprintf("%s> ", lastRoomID))
log.Info().
Str("sender", evt.Sender.String()).
Str("type", evt.Type.String()).
Str("id", evt.ID.String()).
Str("body", evt.Content.AsMessage().Body).
Msg("Received message")
})
syncer.OnEventType(event.StateMember, func(source mautrix.EventSource, evt *event.Event) {
if evt.GetStateKey() == client.UserID.String() && evt.Content.AsMember().Membership == event.MembershipInvite {
_, err := client.JoinRoomByID(evt.RoomID)
if err == nil {
lastRoomID = evt.RoomID
rl.SetPrompt(fmt.Sprintf("%s> ", lastRoomID))
log.Info().
Str("room_id", evt.RoomID.String()).
Str("inviter", evt.Sender.String()).
Msg("Joined room after invite")
} else {
log.Error().Err(err).
Str("room_id", evt.RoomID.String()).
Str("inviter", evt.Sender.String()).
Msg("Failed to join room after invite")
}
}
})
cryptoHelper, err := cryptohelper.NewCryptoHelper(client, []byte("meow"), *database)
if err != nil {
panic(err)
}
cryptoHelper.LoginAs = &mautrix.ReqLogin{
Type: mautrix.AuthTypePassword,
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: *username},
Password: *password,
}
err = cryptoHelper.Init()
if err != nil {
panic(err)
}
client.Crypto = cryptoHelper
log.Info().Msg("Now running")
syncCtx, cancelSync := context.WithCancel(context.Background())
var syncStopWait sync.WaitGroup
syncStopWait.Add(1)
go func() {
err = client.SyncWithContext(syncCtx)
defer syncStopWait.Done()
if err != nil && !errors.Is(err, context.Canceled) {
panic(err)
}
}()
for {
line, err := rl.Readline()
if err != nil {
break
}
if lastRoomID == "" {
log.Error().Msg("Wait for an incoming message before sending messages")
continue
}
resp, err := client.SendText(lastRoomID, line)
if err != nil {
log.Error().Err(err).Msg("Failed to send event")
} else {
log.Info().Str("event_id", resp.EventID.String()).Msg("Event sent")
}
}
cancelSync()
syncStopWait.Wait()
err = cryptoHelper.Close()
if err != nil {
log.Error().Err(err).Msg("Error closing database")
}
}