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.

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