Amazon SES API v2-Beispiele mit AWS SDK for .NET - AWS SDKCode-Beispiele

Weitere AWS SDK Beispiele sind im Repo AWS Doc SDK Examples GitHub verfügbar.

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Amazon SES API v2-Beispiele mit AWS SDK for .NET

Die folgenden Codebeispiele zeigen Ihnen, wie Sie mithilfe von Amazon SES API v2 Aktionen ausführen und allgemeine Szenarien implementieren. AWS SDK for .NET

Aktionen sind Codeauszüge aus größeren Programmen und müssen im Kontext ausgeführt werden. Aktionen zeigen Ihnen zwar, wie Sie einzelne Servicefunktionen aufrufen, aber Sie können Aktionen in den zugehörigen Szenarien im Kontext sehen.

Szenarien sind Codebeispiele, die Ihnen zeigen, wie Sie bestimmte Aufgaben ausführen, indem Sie mehrere Funktionen innerhalb eines Dienstes oder in Kombination mit anderen aufrufen AWS-Services.

Jedes Beispiel enthält einen Link zum vollständigen Quellcode, in dem Sie Anweisungen zum Einrichten und Ausführen des Codes im Kontext finden.

Aktionen

Das folgende Codebeispiel zeigt die VerwendungCreateContact.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

/// <summary> /// Creates a contact and adds it to the specified contact list. /// </summary> /// <param name="emailAddress">The email address of the contact.</param> /// <param name="contactListName">The name of the contact list.</param> /// <returns>The response from the CreateContact operation.</returns> public async Task<bool> CreateContactAsync(string emailAddress, string contactListName) { var request = new CreateContactRequest { EmailAddress = emailAddress, ContactListName = contactListName }; try { var response = await _sesClient.CreateContactAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (AlreadyExistsException ex) { Console.WriteLine($"Contact with email address {emailAddress} already exists in the contact list {contactListName}."); Console.WriteLine(ex.Message); return true; } catch (NotFoundException ex) { Console.WriteLine($"The contact list {contactListName} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while creating the contact: {ex.Message}"); } return false; }
  • APIEinzelheiten finden Sie CreateContactin der AWS SDK for .NET APIReferenz.

Das folgende Codebeispiel zeigt die VerwendungCreateContactList.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

/// <summary> /// Creates a contact list with the specified name. /// </summary> /// <param name="contactListName">The name of the contact list.</param> /// <returns>True if successful.</returns> public async Task<bool> CreateContactListAsync(string contactListName) { var request = new CreateContactListRequest { ContactListName = contactListName }; try { var response = await _sesClient.CreateContactListAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (AlreadyExistsException ex) { Console.WriteLine($"Contact list with name {contactListName} already exists."); Console.WriteLine(ex.Message); return true; } catch (LimitExceededException ex) { Console.WriteLine("The limit for contact lists has been exceeded."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while creating the contact list: {ex.Message}"); } return false; }

Das folgende Codebeispiel zeigt die VerwendungCreateEmailIdentity.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

/// <summary> /// Creates an email identity (email address or domain) and starts the verification process. /// </summary> /// <param name="emailIdentity">The email address or domain to create and verify.</param> /// <returns>The response from the CreateEmailIdentity operation.</returns> public async Task<CreateEmailIdentityResponse> CreateEmailIdentityAsync(string emailIdentity) { var request = new CreateEmailIdentityRequest { EmailIdentity = emailIdentity }; try { var response = await _sesClient.CreateEmailIdentityAsync(request); return response; } catch (AlreadyExistsException ex) { Console.WriteLine($"Email identity {emailIdentity} already exists."); Console.WriteLine(ex.Message); throw; } catch (ConcurrentModificationException ex) { Console.WriteLine($"The email identity {emailIdentity} is being modified by another operation or thread."); Console.WriteLine(ex.Message); throw; } catch (LimitExceededException ex) { Console.WriteLine("The limit for email identities has been exceeded."); Console.WriteLine(ex.Message); throw; } catch (NotFoundException ex) { Console.WriteLine($"The email identity {emailIdentity} does not exist."); Console.WriteLine(ex.Message); throw; } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); throw; } catch (Exception ex) { Console.WriteLine($"An error occurred while creating the email identity: {ex.Message}"); throw; } }

Das folgende Codebeispiel zeigt die VerwendungCreateEmailTemplate.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

/// <summary> /// Creates an email template with the specified content. /// </summary> /// <param name="templateName">The name of the email template.</param> /// <param name="subject">The subject of the email template.</param> /// <param name="htmlContent">The HTML content of the email template.</param> /// <param name="textContent">The text content of the email template.</param> /// <returns>True if successful.</returns> public async Task<bool> CreateEmailTemplateAsync(string templateName, string subject, string htmlContent, string textContent) { var request = new CreateEmailTemplateRequest { TemplateName = templateName, TemplateContent = new EmailTemplateContent { Subject = subject, Html = htmlContent, Text = textContent } }; try { var response = await _sesClient.CreateEmailTemplateAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (AlreadyExistsException ex) { Console.WriteLine($"Email template with name {templateName} already exists."); Console.WriteLine(ex.Message); } catch (LimitExceededException ex) { Console.WriteLine("The limit for email templates has been exceeded."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while creating the email template: {ex.Message}"); } return false; }

Das folgende Codebeispiel zeigt die VerwendungDeleteContactList.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

/// <summary> /// Deletes a contact list and all contacts within it. /// </summary> /// <param name="contactListName">The name of the contact list to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteContactListAsync(string contactListName) { var request = new DeleteContactListRequest { ContactListName = contactListName }; try { var response = await _sesClient.DeleteContactListAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (ConcurrentModificationException ex) { Console.WriteLine($"The contact list {contactListName} is being modified by another operation or thread."); Console.WriteLine(ex.Message); } catch (NotFoundException ex) { Console.WriteLine($"The contact list {contactListName} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while deleting the contact list: {ex.Message}"); } return false; }

Das folgende Codebeispiel zeigt die VerwendungDeleteEmailIdentity.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

/// <summary> /// Deletes an email identity (email address or domain). /// </summary> /// <param name="emailIdentity">The email address or domain to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteEmailIdentityAsync(string emailIdentity) { var request = new DeleteEmailIdentityRequest { EmailIdentity = emailIdentity }; try { var response = await _sesClient.DeleteEmailIdentityAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (ConcurrentModificationException ex) { Console.WriteLine($"The email identity {emailIdentity} is being modified by another operation or thread."); Console.WriteLine(ex.Message); } catch (NotFoundException ex) { Console.WriteLine($"The email identity {emailIdentity} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while deleting the email identity: {ex.Message}"); } return false; }

Das folgende Codebeispiel zeigt die VerwendungDeleteEmailTemplate.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

/// <summary> /// Deletes an email template. /// </summary> /// <param name="templateName">The name of the email template to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteEmailTemplateAsync(string templateName) { var request = new DeleteEmailTemplateRequest { TemplateName = templateName }; try { var response = await _sesClient.DeleteEmailTemplateAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (NotFoundException ex) { Console.WriteLine($"The email template {templateName} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while deleting the email template: {ex.Message}"); } return false; }

Das folgende Codebeispiel zeigt die VerwendungListContacts.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

/// <summary> /// Lists the contacts in the specified contact list. /// </summary> /// <param name="contactListName">The name of the contact list.</param> /// <returns>The list of contacts response from the ListContacts operation.</returns> public async Task<List<Contact>> ListContactsAsync(string contactListName) { var request = new ListContactsRequest { ContactListName = contactListName }; try { var response = await _sesClient.ListContactsAsync(request); return response.Contacts; } catch (NotFoundException ex) { Console.WriteLine($"The contact list {contactListName} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while listing the contacts: {ex.Message}"); } return new List<Contact>(); }
  • APIEinzelheiten finden Sie ListContactsin der AWS SDK for .NET APIReferenz.

Das folgende Codebeispiel zeigt die VerwendungSendEmail.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

/// <summary> /// Sends an email with the specified content and options. /// </summary> /// <param name="fromEmailAddress">The email address to send the email from.</param> /// <param name="toEmailAddresses">The email addresses to send the email to.</param> /// <param name="subject">The subject of the email.</param> /// <param name="htmlContent">The HTML content of the email.</param> /// <param name="textContent">The text content of the email.</param> /// <param name="templateName">The name of the email template to use (optional).</param> /// <param name="templateData">The data to replace placeholders in the email template (optional).</param> /// <param name="contactListName">The name of the contact list for unsubscribe functionality (optional).</param> /// <returns>The MessageId response from the SendEmail operation.</returns> public async Task<string> SendEmailAsync(string fromEmailAddress, List<string> toEmailAddresses, string? subject, string? htmlContent, string? textContent, string? templateName = null, string? templateData = null, string? contactListName = null) { var request = new SendEmailRequest { FromEmailAddress = fromEmailAddress }; if (toEmailAddresses.Any()) { request.Destination = new Destination { ToAddresses = toEmailAddresses }; } if (!string.IsNullOrEmpty(templateName)) { request.Content = new EmailContent() { Template = new Template { TemplateName = templateName, TemplateData = templateData } }; } else { request.Content = new EmailContent { Simple = new Message { Subject = new Content { Data = subject }, Body = new Body { Html = new Content { Data = htmlContent }, Text = new Content { Data = textContent } } } }; } if (!string.IsNullOrEmpty(contactListName)) { request.ListManagementOptions = new ListManagementOptions { ContactListName = contactListName }; } try { var response = await _sesClient.SendEmailAsync(request); return response.MessageId; } catch (AccountSuspendedException ex) { Console.WriteLine("The account's ability to send email has been permanently restricted."); Console.WriteLine(ex.Message); } catch (MailFromDomainNotVerifiedException ex) { Console.WriteLine("The sending domain is not verified."); Console.WriteLine(ex.Message); } catch (MessageRejectedException ex) { Console.WriteLine("The message content is invalid."); Console.WriteLine(ex.Message); } catch (SendingPausedException ex) { Console.WriteLine("The account's ability to send email is currently paused."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while sending the email: {ex.Message}"); } return string.Empty; }
  • APIEinzelheiten finden Sie SendEmailin der AWS SDK for .NET APIReferenz.

Szenarien

Das folgende Codebeispiel zeigt, wie der Amazon SES API v2-Newsletter-Workflow ausgeführt wird.

AWS SDK for .NET
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

Führen Sie den Workflow aus.

using System.Diagnostics; using System.Text.RegularExpressions; using Amazon.SimpleEmailV2; using Amazon.SimpleEmailV2.Model; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Console; using Microsoft.Extensions.Logging.Debug; namespace Sesv2Scenario; public static class NewsletterWorkflow { /* This workflow demonstrates how to use the Amazon Simple Email Service (SES) v2 to send a coupon newsletter to a list of subscribers. The workflow performs the following tasks: 1. Prepare the application: - Create a verified email identity for sending and replying to emails. - Create a contact list to store the subscribers' email addresses. - Create an email template for the coupon newsletter. 2. Gather subscriber email addresses: - Prompt the user for a base email address. - Create 3 variants of the email address using subaddress extensions (e.g., user+ses-weekly-newsletter-1@example.com). - Add each variant as a contact to the contact list. - Send a welcome email to each new contact. 3. Send the coupon newsletter: - Retrieve the list of contacts from the contact list. - Send the coupon newsletter using the email template to each contact. 4. Monitor and review: - Provide instructions for the user to review the sending activity and metrics in the AWS console. 5. Clean up resources: - Delete the contact list (which also deletes all contacts within it). - Delete the email template. - Optionally delete the verified email identity. */ public static SESv2Wrapper _sesv2Wrapper; public static string? _baseEmailAddress = null; public static string? _verifiedEmail = null; private static string _contactListName = "weekly-coupons-newsletter"; private static string _templateName = "weekly-coupons"; private static string _subject = "Weekly Coupons Newsletter"; private static string _htmlContentFile = "coupon-newsletter.html"; private static string _textContentFile = "coupon-newsletter.txt"; private static string _htmlWelcomeFile = "welcome.html"; private static string _textWelcomeFile = "welcome.txt"; private static string _couponsDataFile = "sample_coupons.json"; // Relative location of the shared workflow resources folder. private static string _resourcesFilePathLocation = "../../../../../../../workflows/sesv2_weekly_mailer/resources/"; public static async Task Main(string[] args) { // Set up dependency injection for the Amazon service. using var host = Host.CreateDefaultBuilder(args) .ConfigureLogging(logging => logging.AddFilter("System", LogLevel.Debug) .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) .AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace)) .ConfigureServices((_, services) => services.AddAWSService<IAmazonSimpleEmailServiceV2>() .AddTransient<SESv2Wrapper>() ) .Build(); ServicesSetup(host); try { Console.WriteLine(new string('-', 80)); Console.WriteLine(new string('-', 80)); Console.WriteLine("Welcome to the Amazon SES v2 Coupon Newsletter Workflow."); Console.WriteLine("This workflow demonstrates how to use the Amazon Simple Email Service (SES) v2 " + "\r\nto send a coupon newsletter to a list of subscribers."); // Prepare the application. var emailIdentity = await PrepareApplication(); // Gather subscriber email addresses. await GatherSubscriberEmailAddresses(emailIdentity); // Send the coupon newsletter. await SendCouponNewsletter(emailIdentity); // Monitor and review. MonitorAndReview(true); // Clean up resources. await Cleanup(emailIdentity, true); Console.WriteLine(new string('-', 80)); Console.WriteLine("Amazon SES v2 Coupon Newsletter Workflow is complete."); Console.WriteLine(new string('-', 80)); Console.WriteLine(new string('-', 80)); } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } } /// <summary> /// Populate the services for use within the console application. /// </summary> /// <param name="host">The services host.</param> private static void ServicesSetup(IHost host) { _sesv2Wrapper = host.Services.GetRequiredService<SESv2Wrapper>(); } /// <summary> /// Set up the resources for the workflow. /// </summary> /// <returns>The email address of the verified identity.</returns> public static async Task<string?> PrepareApplication() { var htmlContent = await File.ReadAllTextAsync(_resourcesFilePathLocation + _htmlContentFile); var textContent = await File.ReadAllTextAsync(_resourcesFilePathLocation + _textContentFile); Console.WriteLine(new string('-', 80)); Console.WriteLine("1. In this step, we will prepare the application:" + "\r\n - Create a verified email identity for sending and replying to emails." + "\r\n - Create a contact list to store the subscribers' email addresses." + "\r\n - Create an email template for the coupon newsletter.\r\n"); // Prompt the user for a verified email address. while (!IsEmail(_verifiedEmail)) { Console.Write("Enter a verified email address or an email to verify: "); _verifiedEmail = Console.ReadLine(); } try { // Create an email identity and start the verification process. await _sesv2Wrapper.CreateEmailIdentityAsync(_verifiedEmail); Console.WriteLine($"Identity {_verifiedEmail} created."); } catch (AlreadyExistsException) { Console.WriteLine($"Identity {_verifiedEmail} already exists."); } catch (Exception ex) { Console.WriteLine($"Error creating email identity: {ex.Message}"); } // Create a contact list. try { await _sesv2Wrapper.CreateContactListAsync(_contactListName); Console.WriteLine($"Contact list {_contactListName} created."); } catch (AlreadyExistsException) { Console.WriteLine($"Contact list {_contactListName} already exists."); } catch (Exception ex) { Console.WriteLine($"Error creating contact list: {ex.Message}"); } // Create an email template. try { await _sesv2Wrapper.CreateEmailTemplateAsync(_templateName, _subject, htmlContent, textContent); Console.WriteLine($"Email template {_templateName} created."); } catch (AlreadyExistsException) { Console.WriteLine($"Email template {_templateName} already exists."); } catch (Exception ex) { Console.WriteLine($"Error creating email template: {ex.Message}"); } return _verifiedEmail; } /// <summary> /// Generate subscriber addresses and send welcome emails. /// </summary> /// <param name="fromEmailAddress">The verified email address from PrepareApplication.</param> /// <returns>True if successful.</returns> public static async Task<bool> GatherSubscriberEmailAddresses(string fromEmailAddress) { Console.WriteLine(new string('-', 80)); Console.WriteLine("2. In Step 2, we will gather subscriber email addresses:" + "\r\n - Prompt the user for a base email address." + "\r\n - Create 3 variants of the email address using subaddress extensions (e.g., user+ses-weekly-newsletter-1@example.com)." + "\r\n - Add each variant as a contact to the contact list." + "\r\n - Send a welcome email to each new contact.\r\n"); // Prompt the user for a base email address. while (!IsEmail(_baseEmailAddress)) { Console.Write("Enter a base email address (e.g., user@example.com): "); _baseEmailAddress = Console.ReadLine(); } // Create 3 variants of the email address using +ses-weekly-newsletter-1, +ses-weekly-newsletter-2, etc. var baseEmailAddressParts = _baseEmailAddress!.Split("@"); for (int i = 1; i <= 3; i++) { string emailAddress = $"{baseEmailAddressParts[0]}+ses-weekly-newsletter-{i}@{baseEmailAddressParts[1]}"; try { // Create a contact with the email address in the contact list. await _sesv2Wrapper.CreateContactAsync(emailAddress, _contactListName); Console.WriteLine($"Contact {emailAddress} added to the {_contactListName} contact list."); } catch (AlreadyExistsException) { Console.WriteLine($"Contact {emailAddress} already exists in the {_contactListName} contact list."); } catch (Exception ex) { Console.WriteLine($"Error creating contact {emailAddress}: {ex.Message}"); return false; } // Send a welcome email to the new contact. try { string subject = "Welcome to the Weekly Coupons Newsletter"; string htmlContent = await File.ReadAllTextAsync(_resourcesFilePathLocation + _htmlWelcomeFile); string textContent = await File.ReadAllTextAsync(_resourcesFilePathLocation + _textWelcomeFile); await _sesv2Wrapper.SendEmailAsync(fromEmailAddress, new List<string> { emailAddress }, subject, htmlContent, textContent); Console.WriteLine($"Welcome email sent to {emailAddress}."); } catch (Exception ex) { Console.WriteLine($"Error sending welcome email to {emailAddress}: {ex.Message}"); return false; } // Wait 2 seconds before sending the next email (if the account is in the SES Sandbox). await Task.Delay(2000); } return true; } /// <summary> /// Send the coupon newsletter to the subscribers in the contact list. /// </summary> /// <param name="fromEmailAddress">The verified email address from PrepareApplication.</param> /// <returns>True if successful.</returns> public static async Task<bool> SendCouponNewsletter(string fromEmailAddress) { Console.WriteLine(new string('-', 80)); Console.WriteLine("3. In this step, we will send the coupon newsletter:" + "\r\n - Retrieve the list of contacts from the contact list." + "\r\n - Send the coupon newsletter using the email template to each contact.\r\n"); // Retrieve the list of contacts from the contact list. var contacts = await _sesv2Wrapper.ListContactsAsync(_contactListName); if (!contacts.Any()) { Console.WriteLine($"No contacts found in the {_contactListName} contact list."); return false; } // Load the coupon data from the sample_coupons.json file. string couponsData = await File.ReadAllTextAsync(_resourcesFilePathLocation + _couponsDataFile); // Send the coupon newsletter to each contact using the email template. try { foreach (var contact in contacts) { // To use the Contact List for list management, send to only one address at a time. await _sesv2Wrapper.SendEmailAsync(fromEmailAddress, new List<string> { contact.EmailAddress }, null, null, null, _templateName, couponsData, _contactListName); } Console.WriteLine($"Coupon newsletter sent to contact list {_contactListName}."); } catch (Exception ex) { Console.WriteLine($"Error sending coupon newsletter to contact list {_contactListName}: {ex.Message}"); return false; } return true; } /// <summary> /// Provide instructions for monitoring sending activity and metrics. /// </summary> /// <param name="interactive">True to run in interactive mode.</param> /// <returns>True if successful.</returns> public static bool MonitorAndReview(bool interactive) { Console.WriteLine(new string('-', 80)); Console.WriteLine("4. In step 4, we will monitor and review:" + "\r\n - Provide instructions for the user to review the sending activity and metrics in the AWS console.\r\n"); Console.WriteLine("Review your sending activity using the SES Homepage in the AWS console."); Console.WriteLine("Press Enter to open the SES Homepage in your default browser..."); if (interactive) { Console.ReadLine(); try { // Open the SES Homepage in the default browser. Process.Start(new ProcessStartInfo { FileName = "https://console.aws.amazon.com/ses/home", UseShellExecute = true }); } catch (Exception ex) { Console.WriteLine($"Error opening the SES Homepage: {ex.Message}"); return false; } } Console.WriteLine("Review the sending activity and email metrics, then press Enter to continue..."); if (interactive) Console.ReadLine(); return true; } /// <summary> /// Clean up the resources used in the workflow. /// </summary> /// <param name="verifiedEmailAddress">The verified email address from PrepareApplication.</param> /// <param name="interactive">True if interactive.</param> /// <returns>Async task.</returns> public static async Task<bool> Cleanup(string verifiedEmailAddress, bool interactive) { Console.WriteLine(new string('-', 80)); Console.WriteLine("5. Finally, we clean up resources:" + "\r\n - Delete the contact list (which also deletes all contacts within it)." + "\r\n - Delete the email template." + "\r\n - Optionally delete the verified email identity.\r\n"); Console.WriteLine("Cleaning up resources..."); // Delete the contact list (this also deletes all contacts in the list). try { await _sesv2Wrapper.DeleteContactListAsync(_contactListName); Console.WriteLine($"Contact list {_contactListName} deleted."); } catch (NotFoundException) { Console.WriteLine($"Contact list {_contactListName} not found."); } catch (Exception ex) { Console.WriteLine($"Error deleting contact list {_contactListName}: {ex.Message}"); return false; } // Delete the email template. try { await _sesv2Wrapper.DeleteEmailTemplateAsync(_templateName); Console.WriteLine($"Email template {_templateName} deleted."); } catch (NotFoundException) { Console.WriteLine($"Email template {_templateName} not found."); } catch (Exception ex) { Console.WriteLine($"Error deleting email template {_templateName}: {ex.Message}"); return false; } // Ask the user if they want to delete the email identity. var deleteIdentity = !interactive || GetYesNoResponse( $"Do you want to delete the email identity {verifiedEmailAddress}? (y/n) "); if (deleteIdentity) { try { await _sesv2Wrapper.DeleteEmailIdentityAsync(verifiedEmailAddress); Console.WriteLine($"Email identity {verifiedEmailAddress} deleted."); } catch (NotFoundException) { Console.WriteLine( $"Email identity {verifiedEmailAddress} not found."); } catch (Exception ex) { Console.WriteLine( $"Error deleting email identity {verifiedEmailAddress}: {ex.Message}"); return false; } } else { Console.WriteLine( $"Skipping deletion of email identity {verifiedEmailAddress}."); } return true; } /// <summary> /// Helper method to get a yes or no response from the user. /// </summary> /// <param name="question">The question string to print on the console.</param> /// <returns>True if the user responds with a yes.</returns> private static bool GetYesNoResponse(string question) { Console.WriteLine(question); var ynResponse = Console.ReadLine(); var response = ynResponse != null && ynResponse.Equals("y", StringComparison.InvariantCultureIgnoreCase); return response; } /// <summary> /// Simple check to verify a string is an email address. /// </summary> /// <param name="email">The string to verify.</param> /// <returns>True if a valid email.</returns> private static bool IsEmail(string? email) { if (string.IsNullOrEmpty(email)) return false; return Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$", RegexOptions.IgnoreCase); } }

Wrapper für Serviceoperationen.

using System.Net; using Amazon.SimpleEmailV2; using Amazon.SimpleEmailV2.Model; namespace Sesv2Scenario; /// <summary> /// Wrapper class for Amazon Simple Email Service (SES) v2 operations. /// </summary> public class SESv2Wrapper { private readonly IAmazonSimpleEmailServiceV2 _sesClient; /// <summary> /// Constructor for the SESv2Wrapper. /// </summary> /// <param name="sesClient">The injected SES v2 client.</param> public SESv2Wrapper(IAmazonSimpleEmailServiceV2 sesClient) { _sesClient = sesClient; } /// <summary> /// Creates a contact and adds it to the specified contact list. /// </summary> /// <param name="emailAddress">The email address of the contact.</param> /// <param name="contactListName">The name of the contact list.</param> /// <returns>The response from the CreateContact operation.</returns> public async Task<bool> CreateContactAsync(string emailAddress, string contactListName) { var request = new CreateContactRequest { EmailAddress = emailAddress, ContactListName = contactListName }; try { var response = await _sesClient.CreateContactAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (AlreadyExistsException ex) { Console.WriteLine($"Contact with email address {emailAddress} already exists in the contact list {contactListName}."); Console.WriteLine(ex.Message); return true; } catch (NotFoundException ex) { Console.WriteLine($"The contact list {contactListName} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while creating the contact: {ex.Message}"); } return false; } /// <summary> /// Creates a contact list with the specified name. /// </summary> /// <param name="contactListName">The name of the contact list.</param> /// <returns>True if successful.</returns> public async Task<bool> CreateContactListAsync(string contactListName) { var request = new CreateContactListRequest { ContactListName = contactListName }; try { var response = await _sesClient.CreateContactListAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (AlreadyExistsException ex) { Console.WriteLine($"Contact list with name {contactListName} already exists."); Console.WriteLine(ex.Message); return true; } catch (LimitExceededException ex) { Console.WriteLine("The limit for contact lists has been exceeded."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while creating the contact list: {ex.Message}"); } return false; } /// <summary> /// Creates an email identity (email address or domain) and starts the verification process. /// </summary> /// <param name="emailIdentity">The email address or domain to create and verify.</param> /// <returns>The response from the CreateEmailIdentity operation.</returns> public async Task<CreateEmailIdentityResponse> CreateEmailIdentityAsync(string emailIdentity) { var request = new CreateEmailIdentityRequest { EmailIdentity = emailIdentity }; try { var response = await _sesClient.CreateEmailIdentityAsync(request); return response; } catch (AlreadyExistsException ex) { Console.WriteLine($"Email identity {emailIdentity} already exists."); Console.WriteLine(ex.Message); throw; } catch (ConcurrentModificationException ex) { Console.WriteLine($"The email identity {emailIdentity} is being modified by another operation or thread."); Console.WriteLine(ex.Message); throw; } catch (LimitExceededException ex) { Console.WriteLine("The limit for email identities has been exceeded."); Console.WriteLine(ex.Message); throw; } catch (NotFoundException ex) { Console.WriteLine($"The email identity {emailIdentity} does not exist."); Console.WriteLine(ex.Message); throw; } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); throw; } catch (Exception ex) { Console.WriteLine($"An error occurred while creating the email identity: {ex.Message}"); throw; } } /// <summary> /// Creates an email template with the specified content. /// </summary> /// <param name="templateName">The name of the email template.</param> /// <param name="subject">The subject of the email template.</param> /// <param name="htmlContent">The HTML content of the email template.</param> /// <param name="textContent">The text content of the email template.</param> /// <returns>True if successful.</returns> public async Task<bool> CreateEmailTemplateAsync(string templateName, string subject, string htmlContent, string textContent) { var request = new CreateEmailTemplateRequest { TemplateName = templateName, TemplateContent = new EmailTemplateContent { Subject = subject, Html = htmlContent, Text = textContent } }; try { var response = await _sesClient.CreateEmailTemplateAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (AlreadyExistsException ex) { Console.WriteLine($"Email template with name {templateName} already exists."); Console.WriteLine(ex.Message); } catch (LimitExceededException ex) { Console.WriteLine("The limit for email templates has been exceeded."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while creating the email template: {ex.Message}"); } return false; } /// <summary> /// Deletes a contact list and all contacts within it. /// </summary> /// <param name="contactListName">The name of the contact list to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteContactListAsync(string contactListName) { var request = new DeleteContactListRequest { ContactListName = contactListName }; try { var response = await _sesClient.DeleteContactListAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (ConcurrentModificationException ex) { Console.WriteLine($"The contact list {contactListName} is being modified by another operation or thread."); Console.WriteLine(ex.Message); } catch (NotFoundException ex) { Console.WriteLine($"The contact list {contactListName} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while deleting the contact list: {ex.Message}"); } return false; } /// <summary> /// Deletes an email identity (email address or domain). /// </summary> /// <param name="emailIdentity">The email address or domain to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteEmailIdentityAsync(string emailIdentity) { var request = new DeleteEmailIdentityRequest { EmailIdentity = emailIdentity }; try { var response = await _sesClient.DeleteEmailIdentityAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (ConcurrentModificationException ex) { Console.WriteLine($"The email identity {emailIdentity} is being modified by another operation or thread."); Console.WriteLine(ex.Message); } catch (NotFoundException ex) { Console.WriteLine($"The email identity {emailIdentity} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while deleting the email identity: {ex.Message}"); } return false; } /// <summary> /// Deletes an email template. /// </summary> /// <param name="templateName">The name of the email template to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteEmailTemplateAsync(string templateName) { var request = new DeleteEmailTemplateRequest { TemplateName = templateName }; try { var response = await _sesClient.DeleteEmailTemplateAsync(request); return response.HttpStatusCode == HttpStatusCode.OK; } catch (NotFoundException ex) { Console.WriteLine($"The email template {templateName} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while deleting the email template: {ex.Message}"); } return false; } /// <summary> /// Lists the contacts in the specified contact list. /// </summary> /// <param name="contactListName">The name of the contact list.</param> /// <returns>The list of contacts response from the ListContacts operation.</returns> public async Task<List<Contact>> ListContactsAsync(string contactListName) { var request = new ListContactsRequest { ContactListName = contactListName }; try { var response = await _sesClient.ListContactsAsync(request); return response.Contacts; } catch (NotFoundException ex) { Console.WriteLine($"The contact list {contactListName} does not exist."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while listing the contacts: {ex.Message}"); } return new List<Contact>(); } /// <summary> /// Sends an email with the specified content and options. /// </summary> /// <param name="fromEmailAddress">The email address to send the email from.</param> /// <param name="toEmailAddresses">The email addresses to send the email to.</param> /// <param name="subject">The subject of the email.</param> /// <param name="htmlContent">The HTML content of the email.</param> /// <param name="textContent">The text content of the email.</param> /// <param name="templateName">The name of the email template to use (optional).</param> /// <param name="templateData">The data to replace placeholders in the email template (optional).</param> /// <param name="contactListName">The name of the contact list for unsubscribe functionality (optional).</param> /// <returns>The MessageId response from the SendEmail operation.</returns> public async Task<string> SendEmailAsync(string fromEmailAddress, List<string> toEmailAddresses, string? subject, string? htmlContent, string? textContent, string? templateName = null, string? templateData = null, string? contactListName = null) { var request = new SendEmailRequest { FromEmailAddress = fromEmailAddress }; if (toEmailAddresses.Any()) { request.Destination = new Destination { ToAddresses = toEmailAddresses }; } if (!string.IsNullOrEmpty(templateName)) { request.Content = new EmailContent() { Template = new Template { TemplateName = templateName, TemplateData = templateData } }; } else { request.Content = new EmailContent { Simple = new Message { Subject = new Content { Data = subject }, Body = new Body { Html = new Content { Data = htmlContent }, Text = new Content { Data = textContent } } } }; } if (!string.IsNullOrEmpty(contactListName)) { request.ListManagementOptions = new ListManagementOptions { ContactListName = contactListName }; } try { var response = await _sesClient.SendEmailAsync(request); return response.MessageId; } catch (AccountSuspendedException ex) { Console.WriteLine("The account's ability to send email has been permanently restricted."); Console.WriteLine(ex.Message); } catch (MailFromDomainNotVerifiedException ex) { Console.WriteLine("The sending domain is not verified."); Console.WriteLine(ex.Message); } catch (MessageRejectedException ex) { Console.WriteLine("The message content is invalid."); Console.WriteLine(ex.Message); } catch (SendingPausedException ex) { Console.WriteLine("The account's ability to send email is currently paused."); Console.WriteLine(ex.Message); } catch (TooManyRequestsException ex) { Console.WriteLine("Too many requests were made. Please try again later."); Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine($"An error occurred while sending the email: {ex.Message}"); } return string.Empty; } }