puppet.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. "maunium.net/go/mautrix-whatsapp/database"
  19. log "maunium.net/go/maulogger"
  20. "fmt"
  21. "regexp"
  22. "maunium.net/go/mautrix-whatsapp/types"
  23. "strings"
  24. )
  25. func (bridge *Bridge) ParsePuppetMXID(mxid types.MatrixUserID) (types.MatrixUserID, types.WhatsAppID, bool) {
  26. userIDRegex, err := regexp.Compile(fmt.Sprintf("^@%s:%s$",
  27. bridge.Config.Bridge.FormatUsername("([0-9]+)", "([0-9]+)"),
  28. bridge.Config.Homeserver.Domain))
  29. if err != nil {
  30. bridge.Log.Warnln("Failed to compile puppet user ID regex:", err)
  31. return "", "", false
  32. }
  33. match := userIDRegex.FindStringSubmatch(string(mxid))
  34. if match == nil || len(match) != 3 {
  35. return "", "", false
  36. }
  37. receiver := match[1]
  38. receiver = strings.Replace(receiver, "=40", "@", 1)
  39. colonIndex := strings.LastIndex(receiver, "=3")
  40. receiver = receiver[:colonIndex] + ":" + receiver[colonIndex+len("=3"):]
  41. return types.MatrixUserID(receiver), types.WhatsAppID(match[2]), true
  42. }
  43. func (bridge *Bridge) GetPuppetByMXID(mxid types.MatrixUserID) *Puppet {
  44. receiver, jid, ok := bridge.ParsePuppetMXID(mxid)
  45. if !ok {
  46. return nil
  47. }
  48. user := bridge.GetUser(receiver)
  49. if user == nil {
  50. return nil
  51. }
  52. return user.GetPuppetByJID(jid)
  53. }
  54. func (user *User) GetPuppetByMXID(mxid types.MatrixUserID) *Puppet {
  55. receiver, jid, ok := user.bridge.ParsePuppetMXID(mxid)
  56. if !ok || receiver != user.UserID {
  57. return nil
  58. }
  59. return user.GetPuppetByJID(jid)
  60. }
  61. func (user *User) GetPuppetByJID(jid types.WhatsAppID) *Puppet {
  62. puppet, ok := user.puppets[jid]
  63. if !ok {
  64. dbPuppet := user.bridge.DB.Puppet.Get(jid, user.UserID)
  65. if dbPuppet == nil {
  66. return nil
  67. }
  68. puppet = user.NewPuppet(dbPuppet)
  69. user.puppets[puppet.JID] = puppet
  70. }
  71. return puppet
  72. }
  73. func (user *User) GetAllPuppets() []*Puppet {
  74. dbPuppets := user.bridge.DB.Puppet.GetAll(user.UserID)
  75. output := make([]*Puppet, len(dbPuppets))
  76. for index, dbPuppet := range dbPuppets {
  77. puppet, ok := user.puppets[dbPuppet.JID]
  78. if !ok {
  79. puppet = user.NewPuppet(dbPuppet)
  80. user.puppets[dbPuppet.JID] = puppet
  81. }
  82. output[index] = puppet
  83. }
  84. return output
  85. }
  86. func (user *User) NewPuppet(dbPuppet *database.Puppet) *Puppet {
  87. return &Puppet{
  88. Puppet: dbPuppet,
  89. user: user,
  90. bridge: user.bridge,
  91. log: user.log.Sub(fmt.Sprintf("Puppet/%s", dbPuppet.JID)),
  92. }
  93. }
  94. type Puppet struct {
  95. *database.Puppet
  96. user *User
  97. bridge *Bridge
  98. log log.Logger
  99. }