You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.6 KiB

  1. package slackapi
  2. import (
  3. "net/http"
  4. "strings"
  5. "github.com/matrix-org/go-neb/types"
  6. log "github.com/sirupsen/logrus"
  7. "maunium.net/go/mautrix"
  8. "maunium.net/go/mautrix/event"
  9. "maunium.net/go/mautrix/id"
  10. )
  11. // ServiceType of the Slack API service
  12. const ServiceType = "slackapi"
  13. // Service contains the Config fields for the Slack API service.
  14. //
  15. // This service will send HTML formatted messages into a room when an outgoing slack webhook
  16. // hits WebhookURL.
  17. //
  18. // Example JSON request:
  19. // {
  20. // "room_id": "!someroomid:some.domain.com",
  21. // "message_type": "m.text"
  22. // }
  23. type Service struct {
  24. types.DefaultService
  25. webhookEndpointURL string
  26. // The URL which should be given to an outgoing slack webhook - Populated by Go-NEB after Service registration.
  27. WebhookURL string `json:"webhook_url"`
  28. RoomID id.RoomID `json:"room_id"`
  29. MessageType event.MessageType `json:"message_type"`
  30. }
  31. // OnReceiveWebhook receives requests from a slack outgoing webhook and possibly sends requests
  32. // to Matrix as a result.
  33. //
  34. // This requires that the WebhookURL is given to an outgoing slack webhook (see https://api.slack.com/outgoing-webhooks)
  35. func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli *mautrix.Client) {
  36. segments := strings.Split(req.URL.Path, "/")
  37. if len(segments) < 2 {
  38. w.WriteHeader(400)
  39. return
  40. }
  41. messageType := s.MessageType
  42. if messageType == "" {
  43. messageType = event.MsgText
  44. }
  45. roomID := s.RoomID
  46. slackMessage, err := getSlackMessage(*req)
  47. if err != nil {
  48. log.WithFields(log.Fields{"slackMessage": slackMessage, log.ErrorKey: err}).Error("Slack message error")
  49. w.WriteHeader(500)
  50. return
  51. }
  52. htmlMessage, err := slackMessageToHTMLMessage(slackMessage)
  53. if err != nil {
  54. log.WithError(err).Error("Converting slack message to HTML")
  55. w.WriteHeader(500)
  56. return
  57. }
  58. htmlMessage.MsgType = messageType
  59. cli.SendMessageEvent(
  60. roomID, event.EventMessage, htmlMessage,
  61. )
  62. w.WriteHeader(200)
  63. }
  64. // Register joins the configured room and sets the public WebhookURL
  65. func (s *Service) Register(oldService types.Service, client *mautrix.Client) error {
  66. s.WebhookURL = s.webhookEndpointURL
  67. if _, err := client.JoinRoom(s.RoomID.String(), "", nil); err != nil {
  68. log.WithFields(log.Fields{
  69. log.ErrorKey: err,
  70. "room_id": s.RoomID,
  71. "user_id": client.UserID,
  72. }).Error("Failed to join room")
  73. }
  74. return nil
  75. }
  76. func init() {
  77. types.RegisterService(func(serviceID string, serviceUserID id.UserID, webhookEndpointURL string) types.Service {
  78. return &Service{
  79. DefaultService: types.NewDefaultService(serviceID, serviceUserID, ServiceType),
  80. webhookEndpointURL: webhookEndpointURL,
  81. }
  82. })
  83. }