Skip to main content
Version: 1.0.x

Technical reference

The SendGrid plugin wraps SendGrid's Marketing Campaigns and Mail Send APIs behind a Brightspot-friendly extension point, SendGridTemplateProvider. Any asset that implements it can use the plugin's existing CMS tool pages, widget, caches, and permission model to create, update, schedule, send, test, and disconnect a SendGrid Single Send campaign, with no additional UI work. The plugin is split into an api module (the SendGridClient contract and its request/response data classes) and an api-impl module (a Retrofit-based implementation of that contract), so the SendGrid HTTP wiring can be swapped or mocked independently of the CMS integration.

Dependencies

  • com.psddev:cms-db, dari-db, dari-html, dari-util, dari-web—Brightspot CMS and Dari core libraries.
  • com.brightspot.api-client:api-client and com.brightspot.api-client:retrofit—the shared internal framework SendGridApiConfiguration and SendGridClient build on for typed, cacheable API clients.
  • com.squareup.retrofit2:retrofit and com.squareup.okhttp3:okhttp—the HTTP client stack used by the api-impl module's implementation.
  • com.fasterxml.jackson.core:jackson-annotations/jackson-databind—request/response serialization.
  • com.github.ben-manes.caffeine:caffeine—backs the plugin's in-memory caches.

Installation

<!-- Requires Brightspot 4.8 or later. -->
<dependency>
<groupId>com.brightspot.sendgrid</groupId>
<artifactId>sendgrid</artifactId>
<version>1.0.1</version>
</dependency>
<!-- Requires Brightspot 4.8 or later. -->
<dependency>
<groupId>com.brightspot.sendgrid</groupId>
<artifactId>api-impl</artifactId>
<version>1.0.1</version>
</dependency>

The sendgrid artifact is the core CMS integration and pulls in the api module transitively. Add api-impl as well to get a working SendGridClient—it's the only implementation the plugin ships. Provide your own implementation of SendGridClient/SendGridApiConfiguration instead if you need different HTTP client behavior.

API reference

Extending an asset: SendGridTemplateProvider

An asset opts into SendGrid campaigns by implementing SendGridTemplateProvider.

MethodReturnsDescription
getSendGridClient()SendGridClientThe client to use for this content's campaigns. Defaults to null—override it to supply a client, typically built from the content's Site.
getSendGridSubject()StringThe email subject line this content supplies.
getSendGridPreheader()StringThe preheader text this content supplies.
getSendGridHtmlContent()StringThe HTML content for the campaign.
getSendGridPlainContent()StringThe plain text content for the campaign.
getTemplateData()SendGridTemplateDataThe stored campaign association for this content. Looks one up by provider and returns a new, unsaved instance if none exists yet.

SendGridTemplateData is the record that links a SendGridTemplateProvider to a SendGrid Single Send: singleSendId, singleSendName, status (draft, scheduled, or triggered), lastSyncDate, and lastActionDate.

1
public SendGridClient getSendGridClient() {
2
Site site = as(Site.ObjectModification.class).getOwner();
3
SendGridSiteSettings settings = SiteSettings.get(site, s -> s.as(SendGridSiteSettings.class));
4
String apiKey = settings != null && settings.getSettings() != null
5
? settings.getSettings().getApiKey()
6
: null;
7
8
if (apiKey == null) {
9
return null;
10
}
11
12
return new StandardSendGridClientConfiguration(site.getId(), apiKey, settings.getLastChanged().toInstant()).build();
13
}

SendGridClient

SendGridClient (package brightspot.sendgrid.api) is the contract every SendGrid API call goes through. All methods throw SendGridApiException on failure.

MethodParametersReturnsPurpose
getSenders(GetSendersRequest)requestGetSendersResponseList verified sender identities.
getLists(GetListsRequest)request (pageSize, pageToken)GetListsResponseList contact lists, cursor-paginated.
getSegments()GetSegmentsResponseList all contact segments.
createSingleSend(CreateSingleSendRequest)requestCreateSingleSendResponseCreate a new Single Send campaign.
getSingleSend(GetSingleSendRequest)request (singleSendId)GetSingleSendResponseGet a Single Send campaign by ID.
updateSingleSend(UpdateSingleSendRequest)requestUpdateSingleSendResponseUpdate an existing Single Send campaign.
scheduleSingleSend(ScheduleSingleSendRequest)request (singleSendId, sendAt)ScheduleSingleSendResponseSchedule a Single Send, or send it immediately with sendAt = "now".
cancelScheduledSingleSend(CancelScheduledSingleSendRequest)request (singleSendId)voidCancel a scheduled send and return the campaign to draft.
sendMail(MailSendRequest)requestvoidSend a transactional email via POST /v3/mail/send. Used for test emails.
getSuppressionGroups()GetSuppressionGroupsResponseList suppression (unsubscribe) groups.
getSingleSendStats(GetSingleSendStatsRequest)request (singleSendId)GetSingleSendStatsResponseGet delivery and engagement stats for a Single Send.

isConfigured() (inherited from RetrofitApiClient) reports whether the client has a usable API key.

Data classes

Request and response types live in brightspot.sendgrid.api.data, grouped by the SendGridClient method they belong to:

MethodRequestResponseNotable fields
getSendersGetSendersRequestGetSendersResponse{results}SenderData{id, nickname, from, replyTo, verified}
getListsGetListsRequest{pageSize, pageToken}GetListsResponse{result, metadata}ListData{id, name, contactCount}
getSegmentsGetSegmentsResponse{results}SegmentData{id, name, contactsCount}
createSingleSendCreateSingleSendRequest{name, categories, sendTo, emailConfig}CreateSingleSendResponseExtends SingleSendData
getSingleSendGetSingleSendRequest{singleSendId}GetSingleSendResponseExtends SingleSendData
updateSingleSendUpdateSingleSendRequest{singleSendId, name, categories, sendTo, emailConfig}UpdateSingleSendResponseExtends SingleSendData
scheduleSingleSendScheduleSingleSendRequest{singleSendId, sendAt}ScheduleSingleSendResponsesendAt is an ISO 8601 instant, or "now"
cancelScheduledSingleSendCancelScheduledSingleSendRequest{singleSendId}void
sendMailMailSendRequest{personalizations, from, subject, content}voidMailSendPersonalization{to}, MailSendContent{type, value}
getSuppressionGroupsGetSuppressionGroupsResponse{groups}SuppressionGroupData{id, name, description, isDefault}
getSingleSendStatsGetSingleSendStatsRequest{singleSendId}GetSingleSendStatsResponse{results}SingleSendStatsResultData{id, stats}, where stats is a SingleSendStatsData{requests, delivered, opens, uniqueOpens, clicks, uniqueClicks, bounces}

Shared embedded types: SingleSendData{id, name, status, sendAt, categories, emailConfig, sendTo}, SingleSendEmailConfig{subject, htmlContent, plainContent, senderId, suppressionGroupId}, SingleSendSendTo{listIds, segmentIds, all}.

On failure, StandardSendGridClient parses SendGrid's error body into ErrorResponse{errors: List<ErrorData>}, where each ErrorData has message, field, and help, and wraps it in a SendGridApiException with a message in the form SendGrid API Error [<status>]: <errors>.

Caches

The plugin caches read-heavy SendGrid data per SendGridClient to avoid exceeding SendGrid's rate limits.

CacheCachesTTL
SendGridListsCacheContact lists10 minutes
SendGridSegmentsCacheContact segments10 minutes
SendGridSendersCacheSender identities10 minutes
SendGridSuppressionGroupsCacheSuppression groups10 minutes
SendGridSingleSendCacheA single campaign's live data and stats60 seconds

SendGridListsCache, SendGridSegmentsCache, SendGridSendersCache, and SendGridSuppressionGroupsCache each expose an invalidate()/invalidate(client) method. SendGridSingleSendCache instead exposes invalidate(client, singleSendId), which tool pages that change a campaign's state (schedule, send, unschedule, update) call afterward so the widget reflects the change immediately instead of waiting out the 60-second TTL.

Tool pages and permissions

Every editorial action is a ToolPage subclass of AbstractSendGridToolPage, gated by its own @Permission:

Permission IDTool page
sendgrid/create-single-sendSendGridCreateSingleSendToolPage
sendgrid/update-campaignSendGridUpdateCampaignToolPage
sendgrid/schedule-campaignSendGridScheduleCampaignToolPage
sendgrid/send-campaignSendGridSendCampaignToolPage
sendgrid/send-test-emailSendGridSendTestEmailToolPage
sendgrid/unschedule-campaignSendGridUnscheduleCampaignToolPage
sendgrid/disconnect-campaignSendGridDisconnectToolPage
sendgrid/view-activity-logSendGridViewActivityLogToolPage
sendgrid/view-campaign-infoSendGridViewCampaignDetailsToolPage

SendGridPermissions is the AdditionalPermission a role is configured with; its permissions field holds one of AllSendGridPermission, OnlySendGridPermission, or AllExceptSendGridPermission (all SendGridPermissionOption subtypes), each implementing hasPermission(String permissionId) against the sendgrid/ prefix.

Configuration

SendGridSiteSettings is a Modification<SiteSettings>, so it applies at both the Global level and the per-Site level, with null on a Site meaning "inherit from Global."

FieldTypeDefaultEffect
enabledBooleannullWhether the SendGrid widget and tool pages are active for the site. null on a Site inherits the Global value.
settingsSendGridApiSettingsnullEmbedded API settings; settings.apiKey is the account's SendGrid API key.
defaultSubjectStringnullFallback subject line used when a SendGridTemplateProvider doesn't supply its own.
defaultPreheaderStringnullFallback preheader text used when a SendGridTemplateProvider doesn't supply its own.
categoriesList<String>emptyThe pool of categories offered when creating a campaign.
lastChangedDateRead-only; bumped in beforeCommit() whenever any tracked settings field changes. Used as the timestamp component of StandardSendGridClientConfiguration, so a settings change produces a distinct, cache-busting SendGridClient.

onValidate() requires a non-blank API key—either local or, for a Site, inherited from Global—whenever enabled is true, and rejects duplicate categories.

StandardSendGridClientConfiguration(UUID ownerId, String apiKey, Instant timestamp) targets https://api.sendgrid.com and is keyed by ownerId and timestamp for equality—typically the Site ID and SendGridSiteSettings.getLastChanged(), respectively—so a SendGridClient built for a given site and settings version is stable and cacheable until those settings next change.