bridge.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package bridge
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. log "maunium.net/go/maulogger/v2"
  7. "maunium.net/go/mautrix"
  8. "maunium.net/go/mautrix/appservice"
  9. "gitlab.com/beeper/discord/config"
  10. "gitlab.com/beeper/discord/database"
  11. "gitlab.com/beeper/discord/version"
  12. )
  13. const (
  14. reconnectDelay = 10 * time.Second
  15. )
  16. type Bridge struct {
  17. config *config.Config
  18. log log.Logger
  19. as *appservice.AppService
  20. db *database.Database
  21. eventProcessor *appservice.EventProcessor
  22. matrixHandler *matrixHandler
  23. bot *appservice.IntentAPI
  24. }
  25. func New(cfg *config.Config) (*Bridge, error) {
  26. // Create the logger.
  27. logger, err := cfg.CreateLogger()
  28. if err != nil {
  29. return nil, err
  30. }
  31. logger.Infoln("Initializing version", version.String)
  32. // Create and initalize the app service.
  33. appservice, err := cfg.CreateAppService()
  34. if err != nil {
  35. return nil, err
  36. }
  37. appservice.Log = log.Sub("matrix")
  38. appservice.Init()
  39. // Create the bot.
  40. bot := appservice.BotIntent()
  41. // Setup the database.
  42. db, err := cfg.CreateDatabase(logger)
  43. if err != nil {
  44. return nil, err
  45. }
  46. // Create the bridge.
  47. bridge := &Bridge{
  48. as: appservice,
  49. db: db,
  50. bot: bot,
  51. config: cfg,
  52. log: logger,
  53. }
  54. // Setup the event processors
  55. bridge.setupEvents()
  56. return bridge, nil
  57. }
  58. func (b *Bridge) connect() error {
  59. b.log.Debugln("Checking connection to homeserver")
  60. for {
  61. resp, err := b.bot.Whoami()
  62. if err != nil {
  63. if errors.Is(err, mautrix.MUnknownToken) {
  64. b.log.Fatalln("Access token invalid. Is the registration installed in your homeserver correctly?")
  65. return fmt.Errorf("invalid access token")
  66. }
  67. b.log.Errorfln("Failed to connect to homeserver : %v", err)
  68. b.log.Errorfln("reconnecting in %s", reconnectDelay)
  69. time.Sleep(reconnectDelay)
  70. } else if resp.UserID != b.bot.UserID {
  71. b.log.Fatalln("Unexpected user ID in whoami call: got %s, expected %s", resp.UserID, b.bot.UserID)
  72. return fmt.Errorf("expected user id %q but got %q", b.bot.UserID, resp.UserID)
  73. } else {
  74. break
  75. }
  76. }
  77. b.log.Debugln("Connected to homeserver")
  78. return nil
  79. }
  80. func (b *Bridge) Start() error {
  81. b.log.Infoln("Bridge started")
  82. if err := b.connect(); err != nil {
  83. return err
  84. }
  85. b.log.Debugln("Starting application service HTTP server")
  86. go b.as.Start()
  87. b.log.Debugln("Starting event processor")
  88. go b.eventProcessor.Start()
  89. go b.updateBotProfile()
  90. // Finally tell the appservice we're ready
  91. b.as.Ready = true
  92. return nil
  93. }
  94. func (b *Bridge) Stop() {
  95. b.log.Infoln("Bridge stopped")
  96. }