229 lines
8.1 KiB
Go
229 lines
8.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"houston/appcontext"
|
|
"houston/common/metrics"
|
|
"houston/common/util"
|
|
"houston/internal/processor"
|
|
"houston/internal/resolver"
|
|
"houston/model/incident"
|
|
"houston/model/log"
|
|
"houston/model/team"
|
|
"houston/model/user"
|
|
"houston/pkg/rest"
|
|
"houston/pkg/slackbot"
|
|
rcaRepository "houston/repository/rca/impl"
|
|
"houston/repository/rcaInput"
|
|
"houston/repository/severity"
|
|
"houston/repository/tag"
|
|
"houston/service/documentService"
|
|
incidentServiceV2 "houston/service/incident/impl"
|
|
"houston/service/orchestration"
|
|
rcaService "houston/service/rca/impl"
|
|
slack2 "houston/service/slack"
|
|
|
|
"github.com/slack-go/slack"
|
|
"github.com/slack-go/slack/slackevents"
|
|
"github.com/slack-go/slack/socketmode"
|
|
"github.com/spf13/viper"
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
"houston/logger"
|
|
)
|
|
|
|
type slackHandler struct {
|
|
socketModeClient *socketmode.Client
|
|
slashCommandProcessor *processor.SlashCommandProcessor
|
|
commandProcessor processor.CommandProcessor
|
|
memberJoinCallbackProcessor *processor.MemberJoinedCallbackEventProcessor
|
|
channelUnarchivalEventProcessor *processor.ChannelUnarchivalEventProcessor
|
|
blockActionProcessor *processor.BlockActionProcessor
|
|
viewSubmissionProcessor *processor.ViewSubmissionProcessor
|
|
userChangeEventProcessor *processor.UserChangeEventProcessor
|
|
houstonCommandResolver *resolver.HoustonCommandResolver
|
|
memberLeftChannelEventProcessor *processor.MemberLeftChannelCallbackEventProcessor
|
|
}
|
|
|
|
func NewSlackHandler(
|
|
gormClient *gorm.DB, socketModeClient *socketmode.Client, orchestrator orchestration.IncidentOrchestrator,
|
|
) *slackHandler {
|
|
severityService := severity.NewSeverityRepository(gormClient)
|
|
logRepository := log.NewLogRepository(gormClient)
|
|
tagService := tag.NewTagRepository(gormClient)
|
|
teamService := team.NewTeamRepository(gormClient, logRepository)
|
|
incidentService := incident.NewIncidentRepository(
|
|
gormClient, appcontext.GetSeverityService(), appcontext.GetIncidentStatusService(),
|
|
logRepository, teamService, socketModeClient,
|
|
)
|
|
productsService := appcontext.GetProductsService()
|
|
userService := user.NewUserRepository(gormClient)
|
|
slackbotClient := slackbot.NewSlackClient(socketModeClient)
|
|
incidentServiceV2 := incidentServiceV2.NewIncidentServiceV2(gormClient)
|
|
slackService := slack2.NewSlackService()
|
|
// new services
|
|
rcaRepository := rcaRepository.NewRcaRepository(gormClient)
|
|
rcaInputRepository := rcaInput.NewRcaInputRepository(gormClient)
|
|
restClient := rest.NewHttpRestClient()
|
|
documentService := documentService.NewActionsImpl(restClient)
|
|
rcaService := rcaService.NewRcaService(
|
|
incidentServiceV2, slackService, documentService, rcaRepository,
|
|
rcaInputRepository, userService, appcontext.GetDriveService(), appcontext.GetIncidentJiraService(),
|
|
)
|
|
productTeamService := appcontext.GetProductTeamsService()
|
|
slashCommandProcessor := processor.NewSlashCommandProcessor(socketModeClient, slackbotClient, rcaService)
|
|
tagValueService := appcontext.GetTagValueService()
|
|
|
|
return &slackHandler{
|
|
socketModeClient: socketModeClient,
|
|
slashCommandProcessor: slashCommandProcessor,
|
|
memberJoinCallbackProcessor: processor.NewMemberJoinedCallbackEventProcessor(
|
|
socketModeClient, incidentService, teamService, severityService,
|
|
),
|
|
channelUnarchivalEventProcessor: processor.NewChannelUnarchivalEventProcessor(),
|
|
blockActionProcessor: processor.NewBlockActionProcessor(
|
|
socketModeClient,
|
|
incidentService,
|
|
teamService,
|
|
severityService,
|
|
tagService,
|
|
slackbotClient,
|
|
incidentServiceV2,
|
|
slackService, rcaService,
|
|
productsService,
|
|
productTeamService,
|
|
orchestrator,
|
|
tagValueService,
|
|
),
|
|
viewSubmissionProcessor: processor.NewViewSubmissionProcessor(
|
|
socketModeClient,
|
|
incidentService,
|
|
productsService,
|
|
productTeamService,
|
|
teamService,
|
|
severityService,
|
|
tagService,
|
|
teamService,
|
|
slackbotClient,
|
|
gormClient,
|
|
rcaService,
|
|
incidentServiceV2,
|
|
orchestrator,
|
|
tagValueService,
|
|
),
|
|
userChangeEventProcessor: processor.NewUserChangeEventProcessor(
|
|
socketModeClient, userService,
|
|
),
|
|
houstonCommandResolver: resolver.NewHoustonCommandResolver(
|
|
socketModeClient, slackbotClient, rcaService, productsService, orchestrator, tagValueService,
|
|
),
|
|
memberLeftChannelEventProcessor: processor.NewMemberLeftChannelCallbackEventProcessor(socketModeClient, *incidentServiceV2, appcontext.GetUserService()),
|
|
}
|
|
}
|
|
|
|
func (sh *slackHandler) HoustonConnect() {
|
|
go func() {
|
|
for evt := range sh.socketModeClient.Events {
|
|
metrics.PublishWebSocketEventMetrics(string(evt.Type))
|
|
switch evt.Type {
|
|
case socketmode.EventTypeConnecting:
|
|
{
|
|
logger.Info("houston connecting to slackbot with socket mode")
|
|
}
|
|
case socketmode.EventTypeConnectionError:
|
|
{
|
|
logger.Error("appToken : " + viper.GetString("houston.slack.app.token"))
|
|
logger.Error("botToken : " + viper.GetString("houston.slack.bot.token"))
|
|
logger.Error("houston connection failed.")
|
|
}
|
|
case socketmode.EventTypeConnected:
|
|
{
|
|
logger.Info("houston connected to slackbot with socket mode")
|
|
}
|
|
case socketmode.EventTypeEventsAPI:
|
|
{
|
|
ev, _ := evt.Data.(slackevents.EventsAPIEvent)
|
|
eventJson := &ev
|
|
serializedEventJson, eventErr := json.Marshal(eventJson)
|
|
if eventErr != nil {
|
|
logger.Error("error occurred while serializing the event object", zap.Any("error", eventErr))
|
|
} else {
|
|
if ev.InnerEvent.Type != util.UserChangeEvent {
|
|
logger.Info("event api", zap.String("event", string(serializedEventJson)))
|
|
}
|
|
}
|
|
switch ev.Type {
|
|
case slackevents.CallbackEvent:
|
|
innerEvent := ev.InnerEvent
|
|
|
|
switch innerEvent.Type {
|
|
case util.UserChangeEvent:
|
|
logger.Info(fmt.Sprintf("[UserChangeEvent-socket] received user change event: %v and Type: %s", ev.InnerEvent.Data, ev.InnerEvent.Type))
|
|
sh.userChangeEventProcessor.ProcessCommand(ev, evt.Request)
|
|
case util.ChannelUnarchiveEvent:
|
|
sh.channelUnarchivalEventProcessor.ProcessCommand(
|
|
innerEvent.Data.(*slackevents.ChannelUnarchiveEvent), *evt.Request, sh.socketModeClient,
|
|
)
|
|
}
|
|
|
|
switch innerEventData := innerEvent.Data.(type) {
|
|
case *slackevents.MemberJoinedChannelEvent:
|
|
sh.memberJoinCallbackProcessor.ProcessCommand(innerEventData, evt.Request)
|
|
case *slackevents.MemberLeftChannelEvent:
|
|
sh.memberLeftChannelEventProcessor.ProcessCommand(innerEventData, evt.Request)
|
|
}
|
|
}
|
|
}
|
|
case socketmode.EventTypeInteractive:
|
|
{
|
|
callback, _ := evt.Data.(slack.InteractionCallback)
|
|
|
|
switch callback.Type {
|
|
case slack.InteractionTypeBlockActions:
|
|
{
|
|
logger.Info(
|
|
"received interaction type block action",
|
|
zap.String("action_id", callback.ActionID), zap.String("block_id", callback.BlockID),
|
|
)
|
|
sh.blockActionProcessor.ProcessCommand(callback, evt.Request)
|
|
}
|
|
case slack.InteractionTypeViewSubmission:
|
|
{
|
|
logger.Info(
|
|
"received interaction type view submission",
|
|
zap.String("action_id", callback.ActionID), zap.String("block_id", callback.BlockID),
|
|
)
|
|
callbackJson := &callback
|
|
serializedCallbackJson, callbackErr := json.Marshal(callbackJson)
|
|
if callbackErr != nil {
|
|
logger.Error("error occurred while serializing the callback object", zap.Any("error", callbackErr))
|
|
} else {
|
|
logger.Info("callback data", zap.String("callback", string(serializedCallbackJson)))
|
|
}
|
|
requestJson := &evt.Request
|
|
serializedRequestJson, requestErr := json.Marshal(requestJson)
|
|
if requestErr != nil {
|
|
logger.Error("error occurred while serializing the request object", zap.Any("error", requestErr))
|
|
} else {
|
|
logger.Info("request data", zap.Any("request", serializedRequestJson))
|
|
}
|
|
sh.viewSubmissionProcessor.ProcessCommand(callback, evt.Request)
|
|
}
|
|
}
|
|
}
|
|
case socketmode.EventTypeSlashCommand:
|
|
{
|
|
sh.houstonCommandResolver.Resolve(&evt).ProcessSlashCommand(&evt)
|
|
}
|
|
default:
|
|
{
|
|
logger.Error("houston unexpected event type received", zap.String("event_type", string(evt.Type)))
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
go sh.socketModeClient.Run()
|
|
}
|