183 lines
6.5 KiB
Go
183 lines
6.5 KiB
Go
package action
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/slack-go/slack/slackevents"
|
|
"github.com/slack-go/slack/socketmode"
|
|
"go.uber.org/zap"
|
|
"houston/appcontext"
|
|
"houston/common"
|
|
"houston/common/metrics"
|
|
"houston/common/util"
|
|
"houston/internal/processor/action/view"
|
|
"houston/logger"
|
|
"houston/model/incident"
|
|
incidentStatusModel "houston/model/incidentStatus"
|
|
severityModel "houston/model/severity"
|
|
"houston/model/team"
|
|
"houston/repository/severity"
|
|
incidentStatusService "houston/service/incidentStatus"
|
|
"houston/service/incidentUser"
|
|
incidentUserRequest "houston/service/request/incidentUser"
|
|
userService "houston/service/user"
|
|
"sync"
|
|
)
|
|
|
|
type MemberJoinAction struct {
|
|
client *socketmode.Client
|
|
incidentService *incident.Repository
|
|
teamService *team.Repository
|
|
severityService *severity.Repository
|
|
incidentStatusService incidentStatusService.IncidentStatusService
|
|
userService userService.UserService
|
|
incidentUserService incidentUser.IncidentUserService
|
|
}
|
|
|
|
func NewMemberJoinAction(socketModeClient *socketmode.Client, incidentService *incident.Repository, teamService *team.Repository, severityService *severity.Repository) *MemberJoinAction {
|
|
return &MemberJoinAction{
|
|
client: socketModeClient,
|
|
incidentService: incidentService,
|
|
teamService: teamService,
|
|
severityService: severityService,
|
|
incidentStatusService: appcontext.GetIncidentStatusService(),
|
|
userService: appcontext.GetUserService(),
|
|
incidentUserService: appcontext.GetIncidentUserService(),
|
|
}
|
|
}
|
|
|
|
func (mp *MemberJoinAction) PerformAction(memberJoinedChannelEvent *slackevents.MemberJoinedChannelEvent) {
|
|
logger.Info(fmt.Sprintf("processing member joined channel event: %v", memberJoinedChannelEvent))
|
|
|
|
incidentEntity, err := mp.incidentService.FindIncidentByChannelId(memberJoinedChannelEvent.Channel)
|
|
if err != nil {
|
|
logger.Error("error in searching incident", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.String("user_id", memberJoinedChannelEvent.User), zap.Error(err))
|
|
return
|
|
} else if err == nil && incidentEntity == nil {
|
|
logger.Info("incident not found", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.String("user_id", memberJoinedChannelEvent.User), zap.Error(err))
|
|
return
|
|
}
|
|
|
|
mp.postIncidentSummaryEphemeral(incidentEntity, memberJoinedChannelEvent)
|
|
|
|
go func() {
|
|
err := mp.addIncidentUserMapping(incidentEntity.ID, memberJoinedChannelEvent.User)
|
|
if err != nil {
|
|
logger.Error(fmt.Sprintf("failed to add incident-user mapping"), zap.Error(err))
|
|
metrics.PublishHoustonFlowFailureMetrics(util.ADD_INCIDENT_USER_MAPPING, err.Error())
|
|
}
|
|
}()
|
|
|
|
}
|
|
|
|
func (mp *MemberJoinAction) postIncidentSummaryEphemeral(
|
|
incidentEntity *incident.IncidentEntity, memberJoinedChannelEvent *slackevents.MemberJoinedChannelEvent,
|
|
) {
|
|
var (
|
|
responderTeam, reporterTeam *team.TeamEntity
|
|
severityEntity *severityModel.SeverityEntity
|
|
incidentStatus *incidentStatusModel.IncidentStatusDTO
|
|
errors common.ThreadSafeErrors
|
|
wg sync.WaitGroup
|
|
)
|
|
|
|
wg.Add(4)
|
|
|
|
go util.ExecuteConcurrentAction(&wg, func() {
|
|
team, err := mp.teamService.FindTeamById(incidentEntity.TeamId)
|
|
if err != nil {
|
|
logger.Error("error in fetching team", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.Uint("incident_id", incidentEntity.ID), zap.Error(err))
|
|
errors.AddErrors(err)
|
|
} else if team == nil {
|
|
logger.Info("team not found", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.Uint("incident_id", incidentEntity.ID))
|
|
errors.AddErrors(fmt.Errorf("team not found"))
|
|
} else {
|
|
responderTeam = team
|
|
}
|
|
})
|
|
|
|
go util.ExecuteConcurrentAction(&wg, func() {
|
|
severity, err := mp.severityService.FindSeverityById(incidentEntity.SeverityId)
|
|
if err != nil {
|
|
logger.Error("error in fetching severity", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.Uint("incident_id", incidentEntity.ID), zap.Error(err))
|
|
errors.AddErrors(err)
|
|
} else if severity == nil {
|
|
logger.Info("severity not found", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.Uint("incident_id", incidentEntity.ID))
|
|
errors.AddErrors(fmt.Errorf("severity not found"))
|
|
} else {
|
|
severityEntity = severity
|
|
}
|
|
})
|
|
|
|
go util.ExecuteConcurrentAction(&wg, func() {
|
|
status, err := mp.incidentStatusService.GetIncidentStatusByStatusId(incidentEntity.Status)
|
|
if err != nil {
|
|
logger.Error("error in fetching incident status", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.Uint("incident_id", incidentEntity.ID), zap.Error(err))
|
|
errors.AddErrors(err)
|
|
} else if status == nil {
|
|
logger.Info("incident status not found", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.Uint("incident_id", incidentEntity.ID))
|
|
errors.AddErrors(fmt.Errorf("incident status not found"))
|
|
} else {
|
|
incidentStatus = status
|
|
}
|
|
})
|
|
|
|
go util.ExecuteConcurrentAction(&wg, func() {
|
|
if incidentEntity.ReportingTeamId != nil {
|
|
team, err := mp.teamService.FindTeamById(*incidentEntity.ReportingTeamId)
|
|
if err != nil {
|
|
logger.Error("error in fetching reporting team", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.Uint("incident_id", incidentEntity.ID), zap.Error(err))
|
|
errors.AddErrors(err)
|
|
} else if team == nil {
|
|
logger.Info("reporting team not found", zap.String("channel", memberJoinedChannelEvent.Channel),
|
|
zap.Uint("incident_id", incidentEntity.ID))
|
|
errors.AddErrors(fmt.Errorf("reporting team not found"))
|
|
} else {
|
|
reporterTeam = team
|
|
}
|
|
}
|
|
})
|
|
|
|
wg.Wait()
|
|
if len(errors.GetErrors()) > 0 {
|
|
return
|
|
}
|
|
|
|
blocks := view.IncidentSummarySectionV3(
|
|
incidentEntity, reporterTeam, responderTeam, severityEntity, incidentStatus,
|
|
)
|
|
msgOption := view.IncidentEphemeralMessage(incidentEntity, blocks)
|
|
|
|
_, err := mp.client.PostEphemeral(memberJoinedChannelEvent.Channel, memberJoinedChannelEvent.User, msgOption)
|
|
if err != nil {
|
|
logger.Error("post response failed", zap.Error(err))
|
|
}
|
|
}
|
|
|
|
func (mp *MemberJoinAction) addIncidentUserMapping(incidentId uint, slackUserId string) error {
|
|
user, err := mp.userService.GetHoustonUserBySlackUserId(slackUserId)
|
|
if err != nil {
|
|
logger.Error(fmt.Sprintf("failed to get user with id %s : %v", slackUserId, err))
|
|
return err
|
|
} else if user == nil {
|
|
errMsg := fmt.Sprintf("user with id %s not found", slackUserId)
|
|
logger.Error(errMsg)
|
|
return fmt.Errorf(errMsg)
|
|
}
|
|
|
|
return mp.incidentUserService.AddIncidentUser(
|
|
incidentUserRequest.AddIncidentUserRequest{
|
|
IncidentID: incidentId,
|
|
UserID: user.ID,
|
|
},
|
|
)
|
|
}
|