Sitecore Send SDK (unofficial)
$ dotnet add package SitecoreSend.SDKProvides .NET wrapper around Sitecore Send API
var apiConfiguration = new ApiConfiguration
{
ApiKey = "[YOUR API KEY]",
Clients = new Dictionary<string, string>()
{
{"[YOUR CLIENT NAME / ALIAS]", "[YOUR CLIENT API KEY]"},
},
};
ISendClient send = new SendClient(apiConfiguration);
var response = await send.Lists.GetAll();
// ensure response is not null and Success is true
if (response is {Success: true})
{
IList<MailingList>? allLists = response.Data?.MailingLists;
// handle allLists
}
// internal API
var internalApi = new InternalApi(InternalApiConfiguration.Create(apiConfiguration));
var allWebsites = await internalApi.Websites.GetAll();
Configuration with DI:
var apiConfiguration = new ApiConfiguration
{
ApiKey = "[YOUR API KEY]",
Clients = ...
};
serviceCollection.AddHttpClient("SitecoreSendClient",
(client) => { client.BaseAddress = new Uri(apiConfiguration.BaseUri); });
serviceCollection.AddSingleton<ISendClient>(provider =>
{
var factory = provider.GetRequiredService<IHttpClientFactory>();
return new SendClient(apiConfiguration,
() => factory.CreateClient("SitecoreSendClient"));
});
var request = EmailRequestBuilder.Start(campaign)
.AddPersonalization(new Personalization(testEmail, "Igor Zharikov")
{
Substitutions = new Dictionary<string, string>()
{
{"orderNumber", "123456"},
{"paymentMethod", "PayTest"},
{"total", "123.00 USD"},
{"complex", new
{
items = new List<string>() {"item1", "item2"},
}},
},
})
.AddAttachment(new EmailAttachment()
{
Content = AttachmentTool.StreamToBase64(File.OpenRead("icon.png")),
Type = "image/png",
FileName = "icon.png",
})
.Build();
var result = await _send.Transactional.Send(request);
// 'Client1' should be added inside ApiConfiguration.Clients used in constructor
using (new ClientSwitcher("Client1"))
{
var clientLists = await _send.Lists.GetAll();
Assert.True(clientLists?.Success);
}
Sitecore Send comes with API rate limits for subscribe/unsubscribe endpoints.
To check if rate limit occurred the following can be used:
var response = _send.Subscribers.Add(...);
// option 1:
if (response?.Code == KnownErrors.RATE_LIMITING)
{
...
}
// option 2:
if (response?.RateLimitDetails != null)
{
...
}
Current library supports handling of them with 'Wrapping' limited methods with configured policies.
The following Polly policies configuration can be used: link.
Currently, applies only for SubscribersService:
new SendClient(
apiConfiguration,
httpClientFactory,
new RateLimiterConfiguration()
{
Subscribers = new SubscribersWrapper()
{
AddSubscriber = SendRateLimits.AddSubscriber.ExecuteAsync,
AddMultipleSubscribers = SendRateLimits.AddMultipleSubscribers.ExecuteAsync,
UnsubscribeFromAllLists = SendRateLimits.UnsubscribeFromAllLists.ExecuteAsync,
UnsubscribeFromList = SendRateLimits.UnsubscribeFromList.ExecuteAsync,
UnsubscribeFromListAndCampaign = SendRateLimits.UnsubscribeFromListAndCampaign.ExecuteAsync,
},
}
);
Whenever possible use Get, Update methods of ISendClient.Subscribers.
E.g. if you need to ensure user exists in the list, use extension methods:
// check if subscriber exists => then update, if not => create
_send.Subscribers.CreateOrUpdate(listId, ...);
// check if user is subscribed to the list, if subscribeIfNotExists == true => subscribe to list
_send.Subscribers.EnsureSubscribed(listId, email, subscribeIfNotExists);
Integration tests are located in SitecoreSend.SDK.Tests project.
Create file appsettings.local.jsonc based on appsettings.jsonc in SitecoreSend.SDK.Tests project and populate it with your own values.
You can contact me via email or in Sitecore Slack: zharikovigor97@gmail.com. Or please open an issue.
SmtpClient together with SitecoreSend.SDK.Extensions.SmtpExtensions