* TP-47360| created services to upload slack conversation to cloud and send urls to generate RCA * created rca input repository * TP-47360| enabled generating rca service on resolution * resolved merge conflicts * TP-47360| added migration script for creating rca input table * changed json response structure according to contract * added unit tests * removed api to make gen ai call * made changes in message format posted in slack * changed entity struct and adding flag to enable rca generation * attaching title, description and replies related to incident status block * made design changes in message format
197 lines
7.0 KiB
Go
197 lines
7.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"houston/common/util"
|
|
"houston/internal/cron"
|
|
"houston/internal/diagnostic"
|
|
"houston/internal/processor"
|
|
"houston/internal/resolver"
|
|
"houston/model/incident"
|
|
"houston/model/log"
|
|
"houston/model/severity"
|
|
"houston/model/shedlock"
|
|
"houston/model/tag"
|
|
"houston/model/team"
|
|
"houston/model/user"
|
|
"houston/pkg/rest"
|
|
"houston/pkg/slackbot"
|
|
rcaRepository "houston/repository/rca/impl"
|
|
"houston/repository/rcaInput"
|
|
"houston/service/documentService"
|
|
incidentServiceV2 "houston/service/incident"
|
|
"houston/service/rca"
|
|
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"
|
|
logger "houston/logger"
|
|
)
|
|
|
|
type slackHandler struct {
|
|
socketModeClient *socketmode.Client
|
|
slashCommandProcessor *processor.SlashCommandProcessor
|
|
memberJoinCallbackProcessor *processor.MemberJoinedCallbackEventProcessor
|
|
blockActionProcessor *processor.BlockActionProcessor
|
|
viewSubmissionProcessor *processor.ViewSubmissionProcessor
|
|
slashCommandResolver *resolver.SlashCommandResolver
|
|
diagnosticCommandProcessor *processor.DiagnosticCommandProcessor
|
|
userChangeEventProcessor *processor.UserChangeEventProcessor
|
|
}
|
|
|
|
func NewSlackHandler(gormClient *gorm.DB, socketModeClient *socketmode.Client) *slackHandler {
|
|
severityService := severity.NewSeverityRepository(gormClient)
|
|
logRepository := log.NewLogRepository(gormClient)
|
|
tagService := tag.NewTagRepository(gormClient)
|
|
teamService := team.NewTeamRepository(gormClient, logRepository)
|
|
incidentService := incident.NewIncidentRepository(gormClient, severityService, logRepository, teamService, socketModeClient)
|
|
userService := user.NewUserRepository(gormClient)
|
|
shedlockService := shedlock.NewShedlockRepository(gormClient)
|
|
slackbotClient := slackbot.NewSlackClient(socketModeClient)
|
|
slashCommandProcessor := processor.NewSlashCommandProcessor(socketModeClient, incidentService, slackbotClient)
|
|
grafanaRepository := diagnostic.NewDiagnoseRepository(gormClient)
|
|
diagnosticCommandProcessor := processor.NewDiagnosticCommandProcessor(socketModeClient, grafanaRepository)
|
|
incidentServiceV2 := incidentServiceV2.NewIncidentServiceV2(gormClient)
|
|
slackService := slack2.NewSlackService()
|
|
// new services
|
|
rcaRepository := rcaRepository.NewRcaRepository(gormClient)
|
|
rcaInputRepository := rcaInput.NewRcaInputRepository(gormClient)
|
|
restClient := rest.NewClientActionsImpl()
|
|
documentService := documentService.NewActionsImpl(restClient)
|
|
rcaService := rca.NewRcaService(incidentServiceV2, slackService, restClient, documentService, rcaRepository, rcaInputRepository, userService)
|
|
|
|
cron.RunJob(
|
|
socketModeClient,
|
|
gormClient,
|
|
incidentService,
|
|
severityService,
|
|
teamService,
|
|
shedlockService,
|
|
userService,
|
|
incidentServiceV2,
|
|
slackService,
|
|
)
|
|
|
|
return &slackHandler{
|
|
socketModeClient: socketModeClient,
|
|
slashCommandProcessor: slashCommandProcessor,
|
|
diagnosticCommandProcessor: diagnosticCommandProcessor,
|
|
memberJoinCallbackProcessor: processor.NewMemberJoinedCallbackEventProcessor(
|
|
socketModeClient, incidentService, teamService, severityService,
|
|
),
|
|
blockActionProcessor: processor.NewBlockActionProcessor(
|
|
socketModeClient, incidentService, teamService, severityService, tagService, slackbotClient, incidentServiceV2, slackService, rcaService,
|
|
),
|
|
viewSubmissionProcessor: processor.NewViewSubmissionProcessor(
|
|
socketModeClient, incidentService, teamService, severityService, tagService, teamService, slackbotClient, gormClient,
|
|
),
|
|
slashCommandResolver: resolver.NewSlashCommandResolver(
|
|
diagnosticCommandProcessor, slashCommandProcessor,
|
|
),
|
|
userChangeEventProcessor: processor.NewUserChangeEventProcessor(
|
|
socketModeClient, userService,
|
|
),
|
|
}
|
|
}
|
|
|
|
func (sh *slackHandler) HoustonConnect() {
|
|
go func() {
|
|
for evt := range sh.socketModeClient.Events {
|
|
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:
|
|
sh.userChangeEventProcessor.ProcessCommand(ev, evt.Request)
|
|
}
|
|
|
|
switch innerEventData := innerEvent.Data.(type) {
|
|
case *slackevents.MemberJoinedChannelEvent:
|
|
sh.memberJoinCallbackProcessor.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.String("request", string(serializedRequestJson)))
|
|
}
|
|
sh.viewSubmissionProcessor.ProcessCommand(callback, evt.Request)
|
|
}
|
|
}
|
|
}
|
|
case socketmode.EventTypeSlashCommand:
|
|
{
|
|
sh.slashCommandResolver.Resolve(&evt)
|
|
}
|
|
default:
|
|
{
|
|
logger.Error("houston unexpected event type received", zap.String("event_type", string(evt.Type)))
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
go sh.socketModeClient.Run()
|
|
}
|