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.5 KiB

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