Run or Schedule Custom Email
This scheduled job will automatically send email notifications periodically based on a condition and email template. This is particularly useful if you want a daily summary of what has happened in Bitbucket.
You need to configure the interval and then provide a subject and an email template, as well as the email format (plain text or HTML) and a list of recipients.
List all public repositories
This example sends an email notification listing all the public repositories present in your Bitbucket Server instance.
import com.atlassian.bitbucket.repository.Repository
import com.atlassian.bitbucket.repository.RepositorySearchRequest
import com.atlassian.bitbucket.repository.RepositoryService
import com.atlassian.bitbucket.util.Page
import com.atlassian.bitbucket.util.PageProvider
import com.atlassian.bitbucket.util.PageRequest
import com.atlassian.bitbucket.util.PageRequestImpl
import com.atlassian.bitbucket.util.PagedIterable
import com.atlassian.sal.api.component.ComponentLocator
import javax.annotation.Nonnull
import static com.atlassian.bitbucket.repository.RepositoryVisibility.PUBLIC
def repositoryService = ComponentLocator.getComponent(RepositoryService)
def publicRepositories = new PagedIterable<Repository>(new PageProvider<Repository>() {
@Override
Page<Repository> get(@Nonnull PageRequest pageRequest) {
repositoryService.search(new RepositorySearchRequest.Builder().visibility(PUBLIC).build(), pageRequest) // <1>
}
}, new PageRequestImpl(0, 100))
.collect { Repository repository -> "$repository.project.key/$repository.slug" } // <2>
.join("\n")
config.content = publicRepositories // <3>
!publicRepositories.isEmpty() // <4>- We find all public repositories
- For each public repository we build a string containing the project key and repository slug
- We use the config variable in the binding to store the content for use in the template below.
- The condition will evaluate to true if we have any private repositories and then the email will be sent
The subject template:
List of public repositories:The body template:
These repositories are public, and you should review them:
$publicReposContentThe result should look similar to the following:
These repositories are public, and you should review them:
PROJECT_1/aPublicRepo
PROJECT_5/anotherPublicRepoAdditional Configuration in Emails
You may notice the syntax for getting content in the template is a bit clunky, as the template engine does not allow you to use the import keyword. Rather than doing this, you can pass in a config map to the bindings for both the subject and body templates. This is done in the Mail configuration section.
A useful example of a Mail configuration section that defines config variables for all pull requests that have been merged in the last 24 hours is:
import com.atlassian.bitbucket.nav.NavBuilder
import com.atlassian.bitbucket.pull.PullRequest
import com.atlassian.bitbucket.pull.PullRequestSearchRequest
import com.atlassian.bitbucket.pull.PullRequestService
import com.atlassian.bitbucket.pull.PullRequestState
import com.atlassian.bitbucket.repository.RepositoryService
import com.atlassian.bitbucket.util.Page
import com.atlassian.bitbucket.util.PageProvider
import com.atlassian.bitbucket.util.PageRequest
import com.atlassian.bitbucket.util.PageRequestImpl
import com.atlassian.bitbucket.util.PagedIterable
import com.atlassian.sal.api.component.ComponentLocator
import groovy.xml.MarkupBuilder
import javax.annotation.Nonnull
def pullRequestService = ComponentLocator.getComponent(PullRequestService)
def repositoryService = ComponentLocator.getComponent(RepositoryService)
def projectKey = "PROJECT_1"
def repoSlug = "rep_1"
def repo = repositoryService.getBySlug(projectKey, repoSlug)
def yesterday = new Date().minus(1)
def pullRequestSearchRequest = new PullRequestSearchRequest.Builder()
.state(PullRequestState.MERGED)
.closedSince(yesterday)
.toRepositoryId(repo.id)
.build()
def mergedPullRequests = new PagedIterable<PullRequest>(new PageProvider<PullRequest>() {
@Override
Page<PullRequest> get(@Nonnull PageRequest pageRequest) {
pullRequestService.search(pullRequestSearchRequest, pageRequest)
}
}, new PageRequestImpl(0, 100)) as Iterable<PullRequest>
def navBuilder = ComponentLocator.getComponent(NavBuilder)
def writer = new StringWriter()
def builder = new MarkupBuilder(writer)
builder.ul {
mergedPullRequests.each { PullRequest pullRequest ->
def url = navBuilder.repo(repo).pullRequest(pullRequest.id).buildAbsolute()
builder.li {
a(href: url, pullRequest.title)
}
}
}
config.content = writer.toString()
config.numberMerged = mergedPullRequests.size()projectKey and repoSlug variable above to match your own. The email format selected should be HTML.The subject template:
$numberMerged PRs have been merged todayThe body template:
The following pull requests were merged today:
$contentAs a result of that configuration, an email will be sent to the selected email addresses with a content similar to the following one:
Clicking on the links will take you to that pull request in Bitbucket.