package slacknotifications.teamcity; import jetbrains.buildServer.Build; import jetbrains.buildServer.notification.Notificator; import jetbrains.buildServer.notification.NotificatorRegistry; import jetbrains.buildServer.responsibility.ResponsibilityEntry; import jetbrains.buildServer.responsibility.TestNameResponsibilityEntry; import jetbrains.buildServer.serverSide.*; import jetbrains.buildServer.serverSide.mute.MuteInfo; import jetbrains.buildServer.serverSide.problems.BuildProblemInfo; import jetbrains.buildServer.tests.TestName; import jetbrains.buildServer.users.NotificatorPropertyKey; import jetbrains.buildServer.users.PropertyKey; import jetbrains.buildServer.users.SUser; import jetbrains.buildServer.util.StringUtil; import jetbrains.buildServer.vcs.VcsRoot; import org.apache.http.HttpStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import slacknotifications.SlackNotification; import slacknotifications.teamcity.payload.SlackNotificationPayloadManager; import slacknotifications.teamcity.settings.SlackNotificationMainSettings; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; public class SlackNotificator implements Notificator { private final SlackNotificationMainSettings mainConfig; private final SlackNotificationFactory notificationFactory; private final SlackNotificationPayloadManager payloadManager; private final SBuildServer buildServer; private ArrayList<UserPropertyInfo> userProps; private NotificationUtility notificationUtility; private static final String SLACK_USERNAME_KEY = "tcSlackNotifier.userName"; private static final String TYPE = "tcSlackBuildNotifier"; public static final PropertyKey USERNAME_KEY = new NotificatorPropertyKey(TYPE, SLACK_USERNAME_KEY); public SlackNotificator(NotificatorRegistry notificatorRegistry, SBuildServer sBuildServer, SlackNotificationMainSettings configSettings, SlackNotificationFactory factory, SlackNotificationPayloadManager manager){ Loggers.ACTIVITIES.debug("Registering SlackNotificator..."); userProps = new ArrayList<UserPropertyInfo>(); userProps.add(new UserPropertyInfo(SLACK_USERNAME_KEY, "Slack Username")); notificatorRegistry.register(this, userProps); mainConfig = configSettings; notificationFactory = factory; payloadManager = manager; buildServer = sBuildServer; notificationUtility = new NotificationUtility(); } public void register(){ } @Override public void notifyBuildStarted(SRunningBuild sRunningBuild, Set<SUser> set) { for(SUser sUser : set){ if(!userHasSlackNameConfigured(sUser)){ continue; } SlackNotification slackNotification = createNotification(sUser); slackNotification.setPayload(payloadManager.buildStarted(sRunningBuild, getPreviousNonPersonalBuild(sRunningBuild))); doNotification(slackNotification); } } @Override public void notifyBuildSuccessful(SRunningBuild sRunningBuild, Set<SUser> set) { for(SUser sUser : set){ if(!userHasSlackNameConfigured(sUser)){ continue; } SlackNotification slackNotification = createNotification(sUser); slackNotification.setPayload(payloadManager.buildFinished(sRunningBuild, getPreviousNonPersonalBuild(sRunningBuild))); doNotification(slackNotification); } } @Override public void notifyBuildFailed(SRunningBuild sRunningBuild, Set<SUser> set) { for(SUser sUser : set){ if(!userHasSlackNameConfigured(sUser)){ continue; } SlackNotification slackNotification = createNotification(sUser); slackNotification.setPayload(payloadManager.buildFinished(sRunningBuild, getPreviousNonPersonalBuild(sRunningBuild))); doNotification(slackNotification); } } @Override public void notifyBuildFailedToStart(SRunningBuild sRunningBuild, Set<SUser> set) { } @Override public void notifyLabelingFailed(Build build, VcsRoot vcsRoot, Throwable throwable, Set<SUser> set) { } @Override public void notifyBuildFailing(SRunningBuild sRunningBuild, Set<SUser> set) { for(SUser sUser : set){ if(!userHasSlackNameConfigured(sUser)){ continue; } SlackNotification slackNotification = createNotification(sUser); slackNotification.setPayload(payloadManager.beforeBuildFinish(sRunningBuild, getPreviousNonPersonalBuild(sRunningBuild))); doNotification(slackNotification); } } @Override public void notifyBuildProbablyHanging(SRunningBuild sRunningBuild, Set<SUser> set) { } @Override public void notifyResponsibleChanged(SBuildType sBuildType, Set<SUser> set) { } @Override public void notifyResponsibleAssigned(SBuildType sBuildType, Set<SUser> set) { } @Override public void notifyResponsibleChanged(TestNameResponsibilityEntry testNameResponsibilityEntry, TestNameResponsibilityEntry testNameResponsibilityEntry1, SProject sProject, Set<SUser> set) { } @Override public void notifyResponsibleAssigned(TestNameResponsibilityEntry testNameResponsibilityEntry, TestNameResponsibilityEntry testNameResponsibilityEntry1, SProject sProject, Set<SUser> set) { } @Override public void notifyResponsibleChanged(Collection<TestName> collection, ResponsibilityEntry responsibilityEntry, SProject sProject, Set<SUser> set) { } @Override public void notifyResponsibleAssigned(Collection<TestName> collection, ResponsibilityEntry responsibilityEntry, SProject sProject, Set<SUser> set) { } @Override public void notifyBuildProblemResponsibleAssigned(Collection<BuildProblemInfo> collection, ResponsibilityEntry responsibilityEntry, SProject sProject, Set<SUser> set) { } @Override public void notifyBuildProblemResponsibleChanged(Collection<BuildProblemInfo> collection, ResponsibilityEntry responsibilityEntry, SProject sProject, Set<SUser> set) { } @Override public void notifyTestsMuted(Collection<STest> collection, MuteInfo muteInfo, Set<SUser> set) { } @Override public void notifyTestsUnmuted(Collection<STest> collection, MuteInfo muteInfo, SUser sUser, Set<SUser> set) { } @Override public void notifyBuildProblemsMuted(Collection<BuildProblemInfo> collection, MuteInfo muteInfo, Set<SUser> set) { } @Override public void notifyBuildProblemsUnmuted(Collection<BuildProblemInfo> collection, MuteInfo muteInfo, SUser sUser, Set<SUser> set) { } @NotNull @Override public String getNotificatorType() { return TYPE; } @NotNull @Override public String getDisplayName() { return "Slack Notifier"; } private boolean userHasSlackNameConfigured(SUser sUser){ String userName = sUser.getPropertyValue(USERNAME_KEY); return userName != null && StringUtil.isNotEmpty(userName); } private SlackNotification createNotification(SUser sUser){ SlackNotification notification = notificationFactory.getSlackNotification(); String userName = sUser.getPropertyValue(USERNAME_KEY); if(userName.substring(0,1) == "@"){ userName = userName.substring(1); } notification.setChannel("@" + userName); notification.setTeamName(mainConfig.getTeamName()); notification.setToken(mainConfig.getToken()); notification.setIconUrl(mainConfig.getIconUrl()); notification.setBotName(mainConfig.getBotName()); notification.setEnabled(mainConfig.getEnabled()); notification.setShowBuildAgent(mainConfig.getShowBuildAgent()); notification.setShowElapsedBuildTime(mainConfig.getShowElapsedBuildTime()); notification.setShowCommits(mainConfig.getShowCommits()); notification.setMaxCommitsToDisplay(mainConfig.getMaxCommitsToDisplay()); notification.setMentionChannelEnabled(false); notification.setShowFailureReason(mainConfig.getShowFailureReason()); return notification; } @Nullable private SFinishedBuild getPreviousNonPersonalBuild(SRunningBuild paramSRunningBuild) { List<SFinishedBuild> localList = buildServer.getHistory().getEntriesBefore(paramSRunningBuild, false); for (SFinishedBuild localSFinishedBuild : localList) if (!(localSFinishedBuild.isPersonal())) return localSFinishedBuild; return null; } private void doNotification(SlackNotification notification) { notificationUtility.doPost(notification); } }