Skip to content

Commit 93da099

Browse files
authored
Azure Communication Services Email SDK for GA (Azure#34823)
* AutoGenerated SDK changes from REST API * Update version in EmailClientOptions * Add generated SDK after another round of swagger changes * Add convenience overloads for EmailClient.Send * Fix failing unit tests * Add overload for EmailAttachment constructor that takes BinaryData * Add overload for EmailAttachment that takes BinaryData as parameter * Restore global.json * update SDK with long running operation * revert global.json * fix build failures * Update SDK to include changes due to LRO patternn and fix issues that prevent apiview from being generated. * Remove default value of null for displayName in EmailAddress constructor * Regenerated SDK after swagger approved by ARB * fix tests and samples * fix failing unit tests by removing the generatd StartSend method * rengerate SDK with updated swagger after ARB feedback * stash changes * Implement LRO pattern SDK guidelines * Removing Models namespace from hand-rolled models as well * Hide the Id property in EmailSendResult * Add more unit tests for new scenarios * update property ContentBytesBase64 to ContentInBase64 * Update samples * fix errors from merge * update public API and snippets * regenerate SDK after merge from remote * Convert EmailAddress to struct * Convert Attachment content to base64 only at the end before sending over the wire * Fix failing unit tests * regenerate public API * Rename DisableUserEngagementTracking proprety * Update Public API surface * update EmailMessage constructor to reorder parameters and fix tests * Update recorded tests * Fix build errors and override EmailsendResult.Serialization.cs * update recorded tests with sanitized urls * Update recorded test that was timing out. * Address feedback - customize EmailModelFacory, split sample md files into individual files, fix links in md files * fix broken links and add raw github file link in autorest.md * remove codegenclient and codegensuppresstype * add asp.net extensions for EmailClient * actually adding the file for asp.net extensions for EmailClient * Add missing asp.net extension and rename RestClient * update public APIs * update changelog * update SDK with GA API * update EmailMessage constructor to rename parameters based on previous APIView feedback * Update version in project file. * Make GetSendResult methods internal so that it is not exposed to public. * Update change log and failing live tests. * Update parameter names in EmailClient.Send * implement SDK methods using newer LRO pattern * add exception handling in samples * Remove creation of RequestFailedException and use the exception created by OperationOfTInternal. Update samples * update samples with exception handling * Update to the latest version of swagger in autorest * update recorded tests
1 parent 0495b38 commit 93da099

File tree

62 files changed

+1848
-2170
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1848
-2170
lines changed

sdk/communication/Azure.Communication.Email/CHANGELOG.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
# Release History
22

3-
## 1.0.0-beta.5 (Unreleased)
4-
5-
### Features Added
3+
## 1.0.0 (2023-03-31)
64

75
### Breaking Changes
8-
9-
### Bugs Fixed
10-
11-
### Other Changes
6+
- Changed: Renamed parameter names in EmailMessage constructor
7+
- Removed: Removed public methods for GetSendResult and GetSendResultAsync since the same functionality is available through EmailSendOperation.UpdateStatus method
128

139
## 1.0.0-beta.4 (2023-03-15)
1410

sdk/communication/Azure.Communication.Email/README.md

Lines changed: 81 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This package contains a C# SDK for Azure Communication Services for Email.
99
Install the Azure Communication Email client library for .NET with [NuGet][nuget]:
1010

1111
```dotnetcli
12-
dotnet add package Azure.Communication.Email --prerelease
12+
dotnet add package Azure.Communication.Email
1313
```
1414

1515
### Prerequisites
@@ -46,17 +46,25 @@ EmailClient emailClient = new EmailClient(new Uri(endpoint), tokenCredential);
4646
### Send a simple email message with automatic polling for status
4747
To send an email message, call the simple overload of `Send` or `SendAsync` function from the `EmailClient`.
4848
```C# Snippet:Azure_Communication_Email_Send_Simple_AutoPolling
49-
var emailSendOperation = emailClient.Send(
50-
wait: WaitUntil.Completed,
51-
from: "<Send email address>" // The email address of the domain registered with the Communication Services resource
52-
to: "<recipient email address>"
53-
subject: "This is the subject",
54-
htmlContent: "<html><body>This is the html body</body></html>");
55-
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
49+
try
50+
{
51+
var emailSendOperation = emailClient.Send(
52+
wait: WaitUntil.Completed,
53+
senderAddress: "<Send email address>" // The email address of the domain registered with the Communication Services resource
54+
recipientAddress: "<recipient email address>"
55+
subject: "This is the subject",
56+
htmlContent: "<html><body>This is the html body</body></html>");
57+
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
5658

57-
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
58-
string operationId = emailSendOperation.Id;
59-
Console.WriteLine($"Email operation id = {operationId}");
59+
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
60+
string operationId = emailSendOperation.Id;
61+
Console.WriteLine($"Email operation id = {operationId}");
62+
}
63+
catch ( RequestFailedException ex )
64+
{
65+
/// OperationID is contained in the exception message and can be used for troubleshooting purposes
66+
Console.WriteLine($"Email send operation failed with error code: {ex.ErrorCode}, message: {ex.Message}");
67+
}
6068
```
6169

6270
### Send a simple email message with manual polling for status
@@ -65,26 +73,33 @@ To send an email message, call the simple overload of `Send` or `SendAsync` func
6573
/// Send the email message with WaitUntil.Started
6674
var emailSendOperation = await emailClient.SendAsync(
6775
wait: WaitUntil.Started,
68-
from: "<Send email address>" // The email address of the domain registered with the Communication Services resource
69-
to: "<recipient email address>"
76+
senderAddress: "<Send email address>" // The email address of the domain registered with the Communication Services resource
77+
recipientAddress: "<recipient email address>"
7078
subject: "This is the subject",
7179
htmlContent: "<html><body>This is the html body</body></html>");
7280

7381
/// Call UpdateStatus on the email send operation to poll for the status
7482
/// manually.
75-
while (true)
83+
try
7684
{
77-
await emailSendOperation.UpdateStatusAsync();
78-
if (emailSendOperation.HasCompleted)
85+
while (true)
7986
{
80-
break;
87+
await emailSendOperation.UpdateStatusAsync();
88+
if (emailSendOperation.HasCompleted)
89+
{
90+
break;
91+
}
92+
await Task.Delay(100);
8193
}
82-
await Task.Delay(100);
83-
}
8494

85-
if (emailSendOperation.HasValue)
95+
if (emailSendOperation.HasValue)
96+
{
97+
Console.WriteLine($"Email queued for delivery. Status = {emailSendOperation.Value.Status}");
98+
}
99+
}
100+
catch (RequestFailedException ex)
86101
{
87-
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
102+
Console.WriteLine($"Email send failed with Code = {ex.ErrorCode} and Message = {ex.Message}");
88103
}
89104

90105
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
@@ -104,18 +119,26 @@ var emailContent = new EmailContent("This is the subject")
104119

105120
// Create the EmailMessage
106121
var emailMessage = new EmailMessage(
107-
fromAddress: "<Send email address>" // The email address of the domain registered with the Communication Services resource
108-
toAddress: "<recipient email address>"
122+
senderAddress: "<Send email address>" // The email address of the domain registered with the Communication Services resource
123+
recipientAddress: "<recipient email address>"
109124
content: emailContent);
110125

111-
var emailSendOperation = emailClient.Send(
112-
wait: WaitUntil.Completed,
113-
message: emailMessage);
114-
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
126+
try
127+
{
128+
var emailSendOperation = emailClient.Send(
129+
wait: WaitUntil.Completed,
130+
message: emailMessage);
131+
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
115132

116-
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
117-
string operationId = emailSendOperation.Id;
118-
Console.WriteLine($"Email operation id = {operationId}");
133+
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
134+
string operationId = emailSendOperation.Id;
135+
Console.WriteLine($"Email operation id = {operationId}");
136+
}
137+
catch ( RequestFailedException ex )
138+
{
139+
/// OperationID is contained in the exception message and can be used for troubleshooting purposes
140+
Console.WriteLine($"Email send operation failed with error code: {ex.ErrorCode}, message: {ex.Message}");
141+
}
119142
```
120143

121144
### Send an email message to multiple recipients
@@ -170,21 +193,29 @@ var emailMessage = new EmailMessage(
170193
emailRecipients,
171194
emailContent);
172195

173-
EmailSendOperation emailSendOperation = emailClient.Send(WaitUntil.Completed, emailMessage);
174-
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
196+
try
197+
{
198+
EmailSendOperation emailSendOperation = emailClient.Send(WaitUntil.Completed, emailMessage);
199+
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
175200

176-
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
177-
string operationId = emailSendOperation.Id;
178-
Console.WriteLine($"Email operation id = {operationId}");
201+
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
202+
string operationId = emailSendOperation.Id;
203+
Console.WriteLine($"Email operation id = {operationId}");
204+
}
205+
catch ( RequestFailedException ex )
206+
{
207+
/// OperationID is contained in the exception message and can be used for troubleshooting purposes
208+
Console.WriteLine($"Email send operation failed with error code: {ex.ErrorCode}, message: {ex.Message}");
209+
}
179210
```
180211

181212
### Send email with attachments
182213
Azure Communication Services support sending emails with attachments.
183214
```C# Snippet:Azure_Communication_Email_Send_With_Attachments
184215
// Create the EmailMessage
185216
var emailMessage = new EmailMessage(
186-
fromAddress: "<Send email address>" // The email address of the domain registered with the Communication Services resource
187-
toAddress: "<recipient email address>"
217+
senderAddress: "<Send email address>" // The email address of the domain registered with the Communication Services resource
218+
recipientAddress: "<recipient email address>"
188219
content: emailContent);
189220

190221
var filePath = "<path to your file>";
@@ -196,12 +227,20 @@ var emailAttachment = new EmailAttachment(attachmentName, contentType, content);
196227

197228
emailMessage.Attachments.Add(emailAttachment);
198229

199-
EmailSendOperation emailSendOperation = emailClient.Send(WaitUntil.Completed, emailMessage);
200-
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
230+
try
231+
{
232+
EmailSendOperation emailSendOperation = emailClient.Send(WaitUntil.Completed, emailMessage);
233+
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
201234

202-
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
203-
string operationId = emailSendOperation.Id;
204-
Console.WriteLine($"Email operation id = {operationId}");
235+
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
236+
string operationId = emailSendOperation.Id;
237+
Console.WriteLine($"Email operation id = {operationId}");
238+
}
239+
catch ( RequestFailedException ex )
240+
{
241+
/// OperationID is contained in the exception message and can be used for troubleshooting purposes
242+
Console.WriteLine($"Email send operation failed with error code: {ex.ErrorCode}, message: {ex.Message}");
243+
}
205244
```
206245

207246
## Troubleshooting

sdk/communication/Azure.Communication.Email/api/Azure.Communication.Email.netstandard2.0.cs

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,19 @@ public EmailClient(string connectionString) { }
2424
public EmailClient(string connectionString, Azure.Communication.Email.EmailClientOptions options) { }
2525
public EmailClient(System.Uri endpoint, Azure.AzureKeyCredential credential, Azure.Communication.Email.EmailClientOptions options = null) { }
2626
public EmailClient(System.Uri endpoint, Azure.Core.TokenCredential credential, Azure.Communication.Email.EmailClientOptions options = null) { }
27-
public virtual Azure.Response<Azure.Communication.Email.EmailSendResult> GetSendResult(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
28-
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Communication.Email.EmailSendResult>> GetSendResultAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
2927
public virtual Azure.Communication.Email.EmailSendOperation Send(Azure.WaitUntil wait, Azure.Communication.Email.EmailMessage message, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
30-
public virtual Azure.Communication.Email.EmailSendOperation Send(Azure.WaitUntil wait, string from, string to, string subject, string htmlContent, string plainTextContent = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
28+
public virtual Azure.Communication.Email.EmailSendOperation Send(Azure.WaitUntil wait, string senderAddress, string recipientAddress, string subject, string htmlContent, string plainTextContent = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
3129
public virtual System.Threading.Tasks.Task<Azure.Communication.Email.EmailSendOperation> SendAsync(Azure.WaitUntil wait, Azure.Communication.Email.EmailMessage message, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
32-
public virtual System.Threading.Tasks.Task<Azure.Communication.Email.EmailSendOperation> SendAsync(Azure.WaitUntil wait, string from, string to, string subject, string htmlContent, string plainTextContent = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
30+
public virtual System.Threading.Tasks.Task<Azure.Communication.Email.EmailSendOperation> SendAsync(Azure.WaitUntil wait, string senderAddress, string recipientAddress, string subject, string htmlContent, string plainTextContent = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
3331
}
3432
public partial class EmailClientOptions : Azure.Core.ClientOptions
3533
{
36-
public EmailClientOptions(Azure.Communication.Email.EmailClientOptions.ServiceVersion version = Azure.Communication.Email.EmailClientOptions.ServiceVersion.V2023_01_15_Preview) { }
34+
public EmailClientOptions(Azure.Communication.Email.EmailClientOptions.ServiceVersion version = Azure.Communication.Email.EmailClientOptions.ServiceVersion.V2023_03_31) { }
3735
public enum ServiceVersion
3836
{
3937
V2021_10_01_Preview = 1,
4038
V2023_01_15_Preview = 2,
39+
V2023_03_31 = 3,
4140
}
4241
}
4342
public partial class EmailContent
@@ -50,7 +49,7 @@ public EmailContent(string subject) { }
5049
public partial class EmailMessage
5150
{
5251
public EmailMessage(string senderAddress, Azure.Communication.Email.EmailRecipients recipients, Azure.Communication.Email.EmailContent content) { }
53-
public EmailMessage(string fromAddress, string toAddress, Azure.Communication.Email.EmailContent content) { }
52+
public EmailMessage(string senderAddress, string recipientAddress, Azure.Communication.Email.EmailContent content) { }
5453
public System.Collections.Generic.IList<Azure.Communication.Email.EmailAttachment> Attachments { get { throw null; } }
5554
public Azure.Communication.Email.EmailContent Content { get { throw null; } }
5655
public System.Collections.Generic.IDictionary<string, string> Headers { get { throw null; } }
@@ -61,9 +60,7 @@ public EmailMessage(string fromAddress, string toAddress, Azure.Communication.Em
6160
}
6261
public static partial class EmailModelFactory
6362
{
64-
public static Azure.Communication.Email.EmailSendResult EmailSendResult(string id = null, Azure.Communication.Email.EmailSendStatus status = default(Azure.Communication.Email.EmailSendStatus), Azure.Communication.Email.ErrorDetail error = null) { throw null; }
65-
public static Azure.Communication.Email.ErrorAdditionalInfo ErrorAdditionalInfo(string type = null, object info = null) { throw null; }
66-
public static Azure.Communication.Email.ErrorDetail ErrorDetail(string code = null, string message = null, string target = null, System.Collections.Generic.IEnumerable<Azure.Communication.Email.ErrorDetail> details = null, System.Collections.Generic.IEnumerable<Azure.Communication.Email.ErrorAdditionalInfo> additionalInfo = null) { throw null; }
63+
public static Azure.Communication.Email.EmailSendResult EmailSendResult(string id = null, Azure.Communication.Email.EmailSendStatus status = default(Azure.Communication.Email.EmailSendStatus)) { throw null; }
6764
}
6865
public partial class EmailRecipients
6966
{
@@ -84,13 +81,14 @@ public EmailSendOperation(string id, Azure.Communication.Email.EmailClient clien
8481
public override Azure.Response GetRawResponse() { throw null; }
8582
public override Azure.Response UpdateStatus(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
8683
public override System.Threading.Tasks.ValueTask<Azure.Response> UpdateStatusAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
84+
public override Azure.Response<Azure.Communication.Email.EmailSendResult> WaitForCompletion(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
85+
public override Azure.Response<Azure.Communication.Email.EmailSendResult> WaitForCompletion(System.TimeSpan suggestedPollingInterval, System.Threading.CancellationToken cancellationToken) { throw null; }
8786
public override System.Threading.Tasks.ValueTask<Azure.Response<Azure.Communication.Email.EmailSendResult>> WaitForCompletionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
88-
public override System.Threading.Tasks.ValueTask<Azure.Response<Azure.Communication.Email.EmailSendResult>> WaitForCompletionAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken) { throw null; }
87+
public override System.Threading.Tasks.ValueTask<Azure.Response<Azure.Communication.Email.EmailSendResult>> WaitForCompletionAsync(System.TimeSpan suggestedPollingInterval, System.Threading.CancellationToken cancellationToken) { throw null; }
8988
}
9089
public partial class EmailSendResult
9190
{
9291
internal EmailSendResult() { }
93-
public Azure.Communication.Email.ErrorDetail Error { get { throw null; } }
9492
public Azure.Communication.Email.EmailSendStatus Status { get { throw null; } }
9593
}
9694
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
@@ -114,21 +112,6 @@ internal EmailSendResult() { }
114112
public static bool operator !=(Azure.Communication.Email.EmailSendStatus left, Azure.Communication.Email.EmailSendStatus right) { throw null; }
115113
public override string ToString() { throw null; }
116114
}
117-
public partial class ErrorAdditionalInfo
118-
{
119-
internal ErrorAdditionalInfo() { }
120-
public object Info { get { throw null; } }
121-
public string Type { get { throw null; } }
122-
}
123-
public partial class ErrorDetail
124-
{
125-
internal ErrorDetail() { }
126-
public System.Collections.Generic.IReadOnlyList<Azure.Communication.Email.ErrorAdditionalInfo> AdditionalInfo { get { throw null; } }
127-
public string Code { get { throw null; } }
128-
public System.Collections.Generic.IReadOnlyList<Azure.Communication.Email.ErrorDetail> Details { get { throw null; } }
129-
public string Message { get { throw null; } }
130-
public string Target { get { throw null; } }
131-
}
132115
}
133116
namespace Microsoft.Extensions.Azure
134117
{

sdk/communication/Azure.Communication.Email/samples/Sample1_SendSimpleEmailWithAutomaticPollingForStatus.md

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,25 @@ EmailClient emailClient = new EmailClient(connectionString);
1616
## Send a simple email message with automatic polling for status
1717
To send an email message, call the simple overload of `Send` or `SendAsync` function from the `EmailClient`.
1818
```C# Snippet:Azure_Communication_Email_Send_Simple_AutoPolling
19-
var emailSendOperation = emailClient.Send(
20-
wait: WaitUntil.Completed,
21-
from: "<Send email address>" // The email address of the domain registered with the Communication Services resource
22-
to: "<recipient email address>"
23-
subject: "This is the subject",
24-
htmlContent: "<html><body>This is the html body</body></html>");
25-
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
26-
27-
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
28-
string operationId = emailSendOperation.Id;
29-
Console.WriteLine($"Email operation id = {operationId}");
19+
try
20+
{
21+
var emailSendOperation = emailClient.Send(
22+
wait: WaitUntil.Completed,
23+
senderAddress: "<Send email address>" // The email address of the domain registered with the Communication Services resource
24+
recipientAddress: "<recipient email address>"
25+
subject: "This is the subject",
26+
htmlContent: "<html><body>This is the html body</body></html>");
27+
Console.WriteLine($"Email Sent. Status = {emailSendOperation.Value.Status}");
28+
29+
/// Get the OperationId so that it can be used for tracking the message for troubleshooting
30+
string operationId = emailSendOperation.Id;
31+
Console.WriteLine($"Email operation id = {operationId}");
32+
}
33+
catch ( RequestFailedException ex )
34+
{
35+
/// OperationID is contained in the exception message and can be used for troubleshooting purposes
36+
Console.WriteLine($"Email send operation failed with error code: {ex.ErrorCode}, message: {ex.Message}");
37+
}
3038
```
3139

3240
[README]: https://learn.microsoft.com/azure/communication-services/quickstarts/email/send-email?tabs=windows&pivots=platform-azcli#prerequisites

0 commit comments

Comments
 (0)