

# Amazon Connect Agent Workspace Email API
<a name="api-reference-3P-apps-email-client"></a>

The Amazon Connect SDK provides an `EmailClient` which serves as an interface that your app can use to subscribe to email contact events and make email contact requests.

The `EmailClient` accepts an optional constructor argument, ` ConnectClientConfig` which itself is defined as:

```
export type ConnectClientConfig = {  
    context?: ModuleContext;  
    provider?: AmazonConnectProvider;
};
```

If you do not provide a value for this config, then the client will default to using the ** AmazonConnectProvider** set in the global provider scope. You can also manually configure this using **setGlobalProvider**.

You can instantiate the agent client as follows:

```
import { EmailClient } from "@amazon-connect/email";

const emailClient = new EmailClient({ provider });
```

**Note**  
You must first instantiate the [ AmazonConnectApp](getting-started-initialize-sdk.md) which initializes the default AmazonConnectProvider and returns ` { provider } `. This is the recommended option.

Alternatively, providing a constructor argument:

```
import { EmailClient } from "@amazon-connect/email";
            
const emailClient = new EmailClient({
    context: sampleContext,  
    provider: sampleProvider
});
```

**Note**  
Third-party applications must be configured with Cross Contact scope in order to utilize the EmailClient APIs, and \$1 permission is required.

The following sections describe API calls for working with the Email API.

**Topics**
+ [onAcceptedEmail()](3P-apps-email-requests-acceptedemail-subscribing.md)
+ [offAcceptedEmail()](3P-apps-email-requests-acceptedemail-unsubscribing.md)
+ [createDraftEmail()](3P-apps-email-requests-createdraftemail.md)
+ [onDraftEmailCreated()](3P-apps-email-requests-draftemailcreated-subscribing.md)
+ [offDraftEmailCreated()](3P-apps-email-requests-draftemailcreated-unsubscribing.md)
+ [getEmailData()](3P-apps-email-requests-getemaildata.md)
+ [getEmailThread()](3P-apps-email-requests-getemailthread.md)
+ [sendEmail()](3P-apps-email-requests-sendemail.md)

# Subscribe to accepted email notifications in Amazon Connect Agent Workspace
<a name="3P-apps-email-requests-acceptedemail-subscribing"></a>

Subscribes a callback function to-be-invoked whenever an inbound email contact has been accepted.

 **Signature** 

```
onAcceptedEmail(handler: SubscriptionHandler<EmailContactId> contactId?: string): void
```

 **Usage** 

```
const handler: SubscriptionHandler<EmailContactId> = async (emailContact: EmailContactId) => {
   const { contactId } = emailContact;
   console.log(`Accepted Email Contact with Id: ${contactId}`);
}

emailClient.onAcceptedEmail(handler);

// EmailContactId Structure
{
   contactId: string;
}
```

# Unsubscribe from accepted email notifications in Amazon Connect Agent Workspace
<a name="3P-apps-email-requests-acceptedemail-unsubscribing"></a>

Unsubscribes a callback function from the event that is fired when an inbound email contact is accepted.

 **Signature** 

```
offAcceptedEmail(handler: SubscriptionHandler<EmailContactId>, contactId?: string): void
```

 **Usage** 

```
emailClient.offAcceptedEmail(handler);
```

# Create a draft email contact in Amazon Connect Agent Workspace
<a name="3P-apps-email-requests-createdraftemail"></a>

Creates a draft outbound email contact; can either be an agent initiated outbound draft email or an agent reply draft email. Upon successful draft creation, the email contact will be in connected state. Returns an object that includes:
+ `contactId: string`: The contact id of the newly created draft email contact

 **Signature** 

```
createDraftEmail(contactCreation: CreateDraftEmailContact): Promise<EmailContactId>
```

 **CreateDraftEmailContact Properties** 


|  **Parameter**  |  **Type**  |  **Description**  | 
| --- | --- | --- | 
| initiationMethod | "AGENT\$1REPLY" \$1 "OUTBOUND" | "OUTBOUND" indicates that this draft email is the start of a new email conversation; "AGENT\$1REPLY" indicates that this draft email is being sent in response to an incoming email contact | 
| relatedContactId | string | The id of the contact that is the reason for creating the new draft email; this is required when initiationMethod="AGENT\$1REPLY" and should be the contact id of the email that this email is being sent in response to. | 
| expiryDurationInMinutes | number | Length of time before an unsent contact expires; Minimum is 1 minute, Maximum is 1 week; Default is 12 hours. | 
| attributes | Record<string, string> | A custom key-value pair using an attribute map. The attributes are standard Amazon Connect attributes, and can be accessed in flows just like any other contact attributes. | 
| references | Record<string, \$1 type: string; value: string; \$1> | Well-formed data on a contact, used by agents to complete a contact request. | 

 **Usage for Agent Initiated Outbound** 

```
const contact: EmailContactId = await emailClient.createDraftEmail({
   initiationMethod: "OUTBOUND",
});

const { contactId } = contact;
```

 **Usage for Agent Reply** 

```
const acceptedInboundEmailContactId = "exampleContactId";

const contact: EmailContactId = await emailClient.createDraftEmail({
   initiationMethod: "AGENT_REPLY",
   relatedContactId: acceptedInboundEmailContactId,
});

const { contactId } = contact;
```

# Subscribe to draft email creation notifications in Amazon Connect Agent Workspace
<a name="3P-apps-email-requests-draftemailcreated-subscribing"></a>

Subscribes a callback function to-be-invoked whenever a draft email contact has been created.

 **Signature** 

```
onDraftEmailCreated(handler: SubscriptionHandler<EmailContactId>, contactId?: string): void
```

 **Usage** 

```
const handler: SubscriptionHandler<EmailContactId> = async (emailContact: EmailContactId) => {
   const { contactId } = emailContact;
   console.log(`Draft Email Contact Created with Id: ${contactId}`);
}

emailClient.onDraftEmailCreated(handler);

// EmailContactId Structure
{
   contactId: string;
}
```

# Unsubscribe from draft email creation notifications in Amazon Connect Agent Workspace
<a name="3P-apps-email-requests-draftemailcreated-unsubscribing"></a>

Unsubscribes a callback function from the event that is fired when a draft email contact is created.

 **Signature** 

```
offDraftEmailCreated(handler: SubscriptionHandler<EmailContactId>, contactId?: string): void
```

 **Usage** 

```
emailClient.offDraftEmailCreated(handler);
```

# Get the metadata for an email contact in Amazon Connect Agent Workspace
<a name="3P-apps-email-requests-getemaildata"></a>

Returns the metadata for an email contact id while handling an active contact. The activeContactId is the id of the email contact the agent is actively viewing while contactId is the id of the email contact whose metadata should be retrieved.

 **Signature** 

```
getEmailData({ contactId, activeContactId }: { contactId: string; activeContactId: string; }): Promise<EmailContact>
```

 **Output - *EmailContact Properties*** 


|  **Parameter**  |  **Type**  |  **Description**  | 
| --- | --- | --- | 
| contactId | string | The id of the email contact | 
| contactArn | string | The ARN of the email contact | 
| contactAssociationId | string | The root contactId which is used as a unique identifier for all subsequent contacts in a contact tree. Use this value with the EmailClient.getEmailThread api. | 
| relatedContactId | string | This contact is in response or related to the specified related contact. | 
| initialContactId | string | If this contact is related to other contacts, this is the id of the initial contact. | 
| subject | string | The subject of the email | 
| from | EmailAddress | An object that includes the from email address; this value could be undefined when the email contact has not been sent. | 
| to | EmailAddress[] | An array of objects, each including an email address the email contact was sent to | 
| cc | EmailAddress[] | An array of objects, each including an email address that was carbon copied on the email contact | 
| deliveredTo | EmailAddress | An object that includes the email address associated with Amazon Connect that received this message; this is only applicable when direction=INBOUND. | 
| direction | "INBOUND" \$1 "OUTBOUND" | INBOUND means the email contact was delivered to Amazon Connect; OUTBOUND means the email contact is from Amazon Connect | 
| bodyLocation | EmailArtifactLocation | An object that includes the id and associated resource ARN of the file that the email contact's body is stored in; this value could be undefined when the email contact has not been sent. | 
| attachmentLocations | EmailArtifactLocation[] | An array of objects, each including the id and associated resource ARN, of files that have been attached to the email contact | 

 **EmailAddress Properties** 


|  **Parameter**  |  **Type**  |  **Description**  | 
| --- | --- | --- | 
| emailAddress | string | The email address | 
| displayName | string | The name that is displayed inside the recipient's mailbox | 

 **EmailArtifactLocation Properties** 


|  **Parameter**  |  **Type**  |  **Description**  | 
| --- | --- | --- | 
| fileId | string | The id of the attached file | 
| associatedResourceArn | string | The Amazon Connect resource to which the attached file is related to | 

 **Usage** 

```
const activeContactId: string = "exampleActiveContactId"; // The contact the agent is actively handling
const contactId: string = "contactIdToDescribe"; // The email contact id whose metadata should be retrieved

const emailMetadata: EmailContact = await emailClient.getEmailData({ contactId, activeContactId });

// Get the body of the email through the File Client
const bodyLocation = emailMetadata.bodyLocation;
if (bodyLocation) {
   const body: DownloadableAttachment = await fileClient.getAttachedFileUrl({
        attachment: bodyLocation,
        activeContactId,
   });
   
   const { downloadUrl } = body;
   const response: Response = await fetch(downloadUrl, { method: "GET" });
   const bodyContent: string = (await response.json()).messageContent;
}
```

**Note**  
The EmailContact object will contain bodyLocation and attachmentLocations, both of which will require use of the FileClient's getAttachedFileUrl to get the relevant data for those objects.

# Get a list of email contacts in an email contact's tree in Amazon Connect Agent Workspace
<a name="3P-apps-email-requests-getemailthread"></a>

Returns an array of EmailThreadContact objects (for the provided contactAssociationId) that represent that contact's email thread. The contactAssociationId is the root contact id which is used as a unique identifier for all subsequent contacts in a contact tree. Returns an object that includes:
+ `contacts: EmailThreadContact[]`: an array of EmailThreadContact objects, each an email contact in the thread
+ `nextToken?: string`: The token for the next set of results; use the value returned in the previous response in the next request to retrieve the next set of results

 **Signature** 

```
getEmailThread(getEmailThreadParams: GetEmailThreadParams): Promise<{ contacts: EmailThreadContact[]; nextToken?: string; }>
```

 **EmailThreadContact Properties** 


|  **Parameter**  |  **Type**  |  **Description**  | 
| --- | --- | --- | 
| contactId | string | The id of the email contact | 
| contactArn | string | The ARN of the email contact | 
| previousContactId | string | If this contact is not the first contact, this is the ID of the previous contact. | 
| initialContactId | string | If this contact is related to other contacts, this is the ID of the initial contact. | 
| relatedContactId | string | The contactId that is related to this contact. | 
| initiationMethod | string | Indicates how the contact was initiated; Supported values: "INBOUND" ,"OUTBOUND", "AGENT\$1REPLY", or "TRANSFER" | 
| initiationTimestamp | Date | The date and time this contact was initiated, in UTC time. | 
| disconnectTimestamp | Date \$1 undefined | The date and time that the customer endpoint disconnected from the current contact, in UTC time. In transfer scenarios, the DisconnectTimestamp of the previous contact indicates the date and time when that contact ended. | 

 **GetEmailThreadParams Properties** 


|  **Parameter**  |  **Type**  |  **Description**  | 
| --- | --- | --- | 
| contactAssociationId | string | The contact association id to get the thread for. | 
| maxResults | number | The max number of email threads to return; Default is 100. Minimum value of 1. Maximum value of 100. | 
| nextToken | string | The token for the next set of results. Use the value returned in the previous response in the next request to retrieve the next set of results. | 

 **Usage** 

```
const inboundEmailData = await emailClient.getEmailData({
   contactId: sampleContactId, // The inbound email contact you've accepted (or is still connecting)
   activeContactId: sampleContactId, // The email contact you're actively working; in this example, its the same as the accepted inbound email
}); 

const emailThreadContacts = await emailClient.getEmailThread({
  contactAssociationId: inboundEmailData.contactAssociationId,
});

// OPTIONAL: Filter out contacts that have been transferred to avoid displaying duplicated email content
const previousContactIdsSet = new Set(
    emailThreadContacts
        .map(emailThreadContact => emailThreadContact.previousContactId)
        .filter(Boolean)
);

const filteredEmailContactsInEmailThread = emailThreadContacts.filter(emailContact => 
    emailContact.contactId === sampleContactId || 
    !previousContactIdsSet.includes(emailContact.contactId)
);
```

**Note**  
Each time an email contact is transferred, a new contact ID is created with initiationMethod === 'TRANSFER' and its previousContactId is the contact id before the transfer. You may optionally filter out these transferred contacts to avoid duplicate content when rendering the email thread.

# Send a draft email contact in Amazon Connect Agent Workspace
<a name="3P-apps-email-requests-sendemail"></a>

Sends both agent initiated and agent reply draft email contacts. Upon successfully sending the email, the contact will transition to ENDED state.

 **Signature** 

```
sendEmail(emailContact: DraftEmailContact): Promise<void>
```

 **DraftEmailContact Properties** 


|  **Parameter**  |  **Type**  |  **Description**  | 
| --- | --- | --- | 
| to | EmailAddress[] | An array of destination email addresses; max length supported is 1 | 
| emailContent | EmailContent | The content of the email | 
| from | EmailAddress | The email contact will be sent from this email address; if no from address is provided in the request, the queue MUST have a default email address specified in the Outbound email configuration | 
| cc | EmailAddress[] | Additional recipients to receive a carbon copy of the email; Max length supported is 10 | 
| contactId | string | The id of the draft email contact | 

 **EmailAddress Properties** 


|  **Parameter**  |  **Type**  |  **Description**  | 
| --- | --- | --- | 
| emailAddress | string | The email address | 
| displayName | string | The name that is displayed inside the recipient's mailbox | 

 **EmailContent Properties** 


|  **Parameter**  |  **Type**  |  **Description**  | 
| --- | --- | --- | 
| subject | string | The email contact's subject | 
| body | string | The body/content of the email, either in plain text or HTML | 
| bodyType | "text/plain" \$1 "text/html" | The body type of the email; can either be "text/plain" or "text/html" | 

 **Error Handling** 

When sending draft emails, agents may encounter issues. The @amazon-connect/email library provides methods to handle common errors:
+ `isOutboundEmailAddressNotConfiguredError()`: Handle errors when the routing profile's default outbound queue does not have a default outbound email address and the sendEmail() request does not include a from address.
+ `isEmailBodySizeExceededError()`: Handle errors when the size of the email body exceeds the limit.
+ `isTotalEmailSizeExceededError()`: Handle errors when the total size of the email (email body and all attachments) exceeds the limit.

 **Usage** 

```
import { 
    isOutboundEmailAddressNotConfiguredError, 
    isEmailBodySizeExceededError,
    isTotalEmailSizeExceededError,
} from "@amazon-connect/email";

/* ... */

const toEmailAddress = {
  emailAddress: sampleRecipientAddress,
};

const emailContent = {
  subject: "Hello!",
  body: "Thank you!",
  bodyType: "text/plain",
}

const draftContact = {
  to: [toEmailAddress]
  emailContent,
  contactId: draftContactId, // This is the contact ID of the draft contact created via createDraftEmail()
};

try {
  await emailClient.sendEmail(draftContact);
} catch (e) {
  if (isOutboundEmailAddressNotConfiguredError(e)) {
    // Handle error when the routing profile's default outbound queue does not have a default 
    // outbound email address and the request to `sendEmail` does not include a `from` address.
  } else if (isEmailBodySizeExceededError(e)) {
    // Handle error when the size of the email body exceeds the limit
  } else if (isTotalEmailSizeExceededError(e)) {
    // Handle error when total size of the email (email body and all attachments) exceeds the limit
  }
}
```