package processor import ( "fmt" "github.com/slack-go/slack" "github.com/slack-go/slack/socketmode" "go.uber.org/zap" "houston/internal/diagnostic" "houston/internal/diagnostic/models" "houston/internal/processor/action" "houston/logger" "houston/pkg/slackbot" rcaService "houston/service/rca/impl" "strings" ) type CommandProcessor interface { ProcessSlashCommand(event *socketmode.Event) } type SlashCommandProcessor struct { socketModeClient *socketmode.Client slashCommandAction *action.HoustonCommandAction } type DiagnosticCommandProcessor struct { logger *zap.Logger socketModeClient *socketmode.Client diagnosticCommandActions []action.DiagnosticCommandActionHandler } func NewDiagnosticCommandProcessor(socketModeClient *socketmode.Client, repository *diagnostic.Repository) *DiagnosticCommandProcessor { return &DiagnosticCommandProcessor{ socketModeClient: socketModeClient, diagnosticCommandActions: []action.DiagnosticCommandActionHandler{ action.NewDeploymentConfigActionHandler(socketModeClient, repository), action.NewGrafanaActionHandler(socketModeClient, repository), //action.NewKibanaActionHandler(logger, socketModeClient), action.NewDeploymentPortalActionHandler(socketModeClient, repository), }, } } func NewSlashCommandProcessor( socketModeClient *socketmode.Client, slackBot *slackbot.Client, rcaService *rcaService.RcaService, ) *SlashCommandProcessor { return &SlashCommandProcessor{ socketModeClient: socketModeClient, slashCommandAction: action.NewHoustonCommandAction(socketModeClient, slackBot, rcaService), } } func (scp *SlashCommandProcessor) ProcessSlashCommand(event *socketmode.Event) { defer func() { if r := recover(); r != nil { logger.Error(fmt.Sprintf("[SCP] Exception occurred: %v", r.(error))) } }() scp.slashCommandAction.PerformAction(event) } func (dcp *DiagnosticCommandProcessor) ShouldProcessCommand(text string) bool { commands := strings.Split(text, " ") return len(commands) > 0 && commands[0] == "diagnose" } func (dcp *DiagnosticCommandProcessor) ProcessSlashCommand(e *socketmode.Event) { dcp.socketModeClient.Ack(*e.Request, nil) _, ok := e.Data.(slack.SlashCommand) if !ok { logger.Error("Unable to convert event to slash command", zap.Any("event", e)) return } cmd := e.Data.(slack.SlashCommand) postAckMessage(&dcp.socketModeClient.Client, &cmd) commands := strings.Split(cmd.Text, " ") runbooks := make([]models.Runbook, 0) for _, actionHandler := range dcp.diagnosticCommandActions { runbooks = append(runbooks, actionHandler.HandleAction(e, commands[1])) } diagnosticDataAssembler := diagnostic.NewDiagnosticDataAssembler2() image, text := diagnosticDataAssembler.HandleData(runbooks) postDataOnSlack(&dcp.socketModeClient.Client, &cmd, &image, text) logger.Error("S3 upload failed", zap.Any("error", e)) } func postDataOnSlack(api *slack.Client, sh *slack.SlashCommand, message *slack.MsgOption, attachments []slack.Attachment) { y, x, err := api.PostMessage( sh.ChannelID, *message, slack.MsgOptionAttachments(attachments...), ) if err != nil { fmt.Printf("error occured %s", err) } fmt.Println(y, x) } func postAckMessage(api *slack.Client, sh *slack.SlashCommand) { textBlock := slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("Your request has been acknowledged for\n> %s", sh.Text), false, false) block := slack.NewSectionBlock(textBlock, nil, nil) var messageBlock slack.MsgOption messageBlock = slack.MsgOptionBlocks(block) postDataOnSlack(api, sh, &messageBlock, nil) }