matrix.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
  2. // Copyright (C) 2018 Tulir Asokan
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Affero General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Affero General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Affero General Public License
  15. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. package main
  17. import (
  18. log "maunium.net/go/maulogger"
  19. "maunium.net/go/mautrix-appservice"
  20. "maunium.net/go/gomatrix"
  21. )
  22. type MatrixListener struct {
  23. bridge *Bridge
  24. as *appservice.AppService
  25. log log.Logger
  26. stop chan struct{}
  27. }
  28. func NewMatrixListener(bridge *Bridge) *MatrixListener {
  29. return &MatrixListener{
  30. bridge: bridge,
  31. as: bridge.AppService,
  32. stop: make(chan struct{}, 1),
  33. log: bridge.Log.Sub("Matrix Listener"),
  34. }
  35. }
  36. func (ml *MatrixListener) Start() {
  37. for {
  38. select {
  39. case evt := <-ml.bridge.AppService.Events:
  40. ml.log.Debugln("Received Matrix event:", evt)
  41. switch evt.Type {
  42. case gomatrix.StateMember:
  43. ml.HandleMembership(evt)
  44. case gomatrix.EventMessage:
  45. ml.HandleMessage(evt)
  46. }
  47. case <-ml.stop:
  48. return
  49. }
  50. }
  51. }
  52. func (ml *MatrixListener) HandleBotInvite(evt *gomatrix.Event) {
  53. intent := ml.as.BotIntent()
  54. resp, err := intent.JoinRoom(evt.RoomID, "", nil)
  55. if err != nil {
  56. ml.log.Debugln("Failed to join room", evt.RoomID, "with invite from", evt.Sender)
  57. return
  58. }
  59. members, err := intent.JoinedMembers(resp.RoomID)
  60. if err != nil {
  61. ml.log.Debugln("Failed to get members in room", resp.RoomID, "after accepting invite from", evt.Sender)
  62. intent.LeaveRoom(resp.RoomID)
  63. return
  64. }
  65. if len(members.Joined) < 2 {
  66. ml.log.Debugln("Leaving empty room", resp.RoomID, "after accepting invite from", evt.Sender)
  67. intent.LeaveRoom(resp.RoomID)
  68. return
  69. }
  70. for mxid, _ := range members.Joined {
  71. if mxid == intent.UserID || mxid == evt.Sender {
  72. continue
  73. } else if true { // TODO check if mxid is WhatsApp puppet
  74. continue
  75. }
  76. ml.log.Debugln("Leaving multi-user room", resp.RoomID, "after accepting invite from", evt.Sender)
  77. intent.SendNotice(resp.RoomID, "This bridge is user-specific, please don't invite me into rooms with other users.")
  78. intent.LeaveRoom(resp.RoomID)
  79. return
  80. }
  81. user := ml.bridge.GetUser(evt.Sender)
  82. user.ManagementRoom = resp.RoomID
  83. user.Update()
  84. intent.SendNotice(user.ManagementRoom, "This room has been registered as your bridge management/status room.")
  85. ml.log.Debugln(resp.RoomID, "registered as a management room with", evt.Sender)
  86. }
  87. func (ml *MatrixListener) HandleMembership(evt *gomatrix.Event) {
  88. ml.log.Debugln(evt.Content, evt.Content.Membership, evt.GetStateKey())
  89. if evt.Content.Membership == "invite" && evt.GetStateKey() == ml.as.BotMXID() {
  90. ml.HandleBotInvite(evt)
  91. }
  92. }
  93. func (ml *MatrixListener) HandleMessage(evt *gomatrix.Event) {
  94. }
  95. func (ml *MatrixListener) Stop() {
  96. ml.stop <- struct{}{}
  97. }