Search…
Sending & Receiving Email
Provides your users the ability to perform email communications with a Sudo

Sending Email Messages

The Email SDK can handle sending email messages. Sending messages requires a provisioned email address as discussed in Manage Email Addresses.
We support using a raw RFC 822 payload to allow flexible email composition within your application.
The sendEmailMessage method is used to send an email message. The first input property, rfc822Data, takes in the email message contents formatted under RFC 822 as an array of bytes. The second input property, senderEmailAddressId, must match the id of the email address from the from field in the RFC 822 data. A call to this method returns the id of the sent email message.
A single email message can be sent to a maxium of 10 recipients at once by default. Adding recipients to the email message which exceed this limit will throw a LimitExceededError.

Entitlements

TypeScript
Swift
Kotlin
1
// Collect the input RFC 822 data and sender email address id however makes sense for your implementation.
2
const rfc822Data: ArrayBuffer = // ...
3
const senderEmailAddressId = senderEmailAddress.id
4
try {
5
const messageId = await emailClient.sendEmailMessage({
6
rfc822Data,
7
senderEmailAddressId,
8
})
9
// `messageId` is the identifier associated with the sent email message. You can use this to access the data of the email message.
10
} catch {
11
// Handle/notify user of error
12
}
Copied!
1
/// Collect the input RFC822 data and email address id however makes sense for your implementation.
2
let rfc822Data = input.rfc822Data
3
let emailAddressId = input.emailAddressId
4
emailClient.sendEmailMessage(withRFC822Data: rfc822Data, emailAddressId: emailAddressId) { result in
5
switch result {
6
case let .failure(cause):
7
/// Handle/notify user of error
8
case let .success(id):
9
/// `id` is the identifier associated with the sent email message. You can use this to access the data of the email message.
10
}
Copied!
1
val rfc822EncodedMessage = // ...
2
val senderEmailAddress: EmailAddress = // ...
3
launch {
4
try {
5
val messageId = withContext(Dispatchers.IO) {
6
emailClient.sendEmailMessage(
7
rfc822EncodedMessage,
8
senderEmailAddress.id
9
)
10
}
11
} catch (e: EmailMessageException) {
12
// Handle/notify user of exception
13
}
14
}
Copied!
In order to be able to send an email, the user must be entitled. To send an email the following entitlement checks are performed:
    1.
    The user must be entitled to send emails by thesudoplatform.email.emailMessageSendUserEntitled entitlement,
    2.
    The email address the user is sending from must have sufficient storage capacity available as determined by the sudoplatform.email.emailStorageMaxPerEmailAddress entitlement.
If these entitlements checks do not succeed, the sendEmailMessage fails with an insufficient entitlements error.
See Email Entitlements for an overview of how the Email service integrates with the Sudo Platform Entitlements system.

Entitlements

In order to be able to send an email, the user must be entitled. To send an email the following entitlement checks are performed:
    1.
    The user must be entitled to send emails by thesudoplatform.email.emailMessageSendUserEntitled entitlement.
    2.
    The email address the user is sending from must have sufficient storage capacity available as determined by the sudoplatform.email.emailStorageMaxPerEmailAddress entitlement.
If these entitlements' checks do not succeed, the sendEmailMessage fails with an insufficient entitlements error.
See Email Entitlements for an overview of how the Email service integrates with the Sudo Platform Entitlements system.

Updating Metadata of Email Messages

Updating email message metadata is supported as a batch operation. Note that this API does not allow updating the email message content and headers but rather certain attributes which make up part of the metadata.
The update email messages API currently supports updating the following email message attributes:
folderId
Update this attribute to move email messages between different folders.
seen
Update this attribute to set the seen status of the email message
One or more email message identifiers can be passed into the updateEmailMessages method to perform a batch update of the email messages associated with those identifiers.
Email messages can only be updated in batches of 100. Supplying identifiers to the input which exceed this limit will throw a LimitExceededError.
A BatchOperationResult type is returned from this method call which contains the status of the batch update operation. Three possible statuses can be returned:
Status
Definition
Success
All of the email messages succeeded to update.
Partial
Only a subset of email messages succeeded to update. The return object will include a list of identifiers of messages which failed the update and a list which succeeded the update.
Failure
All of the email messages failed to update.
TypeScript
Swift
Kotlin
1
// Collect the input message ids however makes sense for your implementation.
2
const ids = ['message-id-1', 'message-id-2']
3
try {
4
const updateResult = await emailClient.updateEmailMessages({
5
ids,
6
values: { seen: true },
7
})
8
// `updateResult` contains the status of the batch update operation.
9
} catch {
10
// Handle/notify user of error
11
}
Copied!
1
Coming Soon!
Copied!
1
Coming Soon!
Copied!

Deleting Email Messages

Deleting email messages is supported as a batch operation. Deleting email messages is not the same as moving them to the trash folder. See the Updating Email Messages section for moving email messages to the trash folder and other folders.
By deleting the email message, the message data and metadata will no longer be available and all traces will be deleted permanently.
One or more email message identifiers can be passed into the deleteEmailMessages method to perform a batch delete of the email messages associated with those identifiers.
Email messages can only be deleted in batches of 100. Supplying identifiers to the input which exceed this limit will throw a LimitExceededError.
A BatchOperationResult type is returned from this method call which contains the status of the batch delete operation. Three possible statuses can be returned:
Status
Definition
Success
All of the email messages succeeded to delete.
Partial
Only a subset of email messages succeeded to delete. The return object will include a list of identifiers of messages which failed the delete and a list which succeeded the delete.
Failure
All of the email messages failed to delete.
TypeScript
Swift
Kotlin
1
// Collect the input message ids however makes sense for your implementation.
2
const ids = ['message-id-1', 'message-id-2']
3
try {
4
const deleteResult = await emailClient.deleteEmailMessages(
5
ids
6
)
7
// `deleteResult` contains the status of the batch delete operation.
8
} catch {
9
// Handle/notify user of error
10
}
Copied!
1
/// Collect the email message id however makes sense for your implementation.
2
let emailMessageId = emailMessage.id
3
emailClient.deleteEmailMessageWithId(emailMessageId) { result in
4
switch result {
5
case let .failure(cause):
6
/// Handle/notify user of error
7
case let .success(id):
8
/// Successfully deleted email message - `id` is the id that was just deleted. Will always match the input.
9
}
Copied!
1
launch {
2
try {
3
withContext(Dispatchers.IO) {
4
emailClient.deleteEmailMessage(id)
5
}
6
} catch (e: EmailMessageException) {
7
// Handle/notify user of exception
8
}
9
}
Copied!

Retrieving Email Messages

Sent and received email messages can be accessed in two ways: via its identifier (Single Email Message by Id), or via a multi access method (Multiple Email Messages).
These retrieval methods return the email message metadata but not the content of the message. To learn how to access the RFC 822 message content of the email message, see Accessing RFC 822 Message Data.
If an email message has been deleted, it will no longer be available for access.
A fetch of single or multiple email messages can be performed remotely or locally by specifying the appropriate CachePolicy as part of the input object.

Single Email Message by Id

An single email message can be retrieved via its id using the getEmailMessage method. The id is typically returned from successfully sending an email message. This method will return the record if it exists.
TypeScript
Swift
Kotlin
1
try {
2
const emailMessage = await emailClient.getEmailMessage({
3
id,
4
cachePolicy: CachePolicy.RemoteOnly,
5
})
6
// `emailMessage` contains the email message object, else `undefined` if not found.
7
} catch {
8
// Handle/notify user of errors
9
}
Copied!
1
/// Collect the input id of the email message object.
2
let messageId = input.messageId
3
emailClient.getEmailMessageWithId(messageId, cachePolicy: .remoteOnly) { result in
4
switch result {
5
case let .failure(cause):
6
/// Handle/notify user of error
7
case let .success(emailMessage):
8
/// `emailMessage` contains the email message object, else `nil` if not found.
9
}
Copied!
1
launch {
2
try {
3
val emailMessage = withContext(Dispatchers.IO) {
4
emailClient.getEmailMessage(
5
id,
6
cachePolicy = CachePolicy.REMOTE_ONLY
7
)
8
}
9
// [emailMessage] contains the email message object, else [null] if not found.
10
} catch (e: EmailMessageException) {
11
// Handle/notify user of exception
12
}
13
}
Copied!

Multiple Email Messages

The ability to retrieve multiple email messages available to the user is supported. These results can be paginated and filtered. Provide an EmailMessageFilter input property to the list API call to filter the results.
A call to a list API will return a ListEmailMessagesResult with a status and depending on the status, a list of matching items and a nextToken to support pagination. If no results matching the input are found, the result will contain empty items. There can be three possible statuses returned:
Status
Definition
Success
A list of all requested email messages are returned.
Partial
A list of all email messages that were successfully fetched and unencrypted are returned as well as a list of all email messages that failed to unencrypt successfully, including an error indicating the reason for the failure.
Failure
All email messages failed to be fetched or unencrypted. Contains an error indicating the reason for the failure.
An email message may fail to be unencrypted if the version of the client is not up-to-date or if the required cryptographic key is missing from the client device.

Entitlements

While previously received emails are always able to be retrieved, in order to be able to receive new emails, the user must be entitled. To receive an email the following entitlement checks are performed:
    1.
    The user must be entitled to receive emails by thesudoplatform.email.emailMessageReceiveUserEntitled entitlement.
    2.
    The email address the email is addressed to must have sufficient storage capacity available as determined by the sudoplatform.email.emailStorageMaxPerEmailAddress entitlement.
If these entitlements checks do not succeed, the incoming email is rejected with a reason indicating that the storage quota has been exceeded allowing the sending email service to retry.
See Email Entitlements for an overview of how the Email service integrates with the Sudo Platform Entitlements system.

All Email Messages for an Email Address

To retrieve multiple email messages that are assigned to a certain email address, call the listEmailAddressesForEmailAddressId method by passing in the id of the email address to query.
TypeScript
Swift
Kotlin
1
// Collect the input email address id however makes sense for your implementation.
2
const emailAddressId = emailAddress.id
3
try {
4
const result = await emailClient.listEmailMessagesForEmailAddressId({
5
emailAddressId,
6
cachePolicy: CachePolicy.RemoteOnly,
7
filter: { direction: { eq: Direction.Inbound } },
8
limit: 20,
9
nextToken,
10
})
11
if (result.status === ListOperationResultStatus.Success) {
12
// `result` contains the list of items matching the input.
13
// Page through the results if result.nextToken != undefined.
14
}
15
} catch {
16
// Handle/notify user of errors
17
}
Copied!
1
emailClient.listEmailMessagesWithSudoId(
2
nil,
3
emailAddressId: nil,
4
filter: nil,
5
limit: nil,
6
nextToken: nil
7
) { result in
8
switch result {
9
case let .failure(cause):
10
/// Handle/notify user of error
11
case let .success(output):
12
/// `output` contains a `ListOutput` item of results matching the call.
13
}
Copied!
1
launch {
2
try {
3
val listOutput = withContext(Dispatchers.IO) {
4
emailClient.listEmailMessages(
5
sudoId = null,
6
emailAddressId = null,
7
limit = 40,
8
cachePolicy = CachePolicy.REMOTE_ONLY,
9
filter = filterEmailMessagesBy {
10
allOf(
11
direction equalTo inbound,
12
not(seen)
13
)
14
}
15
)
16
}
17
// Page through the results if listOutput.nextToken != null
18
} catch (e: EmailMessageException) {
19
// Handle/notify user of exception
20
}
21
}
Copied!

All Email Messages for an Email Folder

To retrieve multiple email messages that are assigned to a certain email folder (i.e. Trash), call the listEmailAddressesForEmailFolderId method by passing in the id of the email folder to query.
TypeScript
Swift
Kotlin
1
// Collect the input email folder id however makes sense for your implementation.
2
const emailFolderId = emailFolder.id
3
try {
4
const result = await emailClient.listEmailMessagesForEmailFolderId({
5
emailFolderId,
6
cachePolicy: CachePolicy.RemoteOnly,
7
filter: { direction: { eq: Direction.Inbound } },
8
limit: 20,
9
nextToken,
10
})
11
if (result.status === ListOperationResultStatus.Success) {
12
// `result` contains the list of items matching the input.
13
// Page through the results if result.nextToken != undefined.
14
}
15
} catch {
16
// Handle/notify user of errors
17
}
Copied!
1
Coming Soon!
Copied!
1
Coming Soon!
Copied!
By default, list email messages API have a limit of 1MB of data when no limit is supplied. If using a filter, the limit is applied before the filter.

Filtering Email Messages

Email message queries can be filtered in multiple ways. Email messages can be filtered by the following properties:
    folderId
    direction
    seen
    state
    created, updated, sent and received timestamps
For example, if the user wished to lookup email messages for an email address and filter out all messages that have a seen status equaling false, they could provide a filter for an email message that equals the boolean value.
Email message filters also support more complex logic, such as not, and and or. These are equivalent to their logical names and allow for stringing together complex logic. An example may consist of using an and filter with two filters nested: direction equal Inbound, seen equal false. This filter will ensure that the returned result contain all the inbound messages that have not yet been seen.
TypeScript
Swift
Kotlin
1
// Collect the input email address id however makes sense for your implementation.
2
const emailAddressId = emailAddress.id
3
try {
4
const result = await emailClient.listEmailMessagesForEmailAddressId({
5
emailAddressId,
6
filter: {
7
and: [
8
{ direction: { eq: Direction.Inbound } },
9
{ seen: { eq: false } },
10
],
11
},
12
cachePolicy: CachePolicy.RemoteOnly,
13
limit: 20,
14
nextToken,
15
})
16
if (result.status === ListOperationResultStatus.Success) {
17
// `result` contains the list of items matching the input.
18
// Page through the results if result.nextToken != undefined.
19
}
20
} catch {
21
// Handle/notify user of errors
22
}
Copied!
1
Coming Soon!
Copied!
1
Coming Soon!
Copied!

Accessing RFC 822 Message Data

The Email SDK allows developers to interact with raw email data. The SDK's interfaces and documentation refer to this type of data as RFC 822 data. While there are a number of internet standards, such as RFC 2822, RFC 5322 and RFC 6854, that supersede the RFC 822 specification, the intent is that raw email data conforms to any of these specifications and is appropriate and interoperable with Sudo Platform emails.
To access the message body and headers of the email message, the RFC 822 data will need to be retrieved using the getEmailMessageRfc822Data method. The id of the email message is required to be passed into this method to access the data. The other methods previously supplied on this page only access the metadata of the email message.
TypeScript
Swift
Kotlin
1
try {
2
const rfc822Data = await emailClient.getEmailMessageRfc822Data({
3
id,
4
cachePolicy = CachePolicy.REMOTE_ONLY
5
})
6
// If the `id` matches an email message, `rfc822Data` will be returned, else `undefined` is returned.
7
if (rfc822Data) {
8
const emailMessageWithBody = // parse the `rfc822Data`
9
}
10
} catch {
11
// Handle/notify user of error
12
}
Copied!
1
emailClient.getEmailMessageRFC822DataWithId(id) { result in
2
switch result {
3
case let .failure(error):
4
/// Handle/notify user of error
5
case let .success(data):
6
/// The data here is the RFC822. Parse it to read the necessary fields.
7
}
Copied!
1
launch {
2
try {
3
val rfc822Data = withContext(Dispatchers.IO) {
4
emailClient.getEmailMessageRfc822Data(
5
id,
6
cachePolicy = CachePolicy.REMOTE_ONLY
7
)
8
}
9
// If the [id] matches an email message, [rfc822Data] will be returned, else [null]
10
if (rfc822Data != null) {
11
val emailMessageWithBody = // parse the [rfc822Data]
12
}
13
} catch (e: EmailMessageException) {
14
// Handle/notify user of exception
15
}
16
}
Copied!

Entitlements

While previously received emails are always able to be retrieved, in order to be able to receive new emails, the user must be entitled. To receive an email the following entitlement checks are performed:
    1.
    The user must be entitled to receive emails by thesudoplatform.email.emailMessageReceiveUserEntitled entitlement.
    2.
    The email address the email is addressed to must have sufficient storage capacity available as determined by the sudoplatform.email.emailStorageMaxPerEmailAddress entitlement.
If these entitlements' checks do not succeed, the incoming email is rejected with a reason indicating that the storage quota has been exceeded allowing the sending email service to retry.
See Email Entitlements for an overview of how the Email service integrates with the Sudo Platform Entitlements system.

Subscribing to Email Message Events

Real-time data is supported in the Email SDK. Calling the message subscription methods in the SDK ensures that data relating to email messages will be returned as they are received on the Email Service.
It is important to use subscriptions sparingly as they are resource intensive. It is recommended to only use them when a specific view is open. For example, it would be appropriate for the application to subscribe when a view of a list of emails is in the foreground. When the user navigates from this view, the application should cancel the subscription.
iOS
Android
To subscribe to email messages, use the subscribeToEmailMessageCreated(withDirection:resultHandler:) method for handling created message events, or subscribeToEmailMessageDeleted(resultHandler:) for handling deleted message events. These methods use a closure resultHandler to allow you to decide what happens when a message is received in real-time.
A SubscriptionToken is also returned from the call to these method. In order to ensure that the subscription remains established and connected, you must keep a strong reference to this returned object. If the reference is lost and marked for clean-up in ARC, the subscription will be cancelled and closed.

Setting Up A Subscription

To setup the subscription for created events, call the subscription method as so:
1
let token = try emailClient.subscribeToEmailMessageCreated(
2
withDirection: .inbound
3
) { result in
4
switch result {
5
case let .failure(error):
6
// Handle error
7
case let .success(emailMessage):
8
// `emailMessage` is the new email message object received in real time.
9
}
Copied!
To setup the subscription for deleted events, call the subscription method as so:
1
let token = try emailClient.subscribeToEmailMessageDeleted { result in
2
switch result {
3
case let .failure(error):
4
// Handle error
5
case let .success(emailMessage):
6
// `emailMessage` is the deleted email message object received in real time.
7
}
Copied!
It is important to ensure that token is not lost until the subscription is no longer needed.
Any errors that arise during the setup of the subscription will be returned via a thrown exception, so make sure to wrap your calls in a do-catch block to handle any failed behavior.

Cancelling A Subscription

To cancel a subscription, use the cancel() method on the SubscriptionToken. For example:
1
token.cancel()
Copied!
This will ensure that the subscription is cancelled and system resources are freed.
To subscribe to email messages, use the subscribeToEmailMessages method. You must pass an identifier of the subscription and an instance of a class that implements the EmailMessageSubscriber interface. This class will be notified of new and deleted email messages as well as any changes in the status of the subscription.

Setting Up A Subscription

To setup the subscription call the subscribeToEmailMessages method as so:
1
val subscriptionId = UUID.randomUUID().toString()
2
val subscriber = object : EmailMessageSubscriber {
3
override fun emailMessageCreated(emailMessage: EmailMessage) {
4
// Handle new email message
5
}
6
override fun emailMessageDeleted(emailMessage: EmailMessage) {
7
// Handle deleted email message
8
}
9
override fun connectionStatusChanged(state: ConnectionState) {
10
// Handle change in the state of the subscription connection
11
}
12
}
13
launch {
14
try {
15
emailClient.subscribeToEmailMessages(
16
subscriptionId,
17
subscriber
18
)
19
} catch (e: EmailMessageException) {
20
// Handle/notify the user of exception
21
}
22
}
Copied!
There is also an extension function that allows you to pass lambdas instead of an object that implements the EmailMessageSubscriber interface.
1
val subscriptionId = UUID.randomUUID().toString()
2
launch {
3
try {
4
emailClient.subscribeToEmailMessages(
5
subscriptionId,
6
onEmailMessageCreated = {
7
// Handle new email message
8
},
9
onEmailMessageDeleted = {
10
// Handle deleted email message
11
},
12
onConnectionChange = {
13
// Handle change in the subscription connection
14
}
15
)
16
} catch (e: EmailMessageException) {
17
// Handle/notify the user of exception
18
}
19
}
Copied!

Cancelling A Subscription

To cancel a subscription, use the unsubscribeFromEmailMessages or unsubscribeAll method. For example:
1
val subscriptionId = // From where the subscription was set up
2
launch {
3
try {
4
emailClient.unsubscribeFromEmailMessages(subscriptionId)
5
// or
6
emailClient.unsubscribeAll()
7
} catch (e: EmailMessageException) {
8
// Handle/notify the user of exception
9
}
10
}
Copied!
This will ensure that the subscription is cancelled and system resources are freed.
Last modified 21d ago