package slackapi import ( "net/http" "strings" "github.com/matrix-org/go-neb/types" log "github.com/sirupsen/logrus" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" ) // ServiceType of the Slack API service const ServiceType = "slackapi" // Service contains the Config fields for the Slack API service. // // This service will send HTML formatted messages into a room when an outgoing slack webhook // hits WebhookURL. // // Example JSON request: // { // "room_id": "!someroomid:some.domain.com", // "message_type": "m.text" // } type Service struct { types.DefaultService webhookEndpointURL string // The URL which should be given to an outgoing slack webhook - Populated by Go-NEB after Service registration. WebhookURL string `json:"webhook_url"` RoomID id.RoomID `json:"room_id"` MessageType event.MessageType `json:"message_type"` } // OnReceiveWebhook receives requests from a slack outgoing webhook and possibly sends requests // to Matrix as a result. // // This requires that the WebhookURL is given to an outgoing slack webhook (see https://api.slack.com/outgoing-webhooks) func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli types.MatrixClient) { segments := strings.Split(req.URL.Path, "/") if len(segments) < 2 { w.WriteHeader(400) return } messageType := s.MessageType if messageType == "" { messageType = event.MsgText } roomID := s.RoomID slackMessage, err := getSlackMessage(*req) if err != nil { log.WithFields(log.Fields{"slackMessage": slackMessage, log.ErrorKey: err}).Error("Slack message error") w.WriteHeader(500) return } htmlMessage, err := slackMessageToHTMLMessage(slackMessage) if err != nil { log.WithError(err).Error("Converting slack message to HTML") w.WriteHeader(500) return } htmlMessage.MsgType = messageType cli.SendMessageEvent( roomID, event.EventMessage, htmlMessage, ) w.WriteHeader(200) } // Register joins the configured room and sets the public WebhookURL func (s *Service) Register(oldService types.Service, client types.MatrixClient) error { s.WebhookURL = s.webhookEndpointURL if _, err := client.JoinRoom(s.RoomID.String(), "", nil); err != nil { log.WithFields(log.Fields{ log.ErrorKey: err, "room_id": s.RoomID, }).Error("Failed to join room") } return nil } func init() { types.RegisterService(func(serviceID string, serviceUserID id.UserID, webhookEndpointURL string) types.Service { return &Service{ DefaultService: types.NewDefaultService(serviceID, serviceUserID, ServiceType), webhookEndpointURL: webhookEndpointURL, } }) }