private void verboseCommitLog( RepositoryPushEvent event, RefChange refChange, SlackPayload payload, NavBuilder.Repo urlBuilder, String text, List<Changeset> myChanges) { for (Changeset ch : myChanges) { SlackAttachment attachment = new SlackAttachment(); attachment.setFallback(text); attachment.setColor(ColorCode.GRAY.getCode()); SlackAttachmentField field = new SlackAttachmentField(); attachment.setTitle( String.format( "[%s:%s] - %s", event.getRepository().getName(), refChange.getRefId().replace("refs/heads", ""), ch.getId())); attachment.setTitle_link(urlBuilder.changeset(ch.getId()).buildAbsolute()); field.setTitle("comment"); field.setValue(ch.getMessage()); field.setShort(false); attachment.addField(field); payload.addAttachment(attachment); } }
@EventListener public void NotifySlackChannel(RepositoryPushEvent event) { // find out if notification is enabled for this repo Repository repository = event.getRepository(); SlackSettings slackSettings = slackSettingsService.getSlackSettings(repository); String globalHookUrl = slackGlobalSettingsService.getWebHookUrl(KEY_GLOBAL_SETTING_HOOK_URL); SettingsSelector settingsSelector = new SettingsSelector(slackSettingsService, slackGlobalSettingsService, repository); SlackSettings resolvedSlackSettings = settingsSelector.getResolvedSlackSettings(); if (resolvedSlackSettings.isSlackNotificationsEnabledForPush()) { String localHookUrl = slackSettings.getSlackWebHookUrl(); WebHookSelector hookSelector = new WebHookSelector(globalHookUrl, localHookUrl); ChannelSelector channelSelector = new ChannelSelector( slackGlobalSettingsService.getChannelName(KEY_GLOBAL_SLACK_CHANNEL_NAME), slackSettings.getSlackChannelName()); if (!hookSelector.isHookValid()) { log.error( "There is no valid configured Web hook url! Reason: " + hookSelector.getProblem()); return; } if (repository.isFork() && !resolvedSlackSettings.isSlackNotificationsEnabledForPersonal()) { // simply return silently when we don't want forks to get notifications unless they're // explicitly enabled return; } String repoName = repository.getSlug(); String projectName = repository.getProject().getKey(); String repoPath = projectName + "/" + event.getRepository().getName(); for (RefChange refChange : event.getRefChanges()) { String text; String ref = refChange.getRefId(); NavBuilder.Repo repoUrlBuilder = navBuilder.project(projectName).repo(repoName); String url = repoUrlBuilder.commits().until(refChange.getRefId()).buildAbsolute(); List<Changeset> myChanges = new LinkedList<Changeset>(); boolean isNewRef = refChange.getFromHash().equalsIgnoreCase("0000000000000000000000000000000000000000"); boolean isDeleted = refChange.getToHash().equalsIgnoreCase("0000000000000000000000000000000000000000") && refChange.getType() == RefChangeType.DELETE; if (isDeleted) { // issue#4: if type is "DELETE" and toHash is all zero then this is a branch delete if (ref.indexOf("refs/tags") >= 0) { text = String.format( "Tag `%s` deleted from repository <%s|`%s`>.", ref.replace("refs/tags/", ""), repoUrlBuilder.buildAbsolute(), repoPath); } else { text = String.format( "Branch `%s` deleted from repository <%s|`%s`>.", ref.replace("refs/heads/", ""), repoUrlBuilder.buildAbsolute(), repoPath); } } else if (isNewRef) { // issue#3 if fromHash is all zero (meaning the beginning of everything, probably), then // this push is probably // a new branch or tag, and we want only to display the latest commit, not the entire // history Changeset latestChangeSet = commitService.getChangeset(repository, refChange.getToHash()); myChanges.add(latestChangeSet); if (ref.indexOf("refs/tags") >= 0) { text = String.format( "Tag <%s|`%s`> pushed on <%s|`%s`>. See <%s|commit list>.", url, ref.replace("refs/tags/", ""), repoUrlBuilder.buildAbsolute(), repoPath, url); } else { text = String.format( "Branch <%s|`%s`> pushed on <%s|`%s`>. See <%s|commit list>.", url, ref.replace("refs/heads/", ""), repoUrlBuilder.buildAbsolute(), repoPath, url); } } else { ChangesetsBetweenRequest request = new ChangesetsBetweenRequest.Builder(repository) .exclude(refChange.getFromHash()) .include(refChange.getToHash()) .build(); Page<Changeset> changeSets = commitService.getChangesetsBetween( request, PageUtils.newRequest(0, PageRequest.MAX_PAGE_LIMIT)); myChanges.addAll(Lists.newArrayList(changeSets.getValues())); int commitCount = myChanges.size(); String commitStr = commitCount == 1 ? "commit" : "commits"; String branch = ref.replace("refs/heads/", ""); if (!branch.equals("master")) { continue; } text = String.format( "Push on <%s|`%s`> branch <%s|`%s`> by `%s <%s>` (%d %s). See <%s|commit list>.", repoUrlBuilder.buildAbsolute(), repoPath, url, branch, event.getUser() != null ? event.getUser().getDisplayName() : "unknown user", event.getUser() != null ? event.getUser().getEmailAddress() : "unknown email", commitCount, commitStr, url); } // Figure out what type of change this is: SlackPayload payload = new SlackPayload(); payload.setText(text); payload.setMrkdwn(true); switch (resolvedSlackSettings.getNotificationLevel()) { case COMPACT: compactCommitLog(event, refChange, payload, repoUrlBuilder, myChanges); break; case VERBOSE: verboseCommitLog(event, refChange, payload, repoUrlBuilder, text, myChanges); break; case MINIMAL: default: break; } // slackSettings.getSlackChannelName might be: // - empty // - comma separated list of channel names, eg: #mych1, #mych2, #mych3 if (channelSelector.getSelectedChannel().isEmpty()) { slackNotifier.SendSlackNotification(hookSelector.getSelectedHook(), gson.toJson(payload)); } else { // send message to multiple channels List<String> channels = Arrays.asList(channelSelector.getSelectedChannel().split("\\s*,\\s*")); for (String channel : channels) { payload.setChannel(channel.trim()); slackNotifier.SendSlackNotification( hookSelector.getSelectedHook(), gson.toJson(payload)); } } } } }