intent.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package appservice
  2. import (
  3. "fmt"
  4. "maunium.net/go/gomatrix"
  5. )
  6. type IntentAPI struct {
  7. *gomatrix.Client
  8. bot *gomatrix.Client
  9. as *AppService
  10. Localpart string
  11. UserID string
  12. }
  13. func (as *AppService) NewIntentAPI(localpart string) *IntentAPI {
  14. userID := fmt.Sprintf("@%s:%s", localpart, as.HomeserverDomain)
  15. bot := as.BotClient()
  16. if userID == bot.UserID {
  17. bot = nil
  18. }
  19. return &IntentAPI{
  20. Client: as.Client(userID),
  21. bot: bot,
  22. as: as,
  23. Localpart: localpart,
  24. UserID: userID,
  25. }
  26. }
  27. func (intent *IntentAPI) Register() error {
  28. _, _, err := intent.Client.Register(&gomatrix.ReqRegister{
  29. Username: intent.Localpart,
  30. })
  31. if err != nil {
  32. return err
  33. }
  34. return nil
  35. }
  36. func (intent *IntentAPI) EnsureRegistered() error {
  37. if intent.as.StateStore.IsRegistered(intent.UserID) {
  38. return nil
  39. }
  40. err := intent.Register()
  41. httpErr, ok := err.(gomatrix.HTTPError)
  42. if !ok || httpErr.RespError.ErrCode != "M_USER_IN_USE" {
  43. return err
  44. }
  45. intent.as.StateStore.MarkRegistered(intent.UserID)
  46. return nil
  47. }
  48. func (intent *IntentAPI) EnsureJoined(roomID string) error {
  49. if intent.as.StateStore.IsInRoom(roomID, intent.UserID) {
  50. return nil
  51. }
  52. if err := intent.EnsureRegistered(); err != nil {
  53. return err
  54. }
  55. resp, err := intent.JoinRoom(roomID, "", nil)
  56. if err != nil {
  57. httpErr, ok := err.(gomatrix.HTTPError)
  58. if !ok || httpErr.RespError.ErrCode != "M_FORBIDDEN" || intent.bot == nil {
  59. return httpErr
  60. }
  61. _, inviteErr := intent.bot.InviteUser(roomID, &gomatrix.ReqInviteUser{
  62. UserID: intent.UserID,
  63. })
  64. if inviteErr != nil {
  65. return err
  66. }
  67. resp, err = intent.JoinRoom(roomID, "", nil)
  68. if err != nil {
  69. return err
  70. }
  71. }
  72. intent.as.StateStore.SetMembership(resp.RoomID, intent.UserID, "join")
  73. return nil
  74. }
  75. func (intent *IntentAPI) SendMessageEvent(roomID string, eventType gomatrix.EventType, contentJSON interface{}) (*gomatrix.RespSendEvent, error) {
  76. if err := intent.EnsureJoined(roomID); err != nil {
  77. return nil, err
  78. }
  79. return intent.Client.SendMessageEvent(roomID, eventType, contentJSON)
  80. }
  81. func (intent *IntentAPI) SendMassagedMessageEvent(roomID string, eventType gomatrix.EventType, contentJSON interface{}, ts int64) (*gomatrix.RespSendEvent, error) {
  82. if err := intent.EnsureJoined(roomID); err != nil {
  83. return nil, err
  84. }
  85. return intent.Client.SendMassagedMessageEvent(roomID, eventType, contentJSON, ts)
  86. }
  87. func (intent *IntentAPI) SendStateEvent(roomID string, eventType gomatrix.EventType, stateKey string, contentJSON interface{}) (*gomatrix.RespSendEvent, error) {
  88. if err := intent.EnsureJoined(roomID); err != nil {
  89. return nil, err
  90. }
  91. return intent.Client.SendStateEvent(roomID, eventType, stateKey, contentJSON)
  92. }
  93. func (intent *IntentAPI) SendMassagedStateEvent(roomID string, eventType gomatrix.EventType, stateKey string, contentJSON interface{}, ts int64) (*gomatrix.RespSendEvent, error) {
  94. if err := intent.EnsureJoined(roomID); err != nil {
  95. return nil, err
  96. }
  97. return intent.Client.SendMassagedStateEvent(roomID, eventType, stateKey, contentJSON, ts)
  98. }
  99. func (intent *IntentAPI) StateEvent(roomID string, eventType gomatrix.EventType, stateKey string, outContent interface{}) (err error) {
  100. if err := intent.EnsureJoined(roomID); err != nil {
  101. return err
  102. }
  103. return intent.Client.StateEvent(roomID, eventType, stateKey, outContent)
  104. }
  105. func (intent *IntentAPI) PowerLevels(roomID string) (pl *gomatrix.PowerLevels, err error) {
  106. pl = intent.as.StateStore.GetPowerLevels(roomID)
  107. if pl == nil {
  108. pl = &gomatrix.PowerLevels{}
  109. err = intent.StateEvent(roomID, gomatrix.StatePowerLevels, "", pl)
  110. if err == nil {
  111. intent.as.StateStore.SetPowerLevels(roomID, pl)
  112. }
  113. }
  114. return
  115. }
  116. func (intent *IntentAPI) SetPowerLevels(roomID string, levels *gomatrix.PowerLevels) (resp *gomatrix.RespSendEvent, err error) {
  117. resp, err = intent.SendStateEvent(roomID, gomatrix.StatePowerLevels, "", &levels)
  118. if err == nil {
  119. intent.as.StateStore.SetPowerLevels(roomID, levels)
  120. }
  121. return
  122. }
  123. func (intent *IntentAPI) SetPowerLevel(roomID, userID string, level int) (*gomatrix.RespSendEvent, error) {
  124. pl, err := intent.PowerLevels(roomID)
  125. if err != nil {
  126. return nil, err
  127. }
  128. if pl.GetUserLevel(userID) != level {
  129. pl.SetUserLevel(userID, level)
  130. return intent.SendStateEvent(roomID, gomatrix.StatePowerLevels, "", &pl)
  131. }
  132. return nil, nil
  133. }
  134. func (intent *IntentAPI) UserTyping(roomID string, typing bool, timeout int64) (resp *gomatrix.RespTyping, err error) {
  135. if intent.as.StateStore.IsTyping(roomID, intent.UserID) == typing {
  136. return
  137. }
  138. resp, err = intent.Client.UserTyping(roomID, typing, timeout)
  139. if err != nil {
  140. return
  141. }
  142. if !typing {
  143. timeout = -1
  144. }
  145. intent.as.StateStore.SetTyping(roomID, intent.UserID, timeout)
  146. return
  147. }
  148. func (intent *IntentAPI) SendText(roomID, text string) (*gomatrix.RespSendEvent, error) {
  149. if err := intent.EnsureJoined(roomID); err != nil {
  150. return nil, err
  151. }
  152. return intent.Client.SendText(roomID, text)
  153. }
  154. func (intent *IntentAPI) SendImage(roomID, body, url string) (*gomatrix.RespSendEvent, error) {
  155. if err := intent.EnsureJoined(roomID); err != nil {
  156. return nil, err
  157. }
  158. return intent.Client.SendImage(roomID, body, url)
  159. }
  160. func (intent *IntentAPI) SendVideo(roomID, body, url string) (*gomatrix.RespSendEvent, error) {
  161. if err := intent.EnsureJoined(roomID); err != nil {
  162. return nil, err
  163. }
  164. return intent.Client.SendVideo(roomID, body, url)
  165. }
  166. func (intent *IntentAPI) SendNotice(roomID, text string) (*gomatrix.RespSendEvent, error) {
  167. if err := intent.EnsureJoined(roomID); err != nil {
  168. return nil, err
  169. }
  170. return intent.Client.SendNotice(roomID, text)
  171. }
  172. func (intent *IntentAPI) RedactEvent(roomID, eventID string, req *gomatrix.ReqRedact) (*gomatrix.RespSendEvent, error) {
  173. if err := intent.EnsureJoined(roomID); err != nil {
  174. return nil, err
  175. }
  176. return intent.Client.RedactEvent(roomID, eventID, req)
  177. }
  178. func (intent *IntentAPI) SetRoomName(roomID, roomName string) (*gomatrix.RespSendEvent, error) {
  179. return intent.SendStateEvent(roomID, gomatrix.StateRoomName, "", map[string]interface{}{
  180. "name": roomName,
  181. })
  182. }
  183. func (intent *IntentAPI) SetRoomAvatar(roomID, avatarURL string) (*gomatrix.RespSendEvent, error) {
  184. return intent.SendStateEvent(roomID, gomatrix.StateRoomAvatar, "", map[string]interface{}{
  185. "url": avatarURL,
  186. })
  187. }
  188. func (intent *IntentAPI) SetRoomTopic(roomID, topic string) (*gomatrix.RespSendEvent, error) {
  189. return intent.SendStateEvent(roomID, gomatrix.StateTopic, "", map[string]interface{}{
  190. "topic": topic,
  191. })
  192. }
  193. func (intent *IntentAPI) SetDisplayName(displayName string) error {
  194. if err := intent.EnsureRegistered(); err != nil {
  195. return err
  196. }
  197. return intent.Client.SetDisplayName(displayName)
  198. }
  199. func (intent *IntentAPI) SetAvatarURL(avatarURL string) error {
  200. if err := intent.EnsureRegistered(); err != nil {
  201. return err
  202. }
  203. return intent.Client.SetAvatarURL(avatarURL)
  204. }
  205. func (intent *IntentAPI) EnsureInvited(roomID, userID string) error {
  206. if !intent.as.StateStore.IsInvited(roomID, userID) {
  207. _, err := intent.Client.InviteUser(roomID, &gomatrix.ReqInviteUser{
  208. UserID: userID,
  209. })
  210. return err
  211. }
  212. return nil
  213. }