diff --git a/sdk/communication/Azure.Communication.Messages/CHANGELOG.md b/sdk/communication/Azure.Communication.Messages/CHANGELOG.md new file mode 100644 index 0000000000000..4d7c16e637566 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/CHANGELOG.md @@ -0,0 +1,10 @@ +# Release History + +## 1.0.0-beta.1 (2023-08-15) + +This is the first Public Preview release of Azure Communication Services for advanced messages. For more information, please see the [README][read_me] and [documentation][documentation]. + +This is a Public Preview version, so breaking changes are possible in subsequent releases as we improve the product. To provide feedback, please submit an issue in our [Azure SDK for .NET GitHub repo](https://github.com/Azure/azure-sdk-for-net/issues). + + +[read_me]: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/communication/Azure.Communication.Messages/README.md diff --git a/sdk/communication/Azure.Communication.Messages/README.md b/sdk/communication/Azure.Communication.Messages/README.md new file mode 100644 index 0000000000000..090d7029c8099 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/README.md @@ -0,0 +1,100 @@ +# Azure Communication Messages client library for .NET + +This package contains a C# SDK for Azure Communication Messages Services. + +[Source code][source] | [Package (NuGet)][package] | [Product documentation][product_docs] + + +## Getting started + +### Install the package +Install the Azure Communication Messages client library for .NET with [NuGet][nuget]: + +```dotnetcli +dotnet add package Azure.Communication.Messages --prerelease +``` + +### Prerequisites +You need an [Azure subscription][azure_sub] and a [Communication Service Resource][communication_resource_docs] to use this package. + +To create a new Communication Service, you can use the [Azure Portal][communication_resource_create_portal], the [Azure PowerShell][communication_resource_create_power_shell], or the [.NET management client library][communication_resource_create_net]. + +### Key concepts +`NotificationMessagesClient` provides the functionality to send notification messages . + +### Using statements +```C# +using Azure.Communication.Messages; +``` + +### Authenticate the client +#### Connection String +Messages clients can be authenticated using the connection string acquired from an Azure Communication Resource in the [Azure Portal][azure_portal]. + +```C# +var connectionString = ""; // Find your Communication Services resource in the Azure portal +NotificationMessagesClient notificationMessagesClient = new NotificationMessagesClient(connectionString); +MessageTemplateClient messageTemplateClient = new MessageTemplateClient(connectionString); +``` + +## Examples +### Send an Notification Message +To send a notification message, call the `SendMessage` or `SendMessageAsync` function from the `NotificationMessagesClient`. + +#### Send a text message +```C# +// Create the recipient list, currently only one recipient is supported +var recipient = new List { "" }; +var options = new SendMessageOptions("", recipient, "Come on everyone, let's go for lunch together."); +SendMessageResult result = await notificationMessagesClient.SendMessageAsync(options); +Console.WriteLine($"Message id: {result.Receipts[0].MessageId}"); +``` + +#### Send a template message +```C# +// Create the recipient list, currently only one recipient is supported +var recipient = new List { "" }; +string templateName = "sample_template"; +string templateLanguage = "en_us"; +var messageTemplate = new MessageTemplate(templateName, templateLanguage); +var sendTemplateMessageOptions = new SendMessageOptions(channelRegistrationId, recipientList, messageTemplate); +SendMessageResult result = await notificationMessagesClient.SendMessageAsync(sendTemplateMessageOptions); +Console.WriteLine($"Message id: {result.Receipts[0].MessageId}"); +``` + +#### Send a media message +```C# +// Create the recipient list, currently only one recipient is supported +var recipient = new List { "" }; +var uri = new Uri("https://aka.ms/acsicon1"); +var sendMediaMessageOptions = new SendMessageOptions(channelRegistrationId, recipientList, uri); +SendMessageResult result = await notificationMessagesClient.SendMessageAsync(sendMediaMessageOptions); +Console.WriteLine($"Message id: {result.Receipts[0].MessageId}"); +``` + +### Retrieve templates +To retrieve templates, call the `GetMessages` or `GetMessagesAsync` function from the `MessageTemplateClient`. + + +```C# +AsyncPageable templates = messageTemplateClient.GetTemplatesAsync(channelId); +await foreach (MessageTemplateItem template in templates) +{ + Console.WriteLine($"{template.Name}"); +} +``` + +## Troubleshooting +A `RequestFailedException` is thrown as a service response for any unsuccessful requests. The exception contains information about what response code was returned from the service. + +## Next steps +- Read more about Messages in Azure Communication Services (Link to be added). +- Read more about how to set up Event Grid subscription for new message and message delivery status (Link to be added). + + +## Contributing +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit [cla.microsoft.com][cla]. + +This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For more information see the [Code of Conduct FAQ][coc_faq] or contact [opencode@microsoft.com][coc_contact] with any additional questions or comments. + + diff --git a/sdk/communication/Azure.Communication.Messages/api/Azure.Communication.Messages.netstandard2.0.cs b/sdk/communication/Azure.Communication.Messages/api/Azure.Communication.Messages.netstandard2.0.cs new file mode 100644 index 0000000000000..da475957b2e2a --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/api/Azure.Communication.Messages.netstandard2.0.cs @@ -0,0 +1,240 @@ +namespace Azure.Communication.Messages +{ + [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] + public readonly partial struct CommunicationMessagesChannelType : System.IEquatable + { + private readonly object _dummy; + private readonly int _dummyPrimitive; + public CommunicationMessagesChannelType(string value) { throw null; } + public static Azure.Communication.Messages.CommunicationMessagesChannelType WhatsApp { get { throw null; } } + public bool Equals(Azure.Communication.Messages.CommunicationMessagesChannelType other) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override bool Equals(object obj) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override int GetHashCode() { throw null; } + public static bool operator ==(Azure.Communication.Messages.CommunicationMessagesChannelType left, Azure.Communication.Messages.CommunicationMessagesChannelType right) { throw null; } + public static implicit operator Azure.Communication.Messages.CommunicationMessagesChannelType (string value) { throw null; } + public static bool operator !=(Azure.Communication.Messages.CommunicationMessagesChannelType left, Azure.Communication.Messages.CommunicationMessagesChannelType right) { throw null; } + public override string ToString() { throw null; } + } + public partial class CommunicationMessagesClientOptions : Azure.Core.ClientOptions + { + public CommunicationMessagesClientOptions(Azure.Communication.Messages.CommunicationMessagesClientOptions.ServiceVersion version = Azure.Communication.Messages.CommunicationMessagesClientOptions.ServiceVersion.V2023_08_24_Preview) { } + public enum ServiceVersion + { + V2023_08_24_Preview = 1, + } + } + public static partial class CommunicationMessagesModelFactory + { + public static Azure.Communication.Messages.MessageReceipt MessageReceipt(string messageId = null, string to = null) { throw null; } + public static Azure.Communication.Messages.SendMessageResult SendMessageResult(System.Collections.Generic.IEnumerable receipts = null) { throw null; } + } + [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] + public readonly partial struct CommunicationMessageType : System.IEquatable + { + private readonly object _dummy; + private readonly int _dummyPrimitive; + public CommunicationMessageType(string value) { throw null; } + public static Azure.Communication.Messages.CommunicationMessageType Image { get { throw null; } } + public static Azure.Communication.Messages.CommunicationMessageType Template { get { throw null; } } + public static Azure.Communication.Messages.CommunicationMessageType Text { get { throw null; } } + public bool Equals(Azure.Communication.Messages.CommunicationMessageType other) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override bool Equals(object obj) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override int GetHashCode() { throw null; } + public static bool operator ==(Azure.Communication.Messages.CommunicationMessageType left, Azure.Communication.Messages.CommunicationMessageType right) { throw null; } + public static implicit operator Azure.Communication.Messages.CommunicationMessageType (string value) { throw null; } + public static bool operator !=(Azure.Communication.Messages.CommunicationMessageType left, Azure.Communication.Messages.CommunicationMessageType right) { throw null; } + public override string ToString() { throw null; } + } + public partial class MessageReceipt + { + internal MessageReceipt() { } + public string MessageId { get { throw null; } } + public string To { get { throw null; } } + } + public partial class MessageTemplate + { + public MessageTemplate(string name, string language, System.Collections.Generic.IEnumerable values = null, Azure.Communication.Messages.MessageTemplateBindings bindings = null) { } + public Azure.Communication.Messages.MessageTemplateBindings Bindings { get { throw null; } } + public string Language { get { throw null; } } + public string Name { get { throw null; } } + public System.Collections.Generic.IEnumerable Values { get { throw null; } } + } + public abstract partial class MessageTemplateBindings + { + public MessageTemplateBindings() { } + internal abstract Azure.Communication.Messages.MessageTemplateBindingsInternal ToMessageTemplateBindingsInternal(); + } + public partial class MessageTemplateClient + { + protected MessageTemplateClient() { } + public MessageTemplateClient(string connectionString) { } + public MessageTemplateClient(string connectionString, Azure.Communication.Messages.CommunicationMessagesClientOptions options) { } + public MessageTemplateClient(System.Uri endpoint, Azure.AzureKeyCredential keyCredential, Azure.Communication.Messages.CommunicationMessagesClientOptions options = null) { } + public virtual Azure.Pageable GetTemplates(string channelRegistrationId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual Azure.AsyncPageable GetTemplatesAsync(string channelRegistrationId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + } + public partial class MessageTemplateDocument : Azure.Communication.Messages.MessageTemplateValue + { + public MessageTemplateDocument(string name, System.Uri uri, string caption = null, string fileName = null) : base (default(string)) { } + public string Caption { get { throw null; } set { } } + public string FileName { get { throw null; } set { } } + public System.Uri Uri { get { throw null; } set { } } + } + public partial class MessageTemplateImage : Azure.Communication.Messages.MessageTemplateValue + { + public MessageTemplateImage(string name, System.Uri uri, string caption = null, string fileName = null) : base (default(string)) { } + public string Caption { get { throw null; } set { } } + public string FileName { get { throw null; } set { } } + public System.Uri Uri { get { throw null; } set { } } + } + public partial class MessageTemplateItem + { + internal MessageTemplateItem() { } + public Azure.Communication.Messages.CommunicationMessagesChannelType? ChannelType { get { throw null; } } + public string Language { get { throw null; } } + public string Name { get { throw null; } } + public Azure.Communication.Messages.TemplateStatus? Status { get { throw null; } } + public Azure.Communication.Messages.MessageTemplateItemWhatsApp WhatsApp { get { throw null; } } + } + public partial class MessageTemplateItemWhatsApp + { + internal MessageTemplateItemWhatsApp() { } + public System.BinaryData Content { get { throw null; } } + } + public partial class MessageTemplateLocation : Azure.Communication.Messages.MessageTemplateValue + { + public MessageTemplateLocation(string name, double latitude, double longitude, string locationName = null, string address = null) : base (default(string)) { } + public string Address { get { throw null; } set { } } + public double Latitude { get { throw null; } set { } } + public string LocationName { get { throw null; } set { } } + public double Longitude { get { throw null; } set { } } + } + public partial class MessageTemplateQuickAction : Azure.Communication.Messages.MessageTemplateValue + { + public MessageTemplateQuickAction(string name, string text = null, string payload = null) : base (default(string)) { } + public string Payload { get { throw null; } set { } } + public string Text { get { throw null; } set { } } + } + public partial class MessageTemplateText : Azure.Communication.Messages.MessageTemplateValue + { + public MessageTemplateText(string name, string text) : base (default(string)) { } + public string Text { get { throw null; } set { } } + } + public abstract partial class MessageTemplateValue + { + public MessageTemplateValue(string name) { } + public string Name { get { throw null; } } + internal abstract Azure.Communication.Messages.MessageTemplateValueInternal ToMessageTemplateValueInternal(); + } + [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] + public readonly partial struct MessageTemplateValueKind : System.IEquatable + { + private readonly object _dummy; + private readonly int _dummyPrimitive; + public MessageTemplateValueKind(string value) { throw null; } + public static Azure.Communication.Messages.MessageTemplateValueKind Document { get { throw null; } } + public static Azure.Communication.Messages.MessageTemplateValueKind Image { get { throw null; } } + public static Azure.Communication.Messages.MessageTemplateValueKind Location { get { throw null; } } + public static Azure.Communication.Messages.MessageTemplateValueKind QuickAction { get { throw null; } } + public static Azure.Communication.Messages.MessageTemplateValueKind Text { get { throw null; } } + public static Azure.Communication.Messages.MessageTemplateValueKind Video { get { throw null; } } + public bool Equals(Azure.Communication.Messages.MessageTemplateValueKind other) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override bool Equals(object obj) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override int GetHashCode() { throw null; } + public static bool operator ==(Azure.Communication.Messages.MessageTemplateValueKind left, Azure.Communication.Messages.MessageTemplateValueKind right) { throw null; } + public static implicit operator Azure.Communication.Messages.MessageTemplateValueKind (string value) { throw null; } + public static bool operator !=(Azure.Communication.Messages.MessageTemplateValueKind left, Azure.Communication.Messages.MessageTemplateValueKind right) { throw null; } + public override string ToString() { throw null; } + } + [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] + public readonly partial struct MessageTemplateValueWhatsAppSubType : System.IEquatable + { + private readonly object _dummy; + private readonly int _dummyPrimitive; + public MessageTemplateValueWhatsAppSubType(string value) { throw null; } + public static Azure.Communication.Messages.MessageTemplateValueWhatsAppSubType QuickReply { get { throw null; } } + public static Azure.Communication.Messages.MessageTemplateValueWhatsAppSubType Url { get { throw null; } } + public bool Equals(Azure.Communication.Messages.MessageTemplateValueWhatsAppSubType other) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override bool Equals(object obj) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override int GetHashCode() { throw null; } + public static bool operator ==(Azure.Communication.Messages.MessageTemplateValueWhatsAppSubType left, Azure.Communication.Messages.MessageTemplateValueWhatsAppSubType right) { throw null; } + public static implicit operator Azure.Communication.Messages.MessageTemplateValueWhatsAppSubType (string value) { throw null; } + public static bool operator !=(Azure.Communication.Messages.MessageTemplateValueWhatsAppSubType left, Azure.Communication.Messages.MessageTemplateValueWhatsAppSubType right) { throw null; } + public override string ToString() { throw null; } + } + public partial class MessageTemplateVideo : Azure.Communication.Messages.MessageTemplateValue + { + public MessageTemplateVideo(string name, System.Uri uri, string caption = null, string fileName = null) : base (default(string)) { } + public string Caption { get { throw null; } set { } } + public string FileName { get { throw null; } set { } } + public System.Uri Uri { get { throw null; } set { } } + } + public partial class MessageTemplateWhatsAppBindings : Azure.Communication.Messages.MessageTemplateBindings + { + public MessageTemplateWhatsAppBindings(System.Collections.Generic.IEnumerable header = null, System.Collections.Generic.IEnumerable body = null, System.Collections.Generic.IEnumerable footer = null, System.Collections.Generic.IEnumerable> button = null) { } + public System.Collections.Generic.IEnumerable Body { get { throw null; } } + public System.Collections.Generic.IEnumerable> Button { get { throw null; } } + public System.Collections.Generic.IEnumerable Footer { get { throw null; } } + public System.Collections.Generic.IEnumerable Header { get { throw null; } } + } + public partial class NotificationMessagesClient + { + protected NotificationMessagesClient() { } + public NotificationMessagesClient(string connectionString) { } + public NotificationMessagesClient(string connectionString, Azure.Communication.Messages.CommunicationMessagesClientOptions options) { } + public NotificationMessagesClient(System.Uri endpoint, Azure.AzureKeyCredential keyCredential, Azure.Communication.Messages.CommunicationMessagesClientOptions options = null) { } + public virtual Azure.Response DownloadMedia(string mediaContentId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual System.Threading.Tasks.Task> DownloadMediaAsync(string mediaContentId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual Azure.Response DownloadMediaTo(string mediaContentId, System.IO.Stream destinationStream, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual Azure.Response DownloadMediaTo(string mediaContentId, string destinationPath, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual System.Threading.Tasks.Task DownloadMediaToAsync(string mediaContentId, System.IO.Stream destinationStream, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual System.Threading.Tasks.Task DownloadMediaToAsync(string mediaContentId, string destinationPath, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual Azure.Response SendMessage(Azure.Communication.Messages.SendMessageOptions options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual System.Threading.Tasks.Task> SendMessageAsync(Azure.Communication.Messages.SendMessageOptions options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + } + public partial class SendMessageOptions + { + public SendMessageOptions(string channelRegistrationId, System.Collections.Generic.IEnumerable to, Azure.Communication.Messages.MessageTemplate template) { } + public SendMessageOptions(string channelRegistrationId, System.Collections.Generic.IEnumerable to, string content) { } + public SendMessageOptions(string channelRegistrationId, System.Collections.Generic.IEnumerable to, System.Uri mediaUri, string content = null) { } + public string ChannelRegistrationId { get { throw null; } } + public string Content { get { throw null; } } + public System.Uri MediaUri { get { throw null; } } + public Azure.Communication.Messages.CommunicationMessageType MessageType { get { throw null; } } + public Azure.Communication.Messages.MessageTemplate Template { get { throw null; } } + public System.Collections.Generic.IEnumerable To { get { throw null; } } + } + public partial class SendMessageResult + { + internal SendMessageResult() { } + public System.Collections.Generic.IReadOnlyList Receipts { get { throw null; } } + } + [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] + public readonly partial struct TemplateStatus : System.IEquatable + { + private readonly object _dummy; + private readonly int _dummyPrimitive; + public TemplateStatus(string value) { throw null; } + public static Azure.Communication.Messages.TemplateStatus Approved { get { throw null; } } + public static Azure.Communication.Messages.TemplateStatus Paused { get { throw null; } } + public static Azure.Communication.Messages.TemplateStatus Pending { get { throw null; } } + public static Azure.Communication.Messages.TemplateStatus Rejected { get { throw null; } } + public bool Equals(Azure.Communication.Messages.TemplateStatus other) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override bool Equals(object obj) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public override int GetHashCode() { throw null; } + public static bool operator ==(Azure.Communication.Messages.TemplateStatus left, Azure.Communication.Messages.TemplateStatus right) { throw null; } + public static implicit operator Azure.Communication.Messages.TemplateStatus (string value) { throw null; } + public static bool operator !=(Azure.Communication.Messages.TemplateStatus left, Azure.Communication.Messages.TemplateStatus right) { throw null; } + public override string ToString() { throw null; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Azure.Communication.Messages.csproj b/sdk/communication/Azure.Communication.Messages/src/Azure.Communication.Messages.csproj new file mode 100644 index 0000000000000..f7d7c5708ae1b --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Azure.Communication.Messages.csproj @@ -0,0 +1,27 @@ + + + + + This client library enables working with the Microsoft Azure Communication Messages service. + + Azure Communication Messages Service + 1.0.0-beta.1 + Microsoft Azure Communication Messages Service;Microsoft;Azure;Azure Communication Service;Azure Communication Messages Service;Messages;Communication + $(RequiredTargetFrameworks) + true + + + + + + + + + + + + + + + + diff --git a/sdk/communication/Azure.Communication.Messages/src/CommunicationMessagesClientOptions.cs b/sdk/communication/Azure.Communication.Messages/src/CommunicationMessagesClientOptions.cs new file mode 100644 index 0000000000000..8207ac74eafbf --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/CommunicationMessagesClientOptions.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// + /// The options for communication and . + /// + public class CommunicationMessagesClientOptions : ClientOptions + { + /// + /// The latest version of the Chat service. + /// + internal const ServiceVersion LatestVersion = ServiceVersion.V2023_08_24_Preview; + + internal string ApiVersion { get; } + + /// + /// Initializes a new instance of the . + /// + public CommunicationMessagesClientOptions(ServiceVersion version = LatestVersion) + { + ApiVersion = version switch + { + ServiceVersion.V2023_08_24_Preview => "2023-08-24-preview", + _ => throw new ArgumentOutOfRangeException(nameof(version)), + }; + } + + /// + /// The Messages service version. + /// + public enum ServiceVersion + { + /// + /// The V1 of the Messages service. + /// + #pragma warning disable CA1707 // Identifiers should not contain underscores + #pragma warning disable AZC0016 // Invalid ServiceVersion member name. + V2023_08_24_Preview = 1 + #pragma warning restore AZC0016 // Invalid ServiceVersion member name. + #pragma warning restore CA1707 // Identifiers should not contain underscores + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/CommunicationMessagesModelFactory.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/CommunicationMessagesModelFactory.cs new file mode 100644 index 0000000000000..e09c9d3b3bae7 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/CommunicationMessagesModelFactory.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.Communication.Messages +{ + /// Model factory for models. + public static partial class CommunicationMessagesModelFactory + { + /// Initializes a new instance of SendMessageResult. + /// Receipts of the send message operation. + /// A new instance for mocking. + public static SendMessageResult SendMessageResult(IEnumerable receipts = null) + { + receipts ??= new List(); + + return new SendMessageResult(receipts?.ToList()); + } + + /// Initializes a new instance of MessageReceipt. + /// The message id. + /// The native external platform user identifier of the recipient. + /// or is null. + /// A new instance for mocking. + public static MessageReceipt MessageReceipt(string messageId = null, string to = null) + { + if (messageId == null) + { + throw new ArgumentNullException(nameof(messageId)); + } + if (to == null) + { + throw new ArgumentNullException(nameof(to)); + } + + return new MessageReceipt(messageId, to); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationError.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationError.Serialization.cs new file mode 100644 index 0000000000000..109ebdd2b6d72 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationError.Serialization.cs @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Collections.Generic; +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class CommunicationError + { + internal static CommunicationError DeserializeCommunicationError(JsonElement element) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string code = default; + string message = default; + Optional target = default; + Optional> details = default; + Optional innererror = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("code"u8)) + { + code = property.Value.GetString(); + continue; + } + if (property.NameEquals("message"u8)) + { + message = property.Value.GetString(); + continue; + } + if (property.NameEquals("target"u8)) + { + target = property.Value.GetString(); + continue; + } + if (property.NameEquals("details"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(DeserializeCommunicationError(item)); + } + details = array; + continue; + } + if (property.NameEquals("innererror"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + innererror = DeserializeCommunicationError(property.Value); + continue; + } + } + return new CommunicationError(code, message, target.Value, Optional.ToList(details), innererror.Value); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationError.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationError.cs new file mode 100644 index 0000000000000..c297fa4129e6b --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationError.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The Communication Services error. + internal partial class CommunicationError + { + /// Initializes a new instance of CommunicationError. + /// The error code. + /// The error message. + /// or is null. + internal CommunicationError(string code, string message) + { + Argument.AssertNotNull(code, nameof(code)); + Argument.AssertNotNull(message, nameof(message)); + + Code = code; + Message = message; + Details = new ChangeTrackingList(); + } + + /// Initializes a new instance of CommunicationError. + /// The error code. + /// The error message. + /// The error target. + /// Further details about specific errors that led to this error. + /// The inner error if any. + internal CommunicationError(string code, string message, string target, IReadOnlyList details, CommunicationError innerError) + { + Code = code; + Message = message; + Target = target; + Details = details; + InnerError = innerError; + } + + /// The error code. + public string Code { get; } + /// The error message. + public string Message { get; } + /// The error target. + public string Target { get; } + /// Further details about specific errors that led to this error. + public IReadOnlyList Details { get; } + /// The inner error if any. + public CommunicationError InnerError { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationErrorResponse.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationErrorResponse.Serialization.cs new file mode 100644 index 0000000000000..e40c439387cf6 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationErrorResponse.Serialization.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; + +namespace Azure.Communication.Messages +{ + internal partial class CommunicationErrorResponse + { + internal static CommunicationErrorResponse DeserializeCommunicationErrorResponse(JsonElement element) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + CommunicationError error = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("error"u8)) + { + error = CommunicationError.DeserializeCommunicationError(property.Value); + continue; + } + } + return new CommunicationErrorResponse(error); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationErrorResponse.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationErrorResponse.cs new file mode 100644 index 0000000000000..c3af707cfcf85 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationErrorResponse.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The Communication Services error. + internal partial class CommunicationErrorResponse + { + /// Initializes a new instance of CommunicationErrorResponse. + /// The Communication Services error. + /// is null. + internal CommunicationErrorResponse(CommunicationError error) + { + Argument.AssertNotNull(error, nameof(error)); + + Error = error; + } + + /// The Communication Services error. + public CommunicationError Error { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationMessageType.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationMessageType.cs new file mode 100644 index 0000000000000..3ed021efa15da --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationMessageType.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.Communication.Messages +{ + /// The type of message. Supports text, image, template. + public readonly partial struct CommunicationMessageType : IEquatable + { + private readonly string _value; + + /// Initializes a new instance of . + /// is null. + public CommunicationMessageType(string value) + { + _value = value ?? throw new ArgumentNullException(nameof(value)); + } + + private const string TextValue = "text"; + private const string ImageValue = "image"; + private const string TemplateValue = "template"; + + /// text. + public static CommunicationMessageType Text { get; } = new CommunicationMessageType(TextValue); + /// image. + public static CommunicationMessageType Image { get; } = new CommunicationMessageType(ImageValue); + /// template. + public static CommunicationMessageType Template { get; } = new CommunicationMessageType(TemplateValue); + /// Determines if two values are the same. + public static bool operator ==(CommunicationMessageType left, CommunicationMessageType right) => left.Equals(right); + /// Determines if two values are not the same. + public static bool operator !=(CommunicationMessageType left, CommunicationMessageType right) => !left.Equals(right); + /// Converts a string to a . + public static implicit operator CommunicationMessageType(string value) => new CommunicationMessageType(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is CommunicationMessageType other && Equals(other); + /// + public bool Equals(CommunicationMessageType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value?.GetHashCode() ?? 0; + /// + public override string ToString() => _value; + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationMessagesChannelType.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationMessagesChannelType.cs new file mode 100644 index 0000000000000..1daf9a3f7c073 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/CommunicationMessagesChannelType.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.Communication.Messages +{ + /// The ChannelType. + public readonly partial struct CommunicationMessagesChannelType : IEquatable + { + private readonly string _value; + + /// Initializes a new instance of . + /// is null. + public CommunicationMessagesChannelType(string value) + { + _value = value ?? throw new ArgumentNullException(nameof(value)); + } + + private const string WhatsAppValue = "whatsApp"; + + /// whatsApp. + public static CommunicationMessagesChannelType WhatsApp { get; } = new CommunicationMessagesChannelType(WhatsAppValue); + /// Determines if two values are the same. + public static bool operator ==(CommunicationMessagesChannelType left, CommunicationMessagesChannelType right) => left.Equals(right); + /// Determines if two values are not the same. + public static bool operator !=(CommunicationMessagesChannelType left, CommunicationMessagesChannelType right) => !left.Equals(right); + /// Converts a string to a . + public static implicit operator CommunicationMessagesChannelType(string value) => new CommunicationMessagesChannelType(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is CommunicationMessagesChannelType other && Equals(other); + /// + public bool Equals(CommunicationMessagesChannelType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value?.GetHashCode() ?? 0; + /// + public override string ToString() => _value; + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/ListTemplatesResponse.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/ListTemplatesResponse.Serialization.cs new file mode 100644 index 0000000000000..8692ecadf8044 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/ListTemplatesResponse.Serialization.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Collections.Generic; +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class ListTemplatesResponse + { + internal static ListTemplatesResponse DeserializeListTemplatesResponse(JsonElement element) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IReadOnlyList value = default; + Optional nextLink = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(TemplateResponseInternal.DeserializeTemplateResponseInternal(item)); + } + value = array; + continue; + } + if (property.NameEquals("nextLink"u8)) + { + nextLink = property.Value.GetString(); + continue; + } + } + return new ListTemplatesResponse(value, nextLink.Value); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/ListTemplatesResponse.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/ListTemplatesResponse.cs new file mode 100644 index 0000000000000..0f3fbe73aa62e --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/ListTemplatesResponse.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The ListTemplatesResponse. + internal partial class ListTemplatesResponse + { + /// Initializes a new instance of ListTemplatesResponse. + /// The collection of elements. + /// is null. + internal ListTemplatesResponse(IEnumerable value) + { + Argument.AssertNotNull(value, nameof(value)); + + Value = value.ToList(); + } + + /// Initializes a new instance of ListTemplatesResponse. + /// The collection of elements. + /// + internal ListTemplatesResponse(IReadOnlyList value, string nextLink) + { + Value = value; + NextLink = nextLink; + } + + /// The collection of elements. + public IReadOnlyList Value { get; } + /// Gets the next link. + public string NextLink { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageReceipt.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageReceipt.Serialization.cs new file mode 100644 index 0000000000000..7addd236cd54c --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageReceipt.Serialization.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; + +namespace Azure.Communication.Messages +{ + public partial class MessageReceipt + { + internal static MessageReceipt DeserializeMessageReceipt(JsonElement element) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string messageId = default; + string to = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("messageId"u8)) + { + messageId = property.Value.GetString(); + continue; + } + if (property.NameEquals("to"u8)) + { + to = property.Value.GetString(); + continue; + } + } + return new MessageReceipt(messageId, to); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageReceipt.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageReceipt.cs new file mode 100644 index 0000000000000..f7b93911259bc --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageReceipt.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// Receipt of the sending one message. + public partial class MessageReceipt + { + /// Initializes a new instance of MessageReceipt. + /// The message id. + /// The native external platform user identifier of the recipient. + /// or is null. + internal MessageReceipt(string messageId, string to) + { + Argument.AssertNotNull(messageId, nameof(messageId)); + Argument.AssertNotNull(to, nameof(to)); + + MessageId = messageId; + To = to; + } + + /// The message id. + public string MessageId { get; } + /// The native external platform user identifier of the recipient. + public string To { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsInternal.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsInternal.Serialization.cs new file mode 100644 index 0000000000000..146ef7888916c --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsInternal.Serialization.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateBindingsInternal : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + if (Optional.IsDefined(WhatsApp)) + { + writer.WritePropertyName("whatsApp"u8); + writer.WriteObjectValue(WhatsApp); + } + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsInternal.cs new file mode 100644 index 0000000000000..a4ffd716f099f --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsInternal.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.Communication.Messages +{ + /// The binding object to link values to the template specific locations. + internal partial class MessageTemplateBindingsInternal + { + /// Initializes a new instance of MessageTemplateBindingsInternal. + public MessageTemplateBindingsInternal() + { + } + + /// The template bindings for WhatsApp. + public MessageTemplateBindingsWhatsApp WhatsApp { get; set; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsApp.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsApp.Serialization.cs new file mode 100644 index 0000000000000..46131cdcd2251 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsApp.Serialization.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateBindingsWhatsApp : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + if (Optional.IsCollectionDefined(Header)) + { + writer.WritePropertyName("header"u8); + writer.WriteStartArray(); + foreach (var item in Header) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(Body)) + { + writer.WritePropertyName("body"u8); + writer.WriteStartArray(); + foreach (var item in Body) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(Footer)) + { + writer.WritePropertyName("footer"u8); + writer.WriteStartArray(); + foreach (var item in Footer) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(Button)) + { + writer.WritePropertyName("button"u8); + writer.WriteStartArray(); + foreach (var item in Button) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsApp.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsApp.cs new file mode 100644 index 0000000000000..b37c76c23d4ab --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsApp.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Collections.Generic; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The template bindings for WhatsApp. + internal partial class MessageTemplateBindingsWhatsApp + { + /// Initializes a new instance of MessageTemplateBindingsWhatsApp. + public MessageTemplateBindingsWhatsApp() + { + Header = new ChangeTrackingList(); + Body = new ChangeTrackingList(); + Footer = new ChangeTrackingList(); + Button = new ChangeTrackingList(); + } + + /// Gets the header. + public IList Header { get; } + /// Gets the body. + public IList Body { get; } + /// Gets the footer. + public IList Footer { get; } + /// Gets the button. + public IList Button { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppButton.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppButton.Serialization.cs new file mode 100644 index 0000000000000..197b0674a0954 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppButton.Serialization.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateBindingsWhatsAppButton : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + if (Optional.IsDefined(SubType)) + { + writer.WritePropertyName("subType"u8); + writer.WriteStringValue(SubType.Value.ToString()); + } + writer.WritePropertyName("refValue"u8); + writer.WriteStringValue(RefValue); + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppButton.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppButton.cs new file mode 100644 index 0000000000000..2b7dc1d93acb8 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppButton.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The template bindings component button for WhatsApp. + internal partial class MessageTemplateBindingsWhatsAppButton + { + /// Initializes a new instance of MessageTemplateBindingsWhatsAppButton. + /// The reference to the value in the Microsoft.Azure.Communication.CrossPlatformMessages.Contract.Model.Notifications.V1.Requests.MessageTemplate.Values dictionary. + /// is null. + public MessageTemplateBindingsWhatsAppButton(string refValue) + { + Argument.AssertNotNull(refValue, nameof(refValue)); + + RefValue = refValue; + } + + /// The WhatsApp button sub type. + public MessageTemplateValueWhatsAppSubType? SubType { get; set; } + /// The reference to the value in the Microsoft.Azure.Communication.CrossPlatformMessages.Contract.Model.Notifications.V1.Requests.MessageTemplate.Values dictionary. + public string RefValue { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppComponent.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppComponent.Serialization.cs new file mode 100644 index 0000000000000..2e7842eaa3ee0 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppComponent.Serialization.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateBindingsWhatsAppComponent : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + writer.WritePropertyName("refValue"u8); + writer.WriteStringValue(RefValue); + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppComponent.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppComponent.cs new file mode 100644 index 0000000000000..6a3cb7239d25d --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateBindingsWhatsAppComponent.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The template bindings component for WhatsApp. + internal partial class MessageTemplateBindingsWhatsAppComponent + { + /// Initializes a new instance of MessageTemplateBindingsWhatsAppComponent. + /// The reference to the value in the Microsoft.Azure.Communication.CrossPlatformMessages.Contract.Model.Notifications.V1.Requests.MessageTemplate.Values dictionary. + /// is null. + public MessageTemplateBindingsWhatsAppComponent(string refValue) + { + Argument.AssertNotNull(refValue, nameof(refValue)); + + RefValue = refValue; + } + + /// The reference to the value in the Microsoft.Azure.Communication.CrossPlatformMessages.Contract.Model.Notifications.V1.Requests.MessageTemplate.Values dictionary. + public string RefValue { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateInternal.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateInternal.Serialization.cs new file mode 100644 index 0000000000000..d0c8b11608d45 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateInternal.Serialization.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateInternal : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + writer.WritePropertyName("language"u8); + writer.WriteStringValue(Language); + if (Optional.IsCollectionDefined(Values)) + { + writer.WritePropertyName("values"u8); + writer.WriteStartObject(); + foreach (var item in Values) + { + writer.WritePropertyName(item.Key); + writer.WriteObjectValue(item.Value); + } + writer.WriteEndObject(); + } + if (Optional.IsDefined(Bindings)) + { + writer.WritePropertyName("bindings"u8); + writer.WriteObjectValue(Bindings); + } + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateInternal.cs new file mode 100644 index 0000000000000..d85831bb3029d --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateInternal.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The template object used to create templates. + internal partial class MessageTemplateInternal + { + /// Initializes a new instance of MessageTemplateInternal. + /// Name of the template. + /// The codes for the supported languages for templates. + /// or is null. + public MessageTemplateInternal(string name, string language) + { + Argument.AssertNotNull(name, nameof(name)); + Argument.AssertNotNull(language, nameof(language)); + + Name = name; + Language = language; + Values = new ChangeTrackingDictionary(); + } + + /// Name of the template. + public string Name { get; } + /// The codes for the supported languages for templates. + public string Language { get; } + /// The template values. + public IDictionary Values { get; } + /// The binding object to link values to the template specific locations. + public MessageTemplateBindingsInternal Bindings { get; set; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateParameterLocation.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateParameterLocation.Serialization.cs new file mode 100644 index 0000000000000..4616d5da431d0 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateParameterLocation.Serialization.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateParameterLocation : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + if (Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (Optional.IsDefined(Address)) + { + writer.WritePropertyName("address"u8); + writer.WriteStringValue(Address); + } + if (Optional.IsDefined(Latitude)) + { + writer.WritePropertyName("latitude"u8); + writer.WriteNumberValue(Latitude.Value); + } + if (Optional.IsDefined(Longitude)) + { + writer.WritePropertyName("longitude"u8); + writer.WriteNumberValue(Longitude.Value); + } + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateParameterLocation.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateParameterLocation.cs new file mode 100644 index 0000000000000..fd5a0ee21d3f6 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateParameterLocation.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.Communication.Messages +{ + /// The message template's location value information. + internal partial class MessageTemplateParameterLocation + { + /// Initializes a new instance of MessageTemplateParameterLocation. + public MessageTemplateParameterLocation() + { + } + + /// The [Optional] name of the location. + public string Name { get; set; } + /// The [Optional] address of the location. + public string Address { get; set; } + /// The latitude of the location. + public double? Latitude { get; set; } + /// The longitude of the location. + public double? Longitude { get; set; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueInternal.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueInternal.Serialization.cs new file mode 100644 index 0000000000000..778655c72a2bb --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueInternal.Serialization.cs @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateValueInternal : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind.ToString()); + if (Optional.IsDefined(Text)) + { + writer.WritePropertyName("text"u8); + writer.WriteObjectValue(Text); + } + if (Optional.IsDefined(Image)) + { + writer.WritePropertyName("image"u8); + writer.WriteObjectValue(Image); + } + if (Optional.IsDefined(Document)) + { + writer.WritePropertyName("document"u8); + writer.WriteObjectValue(Document); + } + if (Optional.IsDefined(Video)) + { + writer.WritePropertyName("video"u8); + writer.WriteObjectValue(Video); + } + if (Optional.IsDefined(Location)) + { + writer.WritePropertyName("location"u8); + writer.WriteObjectValue(Location); + } + if (Optional.IsDefined(QuickAction)) + { + writer.WritePropertyName("quickAction"u8); + writer.WriteObjectValue(QuickAction); + } + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueInternal.cs new file mode 100644 index 0000000000000..3db50db11688f --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueInternal.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.Communication.Messages +{ + /// The class describes a parameter of a template. + internal partial class MessageTemplateValueInternal + { + /// Initializes a new instance of MessageTemplateValueInternal. + /// The template value kind. + public MessageTemplateValueInternal(MessageTemplateValueKind kind) + { + Kind = kind; + } + + /// The template value kind. + public MessageTemplateValueKind Kind { get; } + /// The message template's text value information. + public MessageTemplateValueText Text { get; set; } + /// + /// The message template's media value information. + /// Could be an image, document or video. + /// + public MessageTemplateValueMedia Image { get; set; } + /// + /// The message template's media value information. + /// Could be an image, document or video. + /// + public MessageTemplateValueMedia Document { get; set; } + /// + /// The message template's media value information. + /// Could be an image, document or video. + /// + public MessageTemplateValueMedia Video { get; set; } + /// The message template's location value information. + public MessageTemplateParameterLocation Location { get; set; } + /// The message template's quick action value information. + public MessageTemplateValueQuickAction QuickAction { get; set; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueKind.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueKind.cs new file mode 100644 index 0000000000000..4cdd00266a3c2 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueKind.cs @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.Communication.Messages +{ + /// The template value kind. + public readonly partial struct MessageTemplateValueKind : IEquatable + { + private readonly string _value; + + /// Initializes a new instance of . + /// is null. + public MessageTemplateValueKind(string value) + { + _value = value ?? throw new ArgumentNullException(nameof(value)); + } + + private const string TextValue = "text"; + private const string ImageValue = "image"; + private const string DocumentValue = "document"; + private const string VideoValue = "video"; + private const string LocationValue = "location"; + private const string QuickActionValue = "quick_action"; + + /// text. + public static MessageTemplateValueKind Text { get; } = new MessageTemplateValueKind(TextValue); + /// image. + public static MessageTemplateValueKind Image { get; } = new MessageTemplateValueKind(ImageValue); + /// document. + public static MessageTemplateValueKind Document { get; } = new MessageTemplateValueKind(DocumentValue); + /// video. + public static MessageTemplateValueKind Video { get; } = new MessageTemplateValueKind(VideoValue); + /// location. + public static MessageTemplateValueKind Location { get; } = new MessageTemplateValueKind(LocationValue); + /// quick_action. + public static MessageTemplateValueKind QuickAction { get; } = new MessageTemplateValueKind(QuickActionValue); + /// Determines if two values are the same. + public static bool operator ==(MessageTemplateValueKind left, MessageTemplateValueKind right) => left.Equals(right); + /// Determines if two values are not the same. + public static bool operator !=(MessageTemplateValueKind left, MessageTemplateValueKind right) => !left.Equals(right); + /// Converts a string to a . + public static implicit operator MessageTemplateValueKind(string value) => new MessageTemplateValueKind(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is MessageTemplateValueKind other && Equals(other); + /// + public bool Equals(MessageTemplateValueKind other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value?.GetHashCode() ?? 0; + /// + public override string ToString() => _value; + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueMedia.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueMedia.Serialization.cs new file mode 100644 index 0000000000000..a92f825758df0 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueMedia.Serialization.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateValueMedia : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + if (Optional.IsDefined(Url)) + { + writer.WritePropertyName("url"u8); + writer.WriteStringValue(Url.AbsoluteUri); + } + if (Optional.IsDefined(Caption)) + { + writer.WritePropertyName("caption"u8); + writer.WriteStringValue(Caption); + } + if (Optional.IsDefined(FileName)) + { + writer.WritePropertyName("fileName"u8); + writer.WriteStringValue(FileName); + } + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueMedia.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueMedia.cs new file mode 100644 index 0000000000000..f1c94c5f871a2 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueMedia.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.Communication.Messages +{ + /// + /// The message template's media value information. + /// Could be an image, document or video. + /// + internal partial class MessageTemplateValueMedia + { + /// Initializes a new instance of MessageTemplateValueMedia. + public MessageTemplateValueMedia() + { + } + + /// The (public) URL of the media. + public Uri Url { get; set; } + /// The [optional] caption of the media object. + public string Caption { get; set; } + /// The [optional] filename of the media file. + public string FileName { get; set; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueQuickAction.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueQuickAction.Serialization.cs new file mode 100644 index 0000000000000..f4fcf42c2dce3 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueQuickAction.Serialization.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateValueQuickAction : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + if (Optional.IsDefined(Text)) + { + writer.WritePropertyName("text"u8); + writer.WriteStringValue(Text); + } + if (Optional.IsDefined(Payload)) + { + writer.WritePropertyName("payload"u8); + writer.WriteStringValue(Payload); + } + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueQuickAction.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueQuickAction.cs new file mode 100644 index 0000000000000..8f23763d9c7e7 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueQuickAction.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.Communication.Messages +{ + /// The message template's quick action value information. + internal partial class MessageTemplateValueQuickAction + { + /// Initializes a new instance of MessageTemplateValueQuickAction. + public MessageTemplateValueQuickAction() + { + } + + /// The [Optional] quick action text. + public string Text { get; set; } + /// The [Optional] quick action payload. + public string Payload { get; set; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueText.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueText.Serialization.cs new file mode 100644 index 0000000000000..cdf6e2c4e0fd8 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueText.Serialization.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class MessageTemplateValueText : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + writer.WritePropertyName("text"u8); + writer.WriteStringValue(Text); + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueText.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueText.cs new file mode 100644 index 0000000000000..99e7f08adc44e --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueText.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The message template's text value information. + internal partial class MessageTemplateValueText + { + /// Initializes a new instance of MessageTemplateValueText. + /// The text value. + /// is null. + public MessageTemplateValueText(string text) + { + Argument.AssertNotNull(text, nameof(text)); + + Text = text; + } + + /// The text value. + public string Text { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueWhatsAppSubType.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueWhatsAppSubType.cs new file mode 100644 index 0000000000000..ec18bec255dd5 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/MessageTemplateValueWhatsAppSubType.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.Communication.Messages +{ + /// The WhatsApp button sub type. + public readonly partial struct MessageTemplateValueWhatsAppSubType : IEquatable + { + private readonly string _value; + + /// Initializes a new instance of . + /// is null. + public MessageTemplateValueWhatsAppSubType(string value) + { + _value = value ?? throw new ArgumentNullException(nameof(value)); + } + + private const string QuickReplyValue = "quickReply"; + private const string UrlValue = "url"; + + /// quickReply. + public static MessageTemplateValueWhatsAppSubType QuickReply { get; } = new MessageTemplateValueWhatsAppSubType(QuickReplyValue); + /// url. + public static MessageTemplateValueWhatsAppSubType Url { get; } = new MessageTemplateValueWhatsAppSubType(UrlValue); + /// Determines if two values are the same. + public static bool operator ==(MessageTemplateValueWhatsAppSubType left, MessageTemplateValueWhatsAppSubType right) => left.Equals(right); + /// Determines if two values are not the same. + public static bool operator !=(MessageTemplateValueWhatsAppSubType left, MessageTemplateValueWhatsAppSubType right) => !left.Equals(right); + /// Converts a string to a . + public static implicit operator MessageTemplateValueWhatsAppSubType(string value) => new MessageTemplateValueWhatsAppSubType(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is MessageTemplateValueWhatsAppSubType other && Equals(other); + /// + public bool Equals(MessageTemplateValueWhatsAppSubType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value?.GetHashCode() ?? 0; + /// + public override string ToString() => _value; + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendMessageResult.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendMessageResult.Serialization.cs new file mode 100644 index 0000000000000..e9c3af81261c6 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendMessageResult.Serialization.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.Communication.Messages +{ + public partial class SendMessageResult + { + internal static SendMessageResult DeserializeSendMessageResult(JsonElement element) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IReadOnlyList receipts = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("receipts"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(MessageReceipt.DeserializeMessageReceipt(item)); + } + receipts = array; + continue; + } + } + return new SendMessageResult(receipts); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendMessageResult.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendMessageResult.cs new file mode 100644 index 0000000000000..ad8023f9333cc --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendMessageResult.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// Result of the send message operation. + public partial class SendMessageResult + { + /// Initializes a new instance of SendMessageResult. + /// Receipts of the send message operation. + /// is null. + internal SendMessageResult(IEnumerable receipts) + { + Argument.AssertNotNull(receipts, nameof(receipts)); + + Receipts = receipts.ToList(); + } + + /// Initializes a new instance of SendMessageResult. + /// Receipts of the send message operation. + internal SendMessageResult(IReadOnlyList receipts) + { + Receipts = receipts; + } + + /// Receipts of the send message operation. + public IReadOnlyList Receipts { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendNotificationRequest.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendNotificationRequest.Serialization.cs new file mode 100644 index 0000000000000..bcc9181640b5a --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendNotificationRequest.Serialization.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class SendNotificationRequest : IUtf8JsonSerializable + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + { + writer.WriteStartObject(); + writer.WritePropertyName("channelRegistrationId"u8); + writer.WriteStringValue(ChannelRegistrationId); + writer.WritePropertyName("to"u8); + writer.WriteStartArray(); + foreach (var item in To) + { + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + if (Optional.IsDefined(Content)) + { + writer.WritePropertyName("content"u8); + writer.WriteStringValue(Content); + } + if (Optional.IsDefined(MediaUri)) + { + writer.WritePropertyName("mediaUri"u8); + writer.WriteStringValue(MediaUri); + } + if (Optional.IsDefined(Template)) + { + writer.WritePropertyName("template"u8); + writer.WriteObjectValue(Template); + } + writer.WriteEndObject(); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendNotificationRequest.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendNotificationRequest.cs new file mode 100644 index 0000000000000..0fceff2f24608 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/SendNotificationRequest.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// Details of the message to send. + internal partial class SendNotificationRequest + { + /// Initializes a new instance of SendNotificationRequest. + /// The Channel Registration ID for the Business Identifier. + /// The native external platform user identifiers of the recipient. + /// The type of message. Supports text, image, template. + /// or is null. + public SendNotificationRequest(string channelRegistrationId, IEnumerable to, CommunicationMessageType type) + { + Argument.AssertNotNull(channelRegistrationId, nameof(channelRegistrationId)); + Argument.AssertNotNull(to, nameof(to)); + + ChannelRegistrationId = channelRegistrationId; + To = to.ToList(); + Type = type; + } + + /// The Channel Registration ID for the Business Identifier. + public string ChannelRegistrationId { get; } + /// The native external platform user identifiers of the recipient. + public IList To { get; } + /// The type of message. Supports text, image, template. + public CommunicationMessageType Type { get; } + /// Message content. + public string Content { get; set; } + /// A media url for the file. Required if the type is one of the supported media types, e.g. image. + public string MediaUri { get; set; } + /// The template object used to create templates. + public MessageTemplateInternal Template { get; set; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseInternal.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseInternal.Serialization.cs new file mode 100644 index 0000000000000..5723ad4855160 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseInternal.Serialization.cs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class TemplateResponseInternal + { + internal static TemplateResponseInternal DeserializeTemplateResponseInternal(JsonElement element) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional name = default; + Optional language = default; + Optional channelType = default; + Optional status = default; + Optional whatsApp = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("name"u8)) + { + name = property.Value.GetString(); + continue; + } + if (property.NameEquals("language"u8)) + { + language = property.Value.GetString(); + continue; + } + if (property.NameEquals("channelType"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + channelType = new CommunicationMessagesChannelType(property.Value.GetString()); + continue; + } + if (property.NameEquals("status"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + status = new TemplateStatus(property.Value.GetString()); + continue; + } + if (property.NameEquals("whatsApp"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + whatsApp = TemplateResponseWhatsAppInternal.DeserializeTemplateResponseWhatsAppInternal(property.Value); + continue; + } + } + return new TemplateResponseInternal(name.Value, language.Value, Optional.ToNullable(channelType), Optional.ToNullable(status), whatsApp.Value); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseInternal.cs new file mode 100644 index 0000000000000..2dece9fb1cfb2 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseInternal.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.Communication.Messages +{ + /// The TemplateResponse. + internal partial class TemplateResponseInternal + { + /// Initializes a new instance of TemplateResponseInternal. + internal TemplateResponseInternal() + { + } + + /// Initializes a new instance of TemplateResponseInternal. + /// Get the template's Name. + /// Get the template's language. + /// + /// The aggregated template status. + /// The WhatsApp-specific template response contract. + internal TemplateResponseInternal(string name, string language, CommunicationMessagesChannelType? channelType, TemplateStatus? status, TemplateResponseWhatsAppInternal whatsApp) + { + Name = name; + Language = language; + ChannelType = channelType; + Status = status; + WhatsApp = whatsApp; + } + + /// Get the template's Name. + public string Name { get; } + /// Get the template's language. + public string Language { get; } + /// Gets the channel type. + public CommunicationMessagesChannelType? ChannelType { get; } + /// The aggregated template status. + public TemplateStatus? Status { get; } + /// The WhatsApp-specific template response contract. + public TemplateResponseWhatsAppInternal WhatsApp { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseWhatsAppInternal.Serialization.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseWhatsAppInternal.Serialization.cs new file mode 100644 index 0000000000000..fd8cf5c3ebffa --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseWhatsAppInternal.Serialization.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Text.Json; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + internal partial class TemplateResponseWhatsAppInternal + { + internal static TemplateResponseWhatsAppInternal DeserializeTemplateResponseWhatsAppInternal(JsonElement element) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional content = default; + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("content"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + content = property.Value.GetObject(); + continue; + } + } + return new TemplateResponseWhatsAppInternal(content.Value); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseWhatsAppInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseWhatsAppInternal.cs new file mode 100644 index 0000000000000..88b0a97833819 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateResponseWhatsAppInternal.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.Communication.Messages +{ + /// The WhatsApp-specific template response contract. + internal partial class TemplateResponseWhatsAppInternal + { + /// Initializes a new instance of TemplateResponseWhatsAppInternal. + internal TemplateResponseWhatsAppInternal() + { + } + + /// Initializes a new instance of TemplateResponseWhatsAppInternal. + /// + /// WhatsApp platform's template content + /// This is the payload returned from WhatsApp API. + /// + internal TemplateResponseWhatsAppInternal(object content) + { + Content = content; + } + + /// + /// WhatsApp platform's template content + /// This is the payload returned from WhatsApp API. + /// + public object Content { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateStatus.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateStatus.cs new file mode 100644 index 0000000000000..fb01fda63cf84 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/Models/TemplateStatus.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.Communication.Messages +{ + /// The aggregated template status. + public readonly partial struct TemplateStatus : IEquatable + { + private readonly string _value; + + /// Initializes a new instance of . + /// is null. + public TemplateStatus(string value) + { + _value = value ?? throw new ArgumentNullException(nameof(value)); + } + + private const string ApprovedValue = "approved"; + private const string RejectedValue = "rejected"; + private const string PendingValue = "pending"; + private const string PausedValue = "paused"; + + /// approved. + public static TemplateStatus Approved { get; } = new TemplateStatus(ApprovedValue); + /// rejected. + public static TemplateStatus Rejected { get; } = new TemplateStatus(RejectedValue); + /// pending. + public static TemplateStatus Pending { get; } = new TemplateStatus(PendingValue); + /// paused. + public static TemplateStatus Paused { get; } = new TemplateStatus(PausedValue); + /// Determines if two values are the same. + public static bool operator ==(TemplateStatus left, TemplateStatus right) => left.Equals(right); + /// Determines if two values are not the same. + public static bool operator !=(TemplateStatus left, TemplateStatus right) => !left.Equals(right); + /// Converts a string to a . + public static implicit operator TemplateStatus(string value) => new TemplateStatus(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is TemplateStatus other && Equals(other); + /// + public bool Equals(TemplateStatus other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value?.GetHashCode() ?? 0; + /// + public override string ToString() => _value; + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/NotificationMessagesRestClient.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/NotificationMessagesRestClient.cs new file mode 100644 index 0000000000000..ddf5bdefa29ed --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/NotificationMessagesRestClient.cs @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.Communication.Messages +{ + internal partial class NotificationMessagesRestClient + { + private readonly HttpPipeline _pipeline; + private readonly Uri _endpoint; + private readonly string _apiVersion; + + /// The ClientDiagnostics is used to provide tracing support for the client library. + internal ClientDiagnostics ClientDiagnostics { get; } + + /// Initializes a new instance of NotificationMessagesRestClient. + /// The handler for diagnostic messaging in the client. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// The communication resource, for example https://my-resource.communication.azure.com. + /// Api Version. + /// , , or is null. + public NotificationMessagesRestClient(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, Uri endpoint, string apiVersion = "2023-08-24-preview") + { + ClientDiagnostics = clientDiagnostics ?? throw new ArgumentNullException(nameof(clientDiagnostics)); + _pipeline = pipeline ?? throw new ArgumentNullException(nameof(pipeline)); + _endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint)); + _apiVersion = apiVersion ?? throw new ArgumentNullException(nameof(apiVersion)); + } + + internal HttpMessage CreateSendMessageRequest(string channelRegistrationId, IEnumerable to, CommunicationMessageType type, string content, string mediaUri, MessageTemplateInternal template) + { + var message = _pipeline.CreateMessage(); + var request = message.Request; + request.Method = RequestMethod.Post; + var uri = new RawRequestUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/messages/notifications/:send", false); + uri.AppendQuery("api-version", _apiVersion, true); + request.Uri = uri; + request.Headers.Add("Accept", "application/json"); + request.Headers.Add("Content-Type", "application/json"); + var model = new SendNotificationRequest(channelRegistrationId, to.ToList(), type) + { + Content = content, + MediaUri = mediaUri, + Template = template + }; + var content0 = new Utf8JsonRequestContent(); + content0.JsonWriter.WriteObjectValue(model); + request.Content = content0; + return message; + } + + /// The Channel Registration ID for the Business Identifier. + /// The native external platform user identifiers of the recipient. + /// The type of message. Supports text, image, template. + /// Message content. + /// A media url for the file. Required if the type is one of the supported media types, e.g. image. + /// The template object used to create templates. + /// The cancellation token to use. + /// or is null. + public async Task> SendMessageAsync(string channelRegistrationId, IEnumerable to, CommunicationMessageType type, string content = null, string mediaUri = null, MessageTemplateInternal template = null, CancellationToken cancellationToken = default) + { + if (channelRegistrationId == null) + { + throw new ArgumentNullException(nameof(channelRegistrationId)); + } + if (to == null) + { + throw new ArgumentNullException(nameof(to)); + } + + using var message = CreateSendMessageRequest(channelRegistrationId, to, type, content, mediaUri, template); + await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false); + switch (message.Response.Status) + { + case 202: + { + SendMessageResult value = default; + using var document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false); + value = SendMessageResult.DeserializeSendMessageResult(document.RootElement); + return Response.FromValue(value, message.Response); + } + default: + throw new RequestFailedException(message.Response); + } + } + + /// The Channel Registration ID for the Business Identifier. + /// The native external platform user identifiers of the recipient. + /// The type of message. Supports text, image, template. + /// Message content. + /// A media url for the file. Required if the type is one of the supported media types, e.g. image. + /// The template object used to create templates. + /// The cancellation token to use. + /// or is null. + public Response SendMessage(string channelRegistrationId, IEnumerable to, CommunicationMessageType type, string content = null, string mediaUri = null, MessageTemplateInternal template = null, CancellationToken cancellationToken = default) + { + if (channelRegistrationId == null) + { + throw new ArgumentNullException(nameof(channelRegistrationId)); + } + if (to == null) + { + throw new ArgumentNullException(nameof(to)); + } + + using var message = CreateSendMessageRequest(channelRegistrationId, to, type, content, mediaUri, template); + _pipeline.Send(message, cancellationToken); + switch (message.Response.Status) + { + case 202: + { + SendMessageResult value = default; + using var document = JsonDocument.Parse(message.Response.ContentStream); + value = SendMessageResult.DeserializeSendMessageResult(document.RootElement); + return Response.FromValue(value, message.Response); + } + default: + throw new RequestFailedException(message.Response); + } + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/StreamRestClient.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/StreamRestClient.cs new file mode 100644 index 0000000000000..d42b1c26eb7fb --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/StreamRestClient.cs @@ -0,0 +1,107 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.Communication.Messages +{ + internal partial class StreamRestClient + { + private readonly HttpPipeline _pipeline; + private readonly Uri _endpoint; + private readonly string _apiVersion; + + /// The ClientDiagnostics is used to provide tracing support for the client library. + internal ClientDiagnostics ClientDiagnostics { get; } + + /// Initializes a new instance of StreamRestClient. + /// The handler for diagnostic messaging in the client. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// The communication resource, for example https://my-resource.communication.azure.com. + /// Api Version. + /// , , or is null. + public StreamRestClient(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, Uri endpoint, string apiVersion = "2023-08-24-preview") + { + ClientDiagnostics = clientDiagnostics ?? throw new ArgumentNullException(nameof(clientDiagnostics)); + _pipeline = pipeline ?? throw new ArgumentNullException(nameof(pipeline)); + _endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint)); + _apiVersion = apiVersion ?? throw new ArgumentNullException(nameof(apiVersion)); + } + + internal HttpMessage CreateDownloadMediaRequest(string id) + { + var message = _pipeline.CreateMessage(); + var request = message.Request; + message.BufferResponse = false; + request.Method = RequestMethod.Get; + var uri = new RawRequestUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/messages/streams/", false); + uri.AppendPath(id, true); + uri.AppendQuery("api-version", _apiVersion, true); + request.Uri = uri; + request.Headers.Add("Accept", "application/json"); + return message; + } + + /// Download the Media payload from a User to Business message. + /// The Media Identifier contained in the User to Business message event. + /// The cancellation token to use. + /// is null. + public async Task> DownloadMediaAsync(string id, CancellationToken cancellationToken = default) + { + if (id == null) + { + throw new ArgumentNullException(nameof(id)); + } + + using var message = CreateDownloadMediaRequest(id); + await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false); + switch (message.Response.Status) + { + case 200: + { + var value = message.ExtractResponseContent(); + return Response.FromValue(value, message.Response); + } + default: + throw new RequestFailedException(message.Response); + } + } + + /// Download the Media payload from a User to Business message. + /// The Media Identifier contained in the User to Business message event. + /// The cancellation token to use. + /// is null. + public Response DownloadMedia(string id, CancellationToken cancellationToken = default) + { + if (id == null) + { + throw new ArgumentNullException(nameof(id)); + } + + using var message = CreateDownloadMediaRequest(id); + _pipeline.Send(message, cancellationToken); + switch (message.Response.Status) + { + case 200: + { + var value = message.ExtractResponseContent(); + return Response.FromValue(value, message.Response); + } + default: + throw new RequestFailedException(message.Response); + } + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Generated/TemplateV2RestClient.cs b/sdk/communication/Azure.Communication.Messages/src/Generated/TemplateV2RestClient.cs new file mode 100644 index 0000000000000..bb42713c2f8cb --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Generated/TemplateV2RestClient.cs @@ -0,0 +1,176 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.Communication.Messages +{ + internal partial class TemplateV2RestClient + { + private readonly HttpPipeline _pipeline; + private readonly Uri _endpoint; + private readonly string _apiVersion; + + /// The ClientDiagnostics is used to provide tracing support for the client library. + internal ClientDiagnostics ClientDiagnostics { get; } + + /// Initializes a new instance of TemplateV2RestClient. + /// The handler for diagnostic messaging in the client. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// The communication resource, for example https://my-resource.communication.azure.com. + /// Api Version. + /// , , or is null. + public TemplateV2RestClient(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, Uri endpoint, string apiVersion = "2023-08-24-preview") + { + ClientDiagnostics = clientDiagnostics ?? throw new ArgumentNullException(nameof(clientDiagnostics)); + _pipeline = pipeline ?? throw new ArgumentNullException(nameof(pipeline)); + _endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint)); + _apiVersion = apiVersion ?? throw new ArgumentNullException(nameof(apiVersion)); + } + + internal HttpMessage CreateListRequest(Guid channelId, int? maxPageSize) + { + var message = _pipeline.CreateMessage(); + var request = message.Request; + request.Method = RequestMethod.Get; + var uri = new RawRequestUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/messages/channels/", false); + uri.AppendPath(channelId, true); + uri.AppendPath("/templates", false); + if (maxPageSize != null) + { + uri.AppendQuery("maxPageSize", maxPageSize.Value, true); + } + uri.AppendQuery("api-version", _apiVersion, true); + request.Uri = uri; + request.Headers.Add("Accept", "application/json"); + return message; + } + + /// List all templates for given ACS channel. + /// The Guid to use. + /// The Int32 to use. + /// The cancellation token to use. + public async Task> ListAsync(Guid channelId, int? maxPageSize = null, CancellationToken cancellationToken = default) + { + using var message = CreateListRequest(channelId, maxPageSize); + await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false); + switch (message.Response.Status) + { + case 200: + { + ListTemplatesResponse value = default; + using var document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false); + value = ListTemplatesResponse.DeserializeListTemplatesResponse(document.RootElement); + return Response.FromValue(value, message.Response); + } + default: + throw new RequestFailedException(message.Response); + } + } + + /// List all templates for given ACS channel. + /// The Guid to use. + /// The Int32 to use. + /// The cancellation token to use. + public Response List(Guid channelId, int? maxPageSize = null, CancellationToken cancellationToken = default) + { + using var message = CreateListRequest(channelId, maxPageSize); + _pipeline.Send(message, cancellationToken); + switch (message.Response.Status) + { + case 200: + { + ListTemplatesResponse value = default; + using var document = JsonDocument.Parse(message.Response.ContentStream); + value = ListTemplatesResponse.DeserializeListTemplatesResponse(document.RootElement); + return Response.FromValue(value, message.Response); + } + default: + throw new RequestFailedException(message.Response); + } + } + + internal HttpMessage CreateListNextPageRequest(string nextLink, Guid channelId, int? maxPageSize) + { + var message = _pipeline.CreateMessage(); + var request = message.Request; + request.Method = RequestMethod.Get; + var uri = new RawRequestUriBuilder(); + uri.Reset(_endpoint); + uri.AppendRawNextLink(nextLink, false); + request.Uri = uri; + request.Headers.Add("Accept", "application/json"); + return message; + } + + /// List all templates for given ACS channel. + /// The URL to the next page of results. + /// The Guid to use. + /// The Int32 to use. + /// The cancellation token to use. + /// is null. + public async Task> ListNextPageAsync(string nextLink, Guid channelId, int? maxPageSize = null, CancellationToken cancellationToken = default) + { + if (nextLink == null) + { + throw new ArgumentNullException(nameof(nextLink)); + } + + using var message = CreateListNextPageRequest(nextLink, channelId, maxPageSize); + await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false); + switch (message.Response.Status) + { + case 200: + { + ListTemplatesResponse value = default; + using var document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false); + value = ListTemplatesResponse.DeserializeListTemplatesResponse(document.RootElement); + return Response.FromValue(value, message.Response); + } + default: + throw new RequestFailedException(message.Response); + } + } + + /// List all templates for given ACS channel. + /// The URL to the next page of results. + /// The Guid to use. + /// The Int32 to use. + /// The cancellation token to use. + /// is null. + public Response ListNextPage(string nextLink, Guid channelId, int? maxPageSize = null, CancellationToken cancellationToken = default) + { + if (nextLink == null) + { + throw new ArgumentNullException(nameof(nextLink)); + } + + using var message = CreateListNextPageRequest(nextLink, channelId, maxPageSize); + _pipeline.Send(message, cancellationToken); + switch (message.Response.Status) + { + case 200: + { + ListTemplatesResponse value = default; + using var document = JsonDocument.Parse(message.Response.ContentStream); + value = ListTemplatesResponse.DeserializeListTemplatesResponse(document.RootElement); + return Response.FromValue(value, message.Response); + } + default: + throw new RequestFailedException(message.Response); + } + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/MessageTemplateClient.cs b/sdk/communication/Azure.Communication.Messages/src/MessageTemplateClient.cs new file mode 100644 index 0000000000000..02772bc587064 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/MessageTemplateClient.cs @@ -0,0 +1,194 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Azure.Communication.Pipeline; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.Communication.Messages +{ + /// + /// The Azure Communication Services Message Template client. + /// + public class MessageTemplateClient + { + private readonly ClientDiagnostics _clientDiagnostics; + private readonly TemplateV2RestClient _templateV2RestClient; + private readonly StreamRestClient _streamRestClient; + + #region public constructors + + /// + /// Initializes a new instance of + /// + /// Connection string acquired from the Azure Communication Services resource. + public MessageTemplateClient(string connectionString) + : this( + ConnectionString.Parse(Argument.CheckNotNullOrEmpty(connectionString, nameof(connectionString))), + new CommunicationMessagesClientOptions()) + { + } + + /// Initializes a new instance of . + /// Connection string acquired from the Azure Communication Services resource. + /// Client options exposing , , , etc. + public MessageTemplateClient(string connectionString, CommunicationMessagesClientOptions options) + : this( + ConnectionString.Parse(Argument.CheckNotNullOrEmpty(connectionString, nameof(connectionString))), + options ?? new CommunicationMessagesClientOptions()) + { + } + + /// Initializes a new instance of . + /// The URI of the Azure Communication Services resource. + /// The used to authenticate requests. + /// Client options exposing , , , etc. + public MessageTemplateClient(Uri endpoint, AzureKeyCredential keyCredential, CommunicationMessagesClientOptions options = default) + : this( + Argument.CheckNotNull(endpoint, nameof(endpoint)).AbsoluteUri, + Argument.CheckNotNull(keyCredential, nameof(keyCredential)), + options ?? new CommunicationMessagesClientOptions()) + { + } + + #endregion + + #region private constructors + private MessageTemplateClient(ConnectionString connectionString, CommunicationMessagesClientOptions options) + : this(new Uri(connectionString.GetRequired("endpoint")), options.BuildHttpPipeline(connectionString), options) + { } + + private MessageTemplateClient(string endpoint, TokenCredential tokenCredential, CommunicationMessagesClientOptions options) + : this(new Uri(endpoint), options.BuildHttpPipeline(tokenCredential), options) + { } + + private MessageTemplateClient(string endpoint, AzureKeyCredential keyCredential, CommunicationMessagesClientOptions options) + : this(new Uri(endpoint), options.BuildHttpPipeline(keyCredential), options) + { } + + private MessageTemplateClient(Uri endpoint, HttpPipeline httpPipeline, CommunicationMessagesClientOptions options) + { + _clientDiagnostics = new ClientDiagnostics(options); + _templateV2RestClient = new TemplateV2RestClient(_clientDiagnostics, httpPipeline, endpoint, options.ApiVersion); + _streamRestClient = new StreamRestClient(_clientDiagnostics, httpPipeline, endpoint, options.ApiVersion); + } + + #endregion + + /// Initializes a new instance of for mocking. + protected MessageTemplateClient() + { + _clientDiagnostics = null!; + _templateV2RestClient = null!; + _streamRestClient = null!; + } + + #region List Templates Operations + /// List all templates for given ACS channel asynchronously. + /// The registration ID of the channel. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual AsyncPageable GetTemplatesAsync(string channelRegistrationId, CancellationToken cancellationToken = default) + { + _ = channelRegistrationId ?? throw new ArgumentNullException(nameof(channelRegistrationId)); + + async Task> FirstPageFunc(int? pageSizeHint) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MessageTemplateClient)}.{nameof(GetTemplates)}"); + scope.Start(); + + try + { + Response response = await _templateV2RestClient.ListAsync(new Guid(channelRegistrationId), pageSizeHint, cancellationToken).ConfigureAwait(false); + return Page.FromValues(response.Value.Value.Select(x => new MessageTemplateItem(x)), response.Value.NextLink, response.GetRawResponse()); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + async Task> NextPageFunc(string nextLink, int? pageSizeHint) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MessageTemplateClient)}.{nameof(GetTemplates)}"); + scope.Start(); + + try + { + Response response = await _templateV2RestClient.ListNextPageAsync(nextLink, new Guid(channelRegistrationId), pageSizeHint, cancellationToken).ConfigureAwait(false); + if (response.Value.Value == null || response.Value.Value.Count == 0) + { + return Page.FromValues(new List(), null, response.GetRawResponse()); + } + return Page.FromValues(response.Value.Value.Select(x => new MessageTemplateItem(x)), response.Value.NextLink, response.GetRawResponse()); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + return PageableHelpers.CreateAsyncEnumerable(FirstPageFunc, NextPageFunc); + } + + /// List all templates for given ACS channel. + /// The registration ID of the channel. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual Pageable GetTemplates(string channelRegistrationId, CancellationToken cancellationToken = default) + { + _ = channelRegistrationId ?? throw new ArgumentNullException(nameof(channelRegistrationId)); + + Page FirstPageFunc(int? pageSizeHint) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MessageTemplateClient)}.{nameof(GetTemplates)}"); + scope.Start(); + + try + { + Response response = _templateV2RestClient.List(new Guid(channelRegistrationId), pageSizeHint, cancellationToken); + return Page.FromValues(response.Value.Value.Select(x=> new MessageTemplateItem(x)), response.Value.NextLink, response.GetRawResponse()); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + Page NextPageFunc(string nextLink, int? pageSizeHint) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MessageTemplateClient)}.{nameof(GetTemplates)}"); + scope.Start(); + + try + { + Response response = _templateV2RestClient.ListNextPage(nextLink, new Guid(channelRegistrationId), pageSizeHint, cancellationToken); + if (response.Value.Value == null || response.Value.Value.Count == 0) + { + return Page.FromValues(new List(), null, response.GetRawResponse()); + } + return Page.FromValues(response.Value.Value.Select(x => new MessageTemplateItem(x)), response.Value.NextLink, response.GetRawResponse()); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + return PageableHelpers.CreateEnumerable(FirstPageFunc, NextPageFunc); + } + #endregion + + private static HttpPipeline CreatePipelineFromOptions(ConnectionString connectionString, CommunicationMessagesClientOptions options) + { + return options.BuildHttpPipeline(connectionString); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/CommunicationMessagesChannelType.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/CommunicationMessagesChannelType.cs new file mode 100644 index 0000000000000..78cc2eb8cb14a --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/CommunicationMessagesChannelType.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The ChannelType. + [CodeGenModel("ChannelType")] + public partial struct CommunicationMessagesChannelType + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsInternal.cs new file mode 100644 index 0000000000000..11e41a720be50 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsInternal.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplateBindings")] + internal partial class MessageTemplateBindingsInternal + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsWhatsApp.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsWhatsApp.cs new file mode 100644 index 0000000000000..7b02e29ff0baa --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsWhatsApp.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplateBindingsWhatsApp")] + internal partial class MessageTemplateBindingsWhatsApp + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsWhatsAppButton.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsWhatsAppButton.cs new file mode 100644 index 0000000000000..6ff65e06860c4 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsWhatsAppButton.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplateBindingsWhatsAppButton")] + internal partial class MessageTemplateBindingsWhatsAppButton + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsWhatsAppComponent.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsWhatsAppComponent.cs new file mode 100644 index 0000000000000..c11efc8c5ed20 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateBindingsWhatsAppComponent.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplateBindingsWhatsAppComponent")] + internal partial class MessageTemplateBindingsWhatsAppComponent + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateInternal.cs new file mode 100644 index 0000000000000..199b8d9880278 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateInternal.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplate")] + internal partial class MessageTemplateInternal + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateParameterLocation.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateParameterLocation.cs new file mode 100644 index 0000000000000..fafd25050e590 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateParameterLocation.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplateParameterLocation")] + internal partial class MessageTemplateParameterLocation + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueInternal.cs new file mode 100644 index 0000000000000..05ce7151160bc --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueInternal.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplateValue")] + internal partial class MessageTemplateValueInternal + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueMedia.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueMedia.cs new file mode 100644 index 0000000000000..2a88d562009a3 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueMedia.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplateValueMedia")] + internal partial class MessageTemplateValueMedia + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueQuickAction.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueQuickAction.cs new file mode 100644 index 0000000000000..ecec485855811 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueQuickAction.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplateValueQuickAction")] + internal partial class MessageTemplateValueQuickAction + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueText.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueText.cs new file mode 100644 index 0000000000000..0a7c554cb1951 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/MessageTemplateValueText.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("MessageTemplateValueText")] + internal partial class MessageTemplateValueText + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/TemplateResponseInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/TemplateResponseInternal.cs new file mode 100644 index 0000000000000..dd3936bb1a003 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/TemplateResponseInternal.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The response item for template. + [CodeGenModel("TemplateResponse")] + internal partial class TemplateResponseInternal + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/TemplateResponseWhatsAppInternal.cs b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/TemplateResponseWhatsAppInternal.cs new file mode 100644 index 0000000000000..0a93cc25f6a76 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/InternalModels/TemplateResponseWhatsAppInternal.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + [CodeGenModel("TemplateResponseWhatsApp")] + internal partial class TemplateResponseWhatsAppInternal + { + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplate.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplate.cs new file mode 100644 index 0000000000000..d5b26081ba5c8 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplate.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; + +namespace Azure.Communication.Messages +{ + /// The template object used to create templates. + public class MessageTemplate + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the template. + /// The codes for the supported languages for templates. + /// The template values. + /// The binding object to link values to the template specific locations. + public MessageTemplate(string name, string language, IEnumerable values = null, MessageTemplateBindings bindings = null) + { + Name = name ?? throw new ArgumentNullException(nameof(name)); + Language = language ?? throw new ArgumentNullException(nameof(language)); + Values = values; + Bindings = bindings; + } + + /// Name of the template. + public string Name { get; } + /// The codes for the supported languages for templates. + public string Language { get; } + /// The template values. + public IEnumerable Values { get; } + /// The binding object to link values to the template specific locations. + public MessageTemplateBindings Bindings { get; } + + internal MessageTemplateInternal ToMessageTemplateInternal() + { + var messageTemplateInternal = new MessageTemplateInternal(Name, Language); + + if (Values != null) + { + foreach (MessageTemplateValue value in Values) + { + messageTemplateInternal.Values.Add(value.Name, value.ToMessageTemplateValueInternal()); + } + } + + if (Bindings != null) + { + messageTemplateInternal.Bindings = Bindings.ToMessageTemplateBindingsInternal(); + } + + return messageTemplateInternal; + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateBindings.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateBindings.cs new file mode 100644 index 0000000000000..93ad6206eb604 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateBindings.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Azure.Communication.Messages +{ + /// The binding object to link values to the template specific locations. + public abstract class MessageTemplateBindings + { + /// Initializes a new instance of MessageTemplateBindings. + public MessageTemplateBindings() + { + } + + internal abstract MessageTemplateBindingsInternal ToMessageTemplateBindingsInternal(); + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateDocument.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateDocument.cs new file mode 100644 index 0000000000000..86364c176559a --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateDocument.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Azure.Communication.Messages +{ + /// + public class MessageTemplateDocument: MessageTemplateValue + { + /// + public MessageTemplateDocument(string name, Uri uri, string caption = null, string fileName = null) : base(name) + { + Uri = uri; + Caption = caption; + FileName = fileName; + } + + /// The (public) URL of the document media. + public Uri Uri { get; set; } + /// The [optional] caption of the media object. + public string Caption { get; set; } + /// The [optional] filename of the media file. + public string FileName { get; set; } + + internal override MessageTemplateValueInternal ToMessageTemplateValueInternal() + { + return new MessageTemplateValueInternal(MessageTemplateValueKind.Document) + { + Document = new MessageTemplateValueMedia { + Url = Uri, + Caption = Caption, + FileName = FileName + } + }; + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateImage.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateImage.cs new file mode 100644 index 0000000000000..c42a816c625e3 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateImage.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Azure.Communication.Messages +{ + /// + public class MessageTemplateImage: MessageTemplateValue + { + /// + public MessageTemplateImage(string name, Uri uri, string caption = null, string fileName = null) : base(name) + { + Uri = uri; + Caption = caption; + FileName = fileName; + } + + /// The (public) URL of the document media. + public Uri Uri { get; set; } + /// The [optional] caption of the media object. + public string Caption { get; set; } + /// The [optional] filename of the media file. + public string FileName { get; set; } + + internal override MessageTemplateValueInternal ToMessageTemplateValueInternal() + { + return new MessageTemplateValueInternal(MessageTemplateValueKind.Image) + { + Image = new MessageTemplateValueMedia + { + Url = Uri, + Caption = Caption, + FileName = FileName + } + }; + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateItem.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateItem.cs new file mode 100644 index 0000000000000..f2b567d44b2b7 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateItem.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Azure.Communication.Messages +{ + /// The TemplateResponse. + public partial class MessageTemplateItem + { + /// Initializes a new instance of MessageTemplateItem. + internal MessageTemplateItem() + { + } + + /// Initializes a new instance of MessageTemplateItem. + /// Get the template's Name. + /// Get the template's language. + /// + /// The aggregated template status. + /// The WhatsApp-specific template response contract. + internal MessageTemplateItem(string name, string language, CommunicationMessagesChannelType? channelType, TemplateStatus? status, MessageTemplateItemWhatsApp whatsApp) + { + Name = name; + Language = language; + ChannelType = channelType; + Status = status; + WhatsApp = whatsApp; + } + + /// Get the template's Name. + public string Name { get; } + /// Get the template's language. + public string Language { get; } + /// Gets the channel type. + public CommunicationMessagesChannelType? ChannelType { get; } + /// The aggregated template status. + public TemplateStatus? Status { get; } + /// The WhatsApp-specific template response contract. + public MessageTemplateItemWhatsApp WhatsApp { get; } + + internal MessageTemplateItem(TemplateResponseInternal templateResponseInternal) + { + Name = templateResponseInternal.Name; + Language = templateResponseInternal.Language; + ChannelType = templateResponseInternal.ChannelType; + Status = templateResponseInternal.Status; + WhatsApp = new MessageTemplateItemWhatsApp(templateResponseInternal.WhatsApp); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateItemWhatsApp.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateItemWhatsApp.cs new file mode 100644 index 0000000000000..9645e73a16a8e --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateItemWhatsApp.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Azure.Communication.Messages +{ + /// The WhatsApp-specific template response contract. + public partial class MessageTemplateItemWhatsApp + { + /// Initializes a new instance of TemplateResponseWhatsApp. + internal MessageTemplateItemWhatsApp() + { + } + + /// + /// WhatsApp platform's template content + /// This is the payload returned from WhatsApp API. + /// + public BinaryData Content { get; } + + internal MessageTemplateItemWhatsApp(TemplateResponseWhatsAppInternal templateResponseWhatsAppInternal) + { + Content = new BinaryData(templateResponseWhatsAppInternal.Content); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateLocation.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateLocation.cs new file mode 100644 index 0000000000000..d89ce369843ef --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateLocation.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Azure.Communication.Messages +{ + /// + public class MessageTemplateLocation : MessageTemplateValue + { + /// + public MessageTemplateLocation(string name, double latitude, double longitude, string locationName = null, string address = null) + : base(name) + { + Latitude = latitude; + Longitude = longitude; + LocationName = locationName; + Address = address; + } + + /// The name of the location. + public string LocationName { get; set; } + /// The address of the location. + public string Address { get; set; } + /// The latitude of the location. + public double Latitude { get; set; } + /// The longitude of the location. + public double Longitude { get; set; } + + internal override MessageTemplateValueInternal ToMessageTemplateValueInternal() + { + return new MessageTemplateValueInternal(MessageTemplateValueKind.Location) + { + Location = new MessageTemplateParameterLocation + { + Name = LocationName, + Address = Address, + Latitude = Latitude, + Longitude = Longitude + } + }; + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateQuickAction.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateQuickAction.cs new file mode 100644 index 0000000000000..93704a902b5d3 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateQuickAction.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using static System.Net.Mime.MediaTypeNames; + +namespace Azure.Communication.Messages +{ + /// + public class MessageTemplateQuickAction: MessageTemplateValue + { + /// + public MessageTemplateQuickAction(string name, string text = null, string payload = null) : base(name) + { + Text = text; + Payload = payload; + } + + /// The quick action text. + public string Text { get; set; } + /// The quick action payload. + public string Payload { get; set; } + + internal override MessageTemplateValueInternal ToMessageTemplateValueInternal() + { + return new MessageTemplateValueInternal(MessageTemplateValueKind.QuickAction) + { + QuickAction = new MessageTemplateValueQuickAction + { + Payload = Payload, + Text = Text + } + }; + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateText.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateText.cs new file mode 100644 index 0000000000000..0f7fb02a7e441 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateText.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Azure.Communication.Messages +{ + /// + public class MessageTemplateText: MessageTemplateValue + { + /// + public MessageTemplateText(string name, string text) : base(name) + { + Text = text; + } + + /// The message template's text value information. + public string Text { get; set; } + + internal override MessageTemplateValueInternal ToMessageTemplateValueInternal() + { + return new MessageTemplateValueInternal(MessageTemplateValueKind.Text) + { + Text = new MessageTemplateValueText(Text) + }; + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateValue.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateValue.cs new file mode 100644 index 0000000000000..afecb9548fbb6 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateValue.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// The class describes a parameter of a template. + public abstract class MessageTemplateValue + { + /// Initializes a new instance of MessageTemplateValueInternal. + /// The template value name. + public MessageTemplateValue(string name) + { + Name = name; + } + + /// The template value name. + public string Name { get; } + + internal abstract MessageTemplateValueInternal ToMessageTemplateValueInternal(); + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateVideo.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateVideo.cs new file mode 100644 index 0000000000000..5ff68d901b0f7 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateVideo.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Azure.Communication.Messages +{ + /// + public class MessageTemplateVideo: MessageTemplateValue + { + /// + public MessageTemplateVideo(string name, Uri uri, string caption = null, string fileName = null) : base(name) + { + Uri = uri; + Caption = caption; + FileName = fileName; + } + + /// The (public) URL of the document media. + public Uri Uri { get; set; } + /// The [optional] caption of the media object. + public string Caption { get; set; } + /// The [optional] filename of the media file. + public string FileName { get; set; } + + internal override MessageTemplateValueInternal ToMessageTemplateValueInternal() + { + return new MessageTemplateValueInternal(MessageTemplateValueKind.Video) + { + Video = new MessageTemplateValueMedia { + Url = Uri, + Caption = Caption, + FileName = FileName + } + }; + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateWhatsAppBindings.cs b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateWhatsAppBindings.cs new file mode 100644 index 0000000000000..5f87acb75472e --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/MessageTemplateWhatsAppBindings.cs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections.Generic; +using System; +using System.Linq; + +namespace Azure.Communication.Messages +{ + /// The binding object to link values to the template specific locations. + public class MessageTemplateWhatsAppBindings: MessageTemplateBindings + { + /// Initializes a new instance of MessageTemplateWhatsAppBindings. + public MessageTemplateWhatsAppBindings(IEnumerable header = null, IEnumerable body = null, IEnumerable footer = null, IEnumerable> button = null) + { + Header = header; + Body = body; + Footer = footer; + Button = button; + } + + /// Gets the header. + public IEnumerable Header { get; } + /// Gets the body. + public IEnumerable Body { get; } + /// Gets the footer. + public IEnumerable Footer { get; } + /// Gets the button. + public IEnumerable> Button { get; } + + internal override MessageTemplateBindingsInternal ToMessageTemplateBindingsInternal() + { + var whatsApp = new MessageTemplateBindingsWhatsApp(); + + if (Header != null) + { + foreach (string item in Header) + { + whatsApp.Header.Add(new MessageTemplateBindingsWhatsAppComponent(item)); + } + }; + + if (Body != null) + { + foreach (string item in Body) + { + whatsApp.Body.Add(new MessageTemplateBindingsWhatsAppComponent(item)); + } + }; + + if (Footer != null) + { + foreach (string item in Footer) + { + whatsApp.Footer.Add(new MessageTemplateBindingsWhatsAppComponent(item)); + } + }; + + if (Button != null) + { + foreach (var item in Button) + { + whatsApp.Button.Add(new MessageTemplateBindingsWhatsAppButton(item.Key) { SubType = item.Value }); + } + }; + + return new MessageTemplateBindingsInternal() { WhatsApp = whatsApp }; + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Models/SendMessageOptions.cs b/sdk/communication/Azure.Communication.Messages/src/Models/SendMessageOptions.cs new file mode 100644 index 0000000000000..0af50fc982ea3 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Models/SendMessageOptions.cs @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using Azure.Core; + +namespace Azure.Communication.Messages +{ + /// Options for the notification message. + public class SendMessageOptions + { + /// + /// Initializes a new instance of the class for sending a Text message. + /// + /// + /// + /// + public SendMessageOptions(string channelRegistrationId, IEnumerable to, string content) + { + Argument.AssertNotNull(to, nameof(to)); + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNull(channelRegistrationId, nameof(channelRegistrationId)); + ChannelRegistrationId = channelRegistrationId; + To = to; + Content = content; + MessageType = CommunicationMessageType.Text; + } + + /// + /// Initializes a new instance of the class for sending a Media message. + /// + /// + /// + /// + /// + public SendMessageOptions(string channelRegistrationId, IEnumerable to, Uri mediaUri, string content = null) + { + Argument.AssertNotNull(to, nameof(to)); + Argument.AssertNotNull(mediaUri, nameof(mediaUri)); + Argument.AssertNotNull(channelRegistrationId, nameof(channelRegistrationId)); + ChannelRegistrationId = channelRegistrationId; + To = to; + MediaUri = mediaUri; + Content = content; + MessageType = CommunicationMessageType.Image; + } + + /// + /// Initializes a new instance of the class for sending a Template message. + /// + /// + /// + /// + public SendMessageOptions(string channelRegistrationId, IEnumerable to, MessageTemplate template) // type implicitly Template + { + Argument.AssertNotNull(to, nameof(to)); + Argument.AssertNotNull(template, nameof(template)); + Argument.AssertNotNull(channelRegistrationId, nameof(channelRegistrationId)); + ChannelRegistrationId = channelRegistrationId; + To = to; + Template = template; + MessageType = CommunicationMessageType.Template; + } + + /// The Channel Registration ID for the Business Identifier. + public string ChannelRegistrationId { get; } + /// The native external platform user identifiers of the recipient. + public IEnumerable To { get; } + /// The cross-platform threadless message type. + public CommunicationMessageType MessageType { get; } + /// Threadless message content. + public string Content { get; } + /// The media Object. + public Uri MediaUri { get; } + /// The template object used to create message templates. + public MessageTemplate Template { get; } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/NotificationMessagesClient.cs b/sdk/communication/Azure.Communication.Messages/src/NotificationMessagesClient.cs new file mode 100644 index 0000000000000..7bbe835d7be31 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/NotificationMessagesClient.cs @@ -0,0 +1,320 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Azure.Communication.Pipeline; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.Communication.Messages +{ + /// + /// The Azure Communication Services Notification Messages client. + /// + public class NotificationMessagesClient + { + private readonly ClientDiagnostics _clientDiagnostics; + private readonly NotificationMessagesRestClient _notificationMessagesRestClient; + private readonly StreamRestClient _streamRestClient; + + #region public constructors + + /// + /// Initializes a new instance of + /// + /// Connection string acquired from the Azure Communication Services resource. + public NotificationMessagesClient(string connectionString) + : this( + ConnectionString.Parse(Argument.CheckNotNullOrEmpty(connectionString, nameof(connectionString))), + new CommunicationMessagesClientOptions()) + { + } + + /// Initializes a new instance of . + /// Connection string acquired from the Azure Communication Services resource. + /// Client options exposing , , , etc. + public NotificationMessagesClient(string connectionString, CommunicationMessagesClientOptions options) + : this( + ConnectionString.Parse(Argument.CheckNotNullOrEmpty(connectionString, nameof(connectionString))), + options ?? new CommunicationMessagesClientOptions()) + { + } + + /// Initializes a new instance of . + /// The URI of the Azure Communication Services resource. + /// The used to authenticate requests. + /// Client options exposing , , , etc. + public NotificationMessagesClient(Uri endpoint, AzureKeyCredential keyCredential, CommunicationMessagesClientOptions options = default) + : this( + Argument.CheckNotNull(endpoint, nameof(endpoint)).AbsoluteUri, + Argument.CheckNotNull(keyCredential, nameof(keyCredential)), + options ?? new CommunicationMessagesClientOptions()) + { + } + + #endregion + + #region private constructors + private NotificationMessagesClient(ConnectionString connectionString, CommunicationMessagesClientOptions options) + : this(new Uri(connectionString.GetRequired("endpoint")), options.BuildHttpPipeline(connectionString), options) + { } + + private NotificationMessagesClient(string endpoint, TokenCredential tokenCredential, CommunicationMessagesClientOptions options) + : this(new Uri(endpoint), options.BuildHttpPipeline(tokenCredential), options) + { } + + private NotificationMessagesClient(string endpoint, AzureKeyCredential keyCredential, CommunicationMessagesClientOptions options) + : this(new Uri(endpoint), options.BuildHttpPipeline(keyCredential), options) + { } + + private NotificationMessagesClient(Uri endpoint, HttpPipeline httpPipeline, CommunicationMessagesClientOptions options) + { + _clientDiagnostics = new ClientDiagnostics(options); + _notificationMessagesRestClient = new NotificationMessagesRestClient(_clientDiagnostics, httpPipeline, endpoint, options.ApiVersion); + _streamRestClient = new StreamRestClient(_clientDiagnostics, httpPipeline, endpoint, options.ApiVersion); + } + + #endregion + + /// Initializes a new instance of for mocking. + protected NotificationMessagesClient() + { + _clientDiagnostics = null!; + _notificationMessagesRestClient = null!; + _streamRestClient = null!; + } + + #region Send Message Operations + /// Sends a notification message asynchronously. + /// Options for the message. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual async Task> SendMessageAsync(SendMessageOptions options, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(NotificationMessagesClient)}.{nameof(SendMessage)}"); + scope.Start(); + _ = options ?? throw new ArgumentNullException(nameof(options)); + + try + { + return await _notificationMessagesRestClient.SendMessageAsync(options.ChannelRegistrationId, options.To, options.MessageType, options.Content, options.MediaUri?.AbsoluteUri, options.Template?.ToMessageTemplateInternal(), cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + scope.Failed(ex); + throw; + } + } + + /// Sends a notification message. + /// Options for the message. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual Response SendMessage(SendMessageOptions options, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(NotificationMessagesClient)}.{nameof(SendMessage)}"); + scope.Start(); + _ = options ?? throw new ArgumentNullException(nameof(options)); + + try + { + return _notificationMessagesRestClient.SendMessage(options.ChannelRegistrationId, options.To, options.MessageType, options.Content, options.MediaUri?.AbsoluteUri, options.Template?.ToMessageTemplateInternal(), cancellationToken); + } + catch (Exception ex) + { + scope.Failed(ex); + throw; + } + } + #endregion + + #region Download Media Operations + /// Download the Media payload from a User to Business message asynchronously. + /// The Media Identifier contained in the User to Business message event. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual async Task> DownloadMediaAsync(string mediaContentId, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(StreamRestClient)}.{nameof(DownloadMediaAsync)}"); + scope.Start(); + _ = mediaContentId ?? throw new ArgumentNullException(nameof(mediaContentId)); + + try + { + return await _streamRestClient.DownloadMediaAsync(mediaContentId, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + scope.Failed(ex); + throw; + } + } + + /// + /// The downloads + /// the Media payload from a User to Business message asynchronously. + /// + /// The Media Identifier contained in the User to Business message event. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual Response DownloadMedia(string mediaContentId, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(StreamRestClient)}.{nameof(DownloadMedia)}"); + scope.Start(); + _ = mediaContentId ?? throw new ArgumentNullException(nameof(mediaContentId)); + + try + { + return _streamRestClient.DownloadMedia(mediaContentId, cancellationToken); + } + catch (Exception ex) + { + scope.Failed(ex); + throw; + } + } + + /// + /// The operation downloads the + /// specified content asynchronously, and writes the content to . + /// + /// The Media Identifier contained in the User to Business message event. + /// A to write the downloaded content to. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual async Task DownloadMediaToAsync(string mediaContentId, Stream destinationStream, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(StreamRestClient)}.{nameof(DownloadMediaAsync)}"); + scope.Start(); + _ = mediaContentId ?? throw new ArgumentNullException(nameof(mediaContentId)); + + try + { + return await DownloadMediaToAsyncInternal(mediaContentId, destinationStream, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + scope.Failed(ex); + throw; + } + } + + /// + /// The operation downloads the + /// specified content, and writes the content to . + /// + /// The Media Identifier contained in the User to Business message event. + /// A to write the downloaded content to. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual Response DownloadMediaTo(string mediaContentId, Stream destinationStream, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(StreamRestClient)}.{nameof(DownloadMedia)}"); + scope.Start(); + _ = mediaContentId ?? throw new ArgumentNullException(nameof(mediaContentId)); + + try + { + return DownloadMediaToInternal(mediaContentId, destinationStream, cancellationToken); + } + catch (Exception ex) + { + scope.Failed(ex); + throw; + } + } + + /// + /// The operation downloads the + /// specified content, and writes the content to . + /// + /// The Media Identifier contained in the User to Business message event. + /// A file path to write the downloaded content to. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual async Task DownloadMediaToAsync(string mediaContentId, string destinationPath, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(StreamRestClient)}.{nameof(DownloadMediaAsync)}"); + scope.Start(); + _ = mediaContentId ?? throw new ArgumentNullException(nameof(mediaContentId)); + + using Stream destinationStream = File.Create(destinationPath); + + try + { + return await DownloadMediaToAsyncInternal(mediaContentId, destinationStream, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + scope.Failed(ex); + throw; + } + } + + /// + /// The operation downloads the + /// specified content, and writes the content to . + /// + /// The Media Identifier contained in the User to Business message event. + /// A file path to write the downloaded content to. + /// The cancellation token to use. + /// The server returned an error. See for details returned from the server. + public virtual Response DownloadMediaTo(string mediaContentId, string destinationPath, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(StreamRestClient)}.{nameof(DownloadMedia)}"); + scope.Start(); + _ = mediaContentId ?? throw new ArgumentNullException(nameof(mediaContentId)); + + using Stream destinationStream = File.Create(destinationPath); + + try + { + return DownloadMediaToInternal(mediaContentId, destinationStream, cancellationToken); + } + catch (Exception ex) + { + scope.Failed(ex); + throw; + } + } + + private async Task DownloadMediaToAsyncInternal(string mediaContentId, Stream destinationStream, CancellationToken cancellationToken = default) + { + Response initialResponse = await _streamRestClient.DownloadMediaAsync(mediaContentId, cancellationToken).ConfigureAwait(false); + + await CopyToAsync(initialResponse, destinationStream).ConfigureAwait(false); + + return initialResponse.GetRawResponse(); + } + + private Response DownloadMediaToInternal(string mediaContentId, Stream destinationStream, CancellationToken cancellationToken = default) + { + Response initialResponse = _streamRestClient.DownloadMedia(mediaContentId, cancellationToken); + + CopyTo(initialResponse, destinationStream, cancellationToken); + + return initialResponse.GetRawResponse(); + } + + private static async Task CopyToAsync(Stream result, Stream destination) + { + await result.CopyToAsync(destination).ConfigureAwait(false); + } + + private static void CopyTo(Stream result, Stream destination, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + result.CopyTo(destination); + result.Dispose(); + } + #endregion + + private static HttpPipeline CreatePipelineFromOptions(ConnectionString connectionString, CommunicationMessagesClientOptions options) + { + return options.BuildHttpPipeline(connectionString); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/src/Properties/AssemblyInfo.cs b/sdk/communication/Azure.Communication.Messages/src/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000000..6522e17d75ccb --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Runtime.CompilerServices; + +[assembly: Azure.Core.AzureResourceProviderNamespace("Communication")] diff --git a/sdk/communication/Azure.Communication.Messages/src/autorest.md b/sdk/communication/Azure.Communication.Messages/src/autorest.md new file mode 100644 index 0000000000000..c036372cc217b --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/src/autorest.md @@ -0,0 +1,33 @@ +# Azure.Communication.Messages + +When a new version of the swagger needs to be updated: +1. Go to sdk\communication, and run `dotnet msbuild /t:GenerateCode` to generate code. +2. Upload the Azure.Communication.Messages.dll to the apiview.dev tool. +If any of the new objects needs to be overwritten, add the required changes to the 'Models' folder. +3. Repeat 2 and 3 until the decided interface is reflected in the apiview.dev + +### AutoRest Configuration + +> see https://aka.ms/autorest +``` yaml +title: Messages +tag: package-2023-08-24-preview +model-namespace: false +require: + - https://github.com/Azure/azure-rest-api-specs/blob/bf04fb1344aec3daf86deff14ae5d73f943d7cca/specification/communication/data-plane/Messages/readme.md +payload-flattening-threshold: 10 +generation1-convenience-client: true +``` + +### Don't buffer media downloads + +Sets the success response as binary stream, instead of error object. + +``` yaml +directive: +- from: swagger-document + where: $..[?(@.operationId=='Stream_DownloadMedia')] + transform: + $["x-csharp-buffer-response"] = false; + $.responses["200"].schema.format = "binary"; +``` diff --git a/sdk/communication/Azure.Communication.Messages/tests.yml b/sdk/communication/Azure.Communication.Messages/tests.yml new file mode 100644 index 0000000000000..56c818c046ec4 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests.yml @@ -0,0 +1,14 @@ +trigger: none + +extends: + template: /eng/pipelines/templates/stages/archetype-sdk-tests.yml + parameters: + ServiceDirectory: communication + Project: Azure.Communication.Messages + CloudConfig: + Public: + SubscriptionConfigurations: + - $(sub-config-azure-cloud-test-resources) + - $(sub-config-communication-services-cloud-test-resources-common) + - $(sub-config-communication-services-cloud-test-resources-net) + Clouds: Public diff --git a/sdk/communication/Azure.Communication.Messages/tests/Azure.Communication.Messages.Tests.csproj b/sdk/communication/Azure.Communication.Messages/tests/Azure.Communication.Messages.Tests.csproj new file mode 100644 index 0000000000000..4de595b8fc55c --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/Azure.Communication.Messages.Tests.csproj @@ -0,0 +1,33 @@ + + + $(RequiredTargetFrameworks) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/communication/Azure.Communication.Messages/tests/Infrastructure/MessagesLiveTestBase.cs b/sdk/communication/Azure.Communication.Messages/tests/Infrastructure/MessagesLiveTestBase.cs new file mode 100644 index 0000000000000..e8283c3f60b2f --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/Infrastructure/MessagesLiveTestBase.cs @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Azure.Core; +using Azure.Core.TestFramework; +using Azure.Identity; + +namespace Azure.Communication.Messages.Tests +{ + public class MessagesLiveTestBase : RecordedTestBase + { + public MessagesLiveTestBase(bool isAsync) : base(isAsync) + { + SanitizedHeaders.Add("x-ms-content-sha256"); + } + + protected NotificationMessagesClient CreateInstrumentedNotificationMessagesClient() + { + var connectionString = TestEnvironment.LiveTestDynamicConnectionString; + var client = new NotificationMessagesClient(connectionString, InstrumentClientOptions(new CommunicationMessagesClientOptions())); + + return InstrumentClient(client); + } + + protected NotificationMessagesClient CreateInstrumentedNotificationMessagesClientWithAzureKeyCredential() + { + var endpoint = TestEnvironment.LiveTestDynamicEndpoint; + var accessKey = TestEnvironment.LiveTestDynamicAccessKey; + var client = new NotificationMessagesClient(endpoint, new AzureKeyCredential(accessKey), InstrumentClientOptions(new CommunicationMessagesClientOptions())); + + return InstrumentClient(client); + } + + protected MessageTemplateClient CreateInstrumentedMessageTemplateClient() + { + var connectionString = TestEnvironment.LiveTestDynamicConnectionString; + var client = new MessageTemplateClient(connectionString, InstrumentClientOptions(new CommunicationMessagesClientOptions())); + + return InstrumentClient(client); + } + + protected MessageTemplateClient CreateInstrumentedMessageTemplateClientWithAzureKeyCredential() + { + var endpoint = TestEnvironment.LiveTestDynamicEndpoint; + var accessKey = TestEnvironment.LiveTestDynamicAccessKey; + + var client = new MessageTemplateClient(endpoint, new AzureKeyCredential(accessKey), InstrumentClientOptions(new CommunicationMessagesClientOptions())); + + return InstrumentClient(client); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/Infrastructure/MessagesTestEnvironment.cs b/sdk/communication/Azure.Communication.Messages/tests/Infrastructure/MessagesTestEnvironment.cs new file mode 100644 index 0000000000000..841cfdb47121c --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/Infrastructure/MessagesTestEnvironment.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Communication.Tests; + +namespace Azure.Communication.Messages.Tests +{ + /// + /// A helper class used to retrieve information to be used for tests. + /// + public class MessagesTestEnvironment : CommunicationTestEnvironment + { + public string SenderChannelRegistrationId => GetRecordedVariable("SENDER_CHANNEL_REGISTRATION_ID"); + public string RecipientIdentifier => GetRecordedVariable("RECIPIENT_IDENTIFIER"); + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/NotificationMessagesClient/NotificationMessagesClientLiveTests.cs b/sdk/communication/Azure.Communication.Messages/tests/NotificationMessagesClient/NotificationMessagesClientLiveTests.cs new file mode 100644 index 0000000000000..3085023aebd6c --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/NotificationMessagesClient/NotificationMessagesClientLiveTests.cs @@ -0,0 +1,221 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NUnit.Framework; + +namespace Azure.Communication.Messages.Tests +{ + public class NotificationMessagesClientLiveTests : MessagesLiveTestBase + { + public NotificationMessagesClientLiveTests(bool isAsync) : base(isAsync) + { + } + + public const string ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/3/30/Building92microsoft.jpg"; + public const string VideoUrl = "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4"; + public const string DocumentUrl = "https://go.microsoft.com/fwlink/?linkid=2131549"; + + [Test] + public async Task SendMessageShouldSucceed() + { + // Arrange + NotificationMessagesClient notificationMessagesClient = CreateInstrumentedNotificationMessagesClient(); + var options = new SendMessageOptions(TestEnvironment.SenderChannelRegistrationId, new List { TestEnvironment.RecipientIdentifier }, "LiveTest"); + + // Act + Response response = await notificationMessagesClient.SendMessageAsync(options); + + // Assert + validateResponse(response); + } + + [Test] + public async Task SendMessageWithAzureKeyCredentialShouldSucceed() + { + // Arrange + NotificationMessagesClient notificationMessagesClient = CreateInstrumentedNotificationMessagesClientWithAzureKeyCredential(); + var options = new SendMessageOptions(TestEnvironment.SenderChannelRegistrationId, new List { TestEnvironment.RecipientIdentifier }, "LiveTest"); + + // Act + Response response = await notificationMessagesClient.SendMessageAsync(options); + + // Assert + validateResponse(response); + } + + [Test] + public async Task SendShippingConfirmationTemplateMessageShouldSucceed() + { + // Arrange + NotificationMessagesClient notificationMessagesClient = CreateInstrumentedNotificationMessagesClient(); + string channelRegistrationId = TestEnvironment.SenderChannelRegistrationId; + IEnumerable recipients = new List { TestEnvironment.RecipientIdentifier }; + + var ThreeDays = new MessageTemplateText("threeDays", "3"); + IEnumerable values = new List { ThreeDays }; + + MessageTemplateWhatsAppBindings bindings = new MessageTemplateWhatsAppBindings( + body: new[] { ThreeDays.Name } + ); + + MessageTemplate template = new MessageTemplate("sample_shipping_confirmation", "en_us", values, bindings); + SendMessageOptions options = new SendMessageOptions(channelRegistrationId, recipients, template); + + // Act + Response response = await notificationMessagesClient.SendMessageAsync(options); + + // Assert + validateResponse(response); + } + + [Test] + public async Task SendPurchaseFeedbackTemplateMessageShouldSucceed() + { + // Arrange + NotificationMessagesClient notificationMessagesClient = CreateInstrumentedNotificationMessagesClient(); + string channelRegistrationId = TestEnvironment.SenderChannelRegistrationId; + IEnumerable recipients = new List { TestEnvironment.RecipientIdentifier }; + + var image = new MessageTemplateImage("image", new Uri(ImageUrl)); + var product = new MessageTemplateText("product", "Microsoft Office"); + + IEnumerable values = new List { image, product }; + MessageTemplateWhatsAppBindings bindings = new MessageTemplateWhatsAppBindings( + header: new[] { image.Name }, + body: new[] { product.Name } + ); + MessageTemplate template = new MessageTemplate("sample_purchase_feedback", "en_us", values, bindings); + SendMessageOptions options = new SendMessageOptions(channelRegistrationId, recipients, template); + + // Act + Response response = await notificationMessagesClient.SendMessageAsync(options); + + // Assert + validateResponse(response); + } + + [Test] + public async Task SendIssueResolutionTemplateMessageShouldSucceed() + { + // Arrange + NotificationMessagesClient notificationMessagesClient = CreateInstrumentedNotificationMessagesClient(); + string channelRegistrationId = TestEnvironment.SenderChannelRegistrationId; + IEnumerable recipients = new List { TestEnvironment.RecipientIdentifier }; + + var name = new MessageTemplateText("name", "Gloria"); + var yes = new MessageTemplateQuickAction("yes", null, "Yay!"); + var no = new MessageTemplateQuickAction("no", null, "Nay!"); + + IEnumerable values = new List { name, yes, no }; + MessageTemplateWhatsAppBindings bindings = new MessageTemplateWhatsAppBindings( + body: new[] { name.Name }, + button: new[] { + new KeyValuePair(yes.Name, MessageTemplateValueWhatsAppSubType.QuickReply), + new KeyValuePair(no.Name, MessageTemplateValueWhatsAppSubType.QuickReply), + } + ); + MessageTemplate template = new MessageTemplate("sample_issue_resolution", "en_us", values, bindings); + SendMessageOptions options = new SendMessageOptions(channelRegistrationId, recipients, template); + + // Act + Response response = await notificationMessagesClient.SendMessageAsync(options); + + // Assert + validateResponse(response); + } + + [Test] + public async Task SendHappyHourAnnocementTemplateMessageShouldSucceed() + { + // Arrange + NotificationMessagesClient notificationMessagesClient = CreateInstrumentedNotificationMessagesClient(); + string channelRegistrationId = TestEnvironment.SenderChannelRegistrationId; + IEnumerable recipients = new List { TestEnvironment.RecipientIdentifier }; + + var venue = new MessageTemplateText("venue", "Starbucks"); + var time = new MessageTemplateText("time", "Today 2-4PM"); + var video = new MessageTemplateVideo("video", new Uri(VideoUrl)); + + IEnumerable values = new List { venue, time, video }; + MessageTemplateWhatsAppBindings bindings = new MessageTemplateWhatsAppBindings( + header: new[] { video.Name }, + body: new[] { venue.Name, time.Name } + ); + MessageTemplate template = new MessageTemplate("sample_happy_hour_announcement", "en_us", values, bindings); + SendMessageOptions options = new SendMessageOptions(channelRegistrationId, recipients, template); + + // Act + Response response = await notificationMessagesClient.SendMessageAsync(options); + + // Assert + validateResponse(response); + } + + [Test] + public async Task SendFlightConfirmationTemplateMessageShouldSucceed() + { + // Arrange + NotificationMessagesClient notificationMessagesClient = CreateInstrumentedNotificationMessagesClient(); + string channelRegistrationId = TestEnvironment.SenderChannelRegistrationId; + IEnumerable recipients = new List { TestEnvironment.RecipientIdentifier }; + + var document = new MessageTemplateDocument("document", new Uri(DocumentUrl)); + var firstName = new MessageTemplateText("firstName", "Gloria"); + var lastName = new MessageTemplateText("lastName", "Li"); + var date = new MessageTemplateText("date", "July 1st, 2023"); + + IEnumerable values = new List { document, firstName, lastName, date }; + MessageTemplateWhatsAppBindings bindings = new MessageTemplateWhatsAppBindings( + header: new[] { document.Name }, + body: new[] { firstName.Name, lastName.Name, date.Name } + ); + MessageTemplate template = new MessageTemplate("sample_flight_confirmation", "en_us", values, bindings); + SendMessageOptions options = new SendMessageOptions(channelRegistrationId, recipients, template); + + // Act + Response response = await notificationMessagesClient.SendMessageAsync(options); + + // Assert + validateResponse(response); + } + + [Test] + public async Task SendMovieTicketConfirmationTemplateMessageShouldSucceed() + { + // Arrange + NotificationMessagesClient notificationMessagesClient = CreateInstrumentedNotificationMessagesClient(); + string channelRegistrationId = TestEnvironment.SenderChannelRegistrationId; + IEnumerable recipients = new List { TestEnvironment.RecipientIdentifier }; + + var image = new MessageTemplateImage("image", new Uri(ImageUrl)); + var title = new MessageTemplateText("title", "Avengers"); + var time = new MessageTemplateText("time", "July 1st, 2023 12:30PM"); + var venue = new MessageTemplateText("venue", "Cineplex"); + var seats = new MessageTemplateText("seats", "Seat 1A"); + IEnumerable values = new List { image, title, time, venue, seats }; + MessageTemplateWhatsAppBindings bindings = new MessageTemplateWhatsAppBindings( + header: new[] { image.Name }, + body: new[] { title.Name, time.Name, venue.Name, seats.Name } + ); + MessageTemplate template = new MessageTemplate("sample_movie_ticket_confirmation", "en_us", values, bindings); + SendMessageOptions options = new SendMessageOptions(channelRegistrationId, recipients, template); + + // Act + Response response = await notificationMessagesClient.SendMessageAsync(options); + + // Assert + validateResponse(response); + } + + private void validateResponse(Response response) + { + Assert.AreEqual(202, response.GetRawResponse().Status); + Assert.IsNotNull(response.Value.Receipts[0].MessageId); + Assert.IsNotNull(response.Value.Receipts[0].To); + Assert.AreEqual(TestEnvironment.RecipientIdentifier, response.Value.Receipts[0].To); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/NotificationMessagesClient/NotificationMessagesClientTests.cs b/sdk/communication/Azure.Communication.Messages/tests/NotificationMessagesClient/NotificationMessagesClientTests.cs new file mode 100644 index 0000000000000..1be3268dcbfda --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/NotificationMessagesClient/NotificationMessagesClientTests.cs @@ -0,0 +1,94 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Azure.Core.TestFramework; +using Microsoft.Extensions.Options; +using NUnit.Framework; + +namespace Azure.Communication.Messages.Tests +{ + public class NotificationMessagesClientTests : ClientTestBase + { + protected const string ConnectionString = "endpoint=https://contoso.azure.com/;accesskey=ZHVtbXlhY2Nlc3NrZXk="; + + private const string SendMessageApiResponsePayload = "{\"receipts\":[{\"messageId\":\"d53605de-2f6e-437d-9e40-8d83b2111cb8\",\"to\":\"+1(123)456-7890\"}]}"; + + public NotificationMessagesClientTests(bool isAsync) : base(isAsync) + { + } + + [Test] + public void Constructor_InvalidParamsThrows() + { + Assert.Throws(() => new NotificationMessagesClient(null)); + Assert.Throws(() => new NotificationMessagesClient(string.Empty)); + Assert.Throws(() => new NotificationMessagesClient(" ")); + Assert.Throws(() => new NotificationMessagesClient("test")); + } + + [Test] + public async Task SendMessage_ValidParams_ShouldSucceed() + { + //arrange + NotificationMessagesClient notificationMessagesClient = CreateMockNotificationMessagesClient(202, SendMessageApiResponsePayload); + + //act + SendMessageOptions sendMessageOptions = new SendMessageOptions("testChannelRegistrationId", new List { "+1(123)456-7890" }, "testMessage"); + SendMessageResult sendMessageResult = await notificationMessagesClient.SendMessageAsync(sendMessageOptions); + + //assert + Assert.IsNotNull(sendMessageResult.Receipts[0].MessageId); + Assert.IsNotNull(sendMessageResult.Receipts[0].To); + Assert.AreEqual("d53605de-2f6e-437d-9e40-8d83b2111cb8", sendMessageResult.Receipts[0].MessageId); + Assert.AreEqual("+1(123)456-7890", sendMessageResult.Receipts[0].To); + } + + [Test] + public void SendNotificationMessage_NullSendMessageOptions_Throws() + { + //arrange + NotificationMessagesClient notificationMessagesClient = CreateMockNotificationMessagesClient(); + + //act & assert + Assert.ThrowsAsync(async () => await notificationMessagesClient.SendMessageAsync(null)); + } + + [Test] + public async Task SendMessage_InvalidChannelRegistrationId_ThrowsBadRequestException() + { + //arrange + NotificationMessagesClient notificationMessagesClient = CreateMockNotificationMessagesClient(400); + + try + { + //act + SendMessageOptions sendMessageOptions = new SendMessageOptions("invalidChannelRegistrationId", new List { "+1(123)456-7890" }, "testMessage"); + await notificationMessagesClient.SendMessageAsync(sendMessageOptions); + } + catch (RequestFailedException requestFailedException) + { + //assert + Assert.AreEqual(400, requestFailedException.Status); + } + } + + private NotificationMessagesClient CreateMockNotificationMessagesClient(int responseCode = 202, string responseContent = null) + { + var mockResponse = new MockResponse(responseCode); + if (responseContent != null) + { + mockResponse.SetContent(responseContent); + } + + var notificationMessagesClientOptions = new CommunicationMessagesClientOptions + { + Transport = new MockTransport(mockResponse) + }; + + return new NotificationMessagesClient(ConnectionString, notificationMessagesClientOptions); + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesShouldSucceed.json new file mode 100644 index 0000000000000..6f771fa284bd8 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesShouldSucceed.json @@ -0,0 +1,723 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-8570f5ccd3dfd6ce6777d0a08d1ba0b5-dfb1a805bbd63c39-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "d824e77a461ffaa87df9cb7150d5e937", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:15 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "9833", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:16 GMT", + "MS-CV": "HSVUeJZ21023ph9hVFUaKw.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "03K0gZQAAAACCTJz6LdAWSq690\u002BSbtvcUWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "514ms" + }, + "ResponseBody": { + "value": [ + { + "name": "optin_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Reply {{1}} to receive {{2}}. Txt {{3}} for HELP, Txt {{4}} to opt-out.", + "example": { + "body_text": [ + [ + "Y", + "appointment reminders", + "HELP", + "STOP" + ] + ] + } + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "This is your flight confirmation for {{1}}-{{2}} on {{3}}." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Esta \u00E9 a sua confirma\u00E7\u00E3o de voo para {{1}}-{{2}} em {{3}}." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Confirmamos tu vuelo a {{1}}-{{2}} para el {{3}}." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Ini merupakan konfirmasi penerbangan Anda untuk {{1}}-{{2}} di {{3}}." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Terima kasih sudah membeli {{1}}! Kami menghargai masukan Anda dan ingin mempelajari lebih lanjut terkait pengalaman Anda." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Ikuti survei", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Thank you for purchasing {{1}}! We value your feedback and would like to learn more about your experience." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Take Survey", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Agradecemos a aquisi\u00E7\u00E3o de {{1}}! Valorizamos seu feedback e gostar\u00EDamos de saber mais sobre sua experi\u00EAncia." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Responder \u00E0 pesquisa", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "\u00A1Gracias por comprar {{1}}! Valoramos tus comentarios y nos gustar\u00EDa saber c\u00F3mo fue tu experiencia." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Responder encuesta", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "Jam diskon telah tiba! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nBergembiralah dan nikmati hari Anda. \uD83C\uDF89\nTempat: {{1}}\nWaktu: {{2}}" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "\u00A1Lleg\u00F3 el happy hour! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nA divertirse y disfrutar. \uD83C\uDF89\nLugar: {{1}}\nHora: {{2}}" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "O happy hour chegou! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nSeja feliz e aproveite o dia. \uD83C\uDF89\nLocal: {{1}}\nHor\u00E1rio: {{2}}" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "Happy hour is here! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nPlease be merry and enjoy the day. \uD83C\uDF89\nVenue: {{1}}\nTime: {{2}}" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Oi, {{1}}. N\u00F3s conseguimos resolver o problema que voc\u00EA estava enfrentando?" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Sim" + }, + { + "type": "QUICK_REPLY", + "text": "N\u00E3o" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Hi {{1}}, were we able to solve the issue that you were facing?" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Yes" + }, + { + "type": "QUICK_REPLY", + "text": "No" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Halo {{1}}, apakah kami bisa mengatasi masalah yang sedang Anda hadapi?" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Ya" + }, + { + "type": "QUICK_REPLY", + "text": "Tidak" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Hola, {{1}}. \u00BFPudiste solucionar el problema que ten\u00EDas?" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "S\u00ED" + }, + { + "type": "QUICK_REPLY", + "text": "No" + } + ] + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Tu entrada para *{{1}}*\n*Hora* - {{2}}\n*Lugar* - {{3}}\n*Asientos* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Seu ingresso para *{{1}}*\n*Hor\u00E1rio* - {{2}}\n*Local* - {{3}}\n*Assentos* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Your ticket for *{{1}}*\n*Time* - {{2}}\n*Venue* - {{3}}\n*Seats* - {{4}}" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Tiket Anda untuk *{{1}}*\n*Waktu* - {{2}}\n*Tempat* - {{3}}\n*Kursi* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Your package has been shipped. It will be delivered in {{1}} business days." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Seu pacote foi enviado. Ele ser\u00E1 entregue em {{1}} dias \u00FAteis." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "\u00F3 tu paquete. La entrega se realizar\u00E1 en {{1}} d\u00ED." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Paket Anda sudah dikirim. Paket akan sampai dalam {{1}} hari kerja." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "appointment_reminder", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Dear {{1}} {{2}}, your next appointment with {{3}} is scheduled for {{4}}. Reply YES to confirm.", + "example": { + "body_text": [ + [ + "Eugenia", + "Lopez", + "Lamna Healthcare", + "September 25, 2022 at 9:00 AM" + ] + ] + } + } + ] + } + }, + { + "name": "order_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Your {{1}} order has been placed. Track order updates {{2}} Reply HELP for help." + } + ] + } + } + ], + "nextLink": "/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview\u0026continuationToken=MjQZD" + } + }, + { + "RequestUri": "https://sanitized.communication.azure.com/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview\u0026continuationToken=MjQZD", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-ed568cd511b864a9aeccc81aaad752de-d943206472d67079-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "865b2c0e3c8ac241ad864b537ae18160", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:17 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "12", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:17 GMT", + "MS-CV": "D0Geczfgq0SNStVwrBGXlQ.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "03a0gZQAAAAAFoJ3bQj82RZq2b\u002BaUk7ZMWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "440ms" + }, + "ResponseBody": { + "value": [] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "307047532", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesShouldSucceedAsync.json new file mode 100644 index 0000000000000..d3c816460e0fd --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesShouldSucceedAsync.json @@ -0,0 +1,723 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-011a3fe03f19fcbfa4178d42ef8e5d9a-64cce9f7766f2ea3-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "efb9e77c0d6a1d4979fd3ec2afdf693c", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:19 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "9833", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:19 GMT", + "MS-CV": "CECycpoKAEuAetLY0HvRbw.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "0360gZQAAAAAAArMCtdFwQJeQwoVSowOIWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "376ms" + }, + "ResponseBody": { + "value": [ + { + "name": "optin_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Reply {{1}} to receive {{2}}. Txt {{3}} for HELP, Txt {{4}} to opt-out.", + "example": { + "body_text": [ + [ + "Y", + "appointment reminders", + "HELP", + "STOP" + ] + ] + } + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "This is your flight confirmation for {{1}}-{{2}} on {{3}}." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Esta \u00E9 a sua confirma\u00E7\u00E3o de voo para {{1}}-{{2}} em {{3}}." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Confirmamos tu vuelo a {{1}}-{{2}} para el {{3}}." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Ini merupakan konfirmasi penerbangan Anda untuk {{1}}-{{2}} di {{3}}." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Terima kasih sudah membeli {{1}}! Kami menghargai masukan Anda dan ingin mempelajari lebih lanjut terkait pengalaman Anda." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Ikuti survei", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Thank you for purchasing {{1}}! We value your feedback and would like to learn more about your experience." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Take Survey", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Agradecemos a aquisi\u00E7\u00E3o de {{1}}! Valorizamos seu feedback e gostar\u00EDamos de saber mais sobre sua experi\u00EAncia." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Responder \u00E0 pesquisa", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "\u00A1Gracias por comprar {{1}}! Valoramos tus comentarios y nos gustar\u00EDa saber c\u00F3mo fue tu experiencia." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Responder encuesta", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "Jam diskon telah tiba! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nBergembiralah dan nikmati hari Anda. \uD83C\uDF89\nTempat: {{1}}\nWaktu: {{2}}" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "\u00A1Lleg\u00F3 el happy hour! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nA divertirse y disfrutar. \uD83C\uDF89\nLugar: {{1}}\nHora: {{2}}" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "O happy hour chegou! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nSeja feliz e aproveite o dia. \uD83C\uDF89\nLocal: {{1}}\nHor\u00E1rio: {{2}}" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "Happy hour is here! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nPlease be merry and enjoy the day. \uD83C\uDF89\nVenue: {{1}}\nTime: {{2}}" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Oi, {{1}}. N\u00F3s conseguimos resolver o problema que voc\u00EA estava enfrentando?" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Sim" + }, + { + "type": "QUICK_REPLY", + "text": "N\u00E3o" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Hi {{1}}, were we able to solve the issue that you were facing?" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Yes" + }, + { + "type": "QUICK_REPLY", + "text": "No" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Halo {{1}}, apakah kami bisa mengatasi masalah yang sedang Anda hadapi?" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Ya" + }, + { + "type": "QUICK_REPLY", + "text": "Tidak" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Hola, {{1}}. \u00BFPudiste solucionar el problema que ten\u00EDas?" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "S\u00ED" + }, + { + "type": "QUICK_REPLY", + "text": "No" + } + ] + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Tu entrada para *{{1}}*\n*Hora* - {{2}}\n*Lugar* - {{3}}\n*Asientos* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Seu ingresso para *{{1}}*\n*Hor\u00E1rio* - {{2}}\n*Local* - {{3}}\n*Assentos* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Your ticket for *{{1}}*\n*Time* - {{2}}\n*Venue* - {{3}}\n*Seats* - {{4}}" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Tiket Anda untuk *{{1}}*\n*Waktu* - {{2}}\n*Tempat* - {{3}}\n*Kursi* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Your package has been shipped. It will be delivered in {{1}} business days." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Seu pacote foi enviado. Ele ser\u00E1 entregue em {{1}} dias \u00FAteis." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "\u00F3 tu paquete. La entrega se realizar\u00E1 en {{1}} d\u00ED." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Paket Anda sudah dikirim. Paket akan sampai dalam {{1}} hari kerja." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "appointment_reminder", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Dear {{1}} {{2}}, your next appointment with {{3}} is scheduled for {{4}}. Reply YES to confirm.", + "example": { + "body_text": [ + [ + "Eugenia", + "Lopez", + "Lamna Healthcare", + "September 25, 2022 at 9:00 AM" + ] + ] + } + } + ] + } + }, + { + "name": "order_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Your {{1}} order has been placed. Track order updates {{2}} Reply HELP for help." + } + ] + } + } + ], + "nextLink": "/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview\u0026continuationToken=MjQZD" + } + }, + { + "RequestUri": "https://sanitized.communication.azure.com/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview\u0026continuationToken=MjQZD", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-819ca6c0b23ddd961c0de6304fc36809-269437e3bf197793-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "9491b3811273fa6ff6769b27e2e75fdc", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:19 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "12", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:19 GMT", + "MS-CV": "I1RfSdPPFk\u002BtPlnaorPJoA.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "04K0gZQAAAACOc\u002BOaK3qOSqEXfw\u002BA6jAmWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "325ms" + }, + "ResponseBody": { + "value": [] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "221729722", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesWithAzureKeyCredentialShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesWithAzureKeyCredentialShouldSucceed.json new file mode 100644 index 0000000000000..e3228b1c784d7 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesWithAzureKeyCredentialShouldSucceed.json @@ -0,0 +1,723 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-aaf19dc41005bafcd0b5228b9364f7d1-0ad7114f5adeb89a-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "a9d52edc108c9fc4551e6c10e08d4f4c", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:18 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "9833", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:18 GMT", + "MS-CV": "cOKPLQZ8HUSmXEuHv7l36w.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "03q0gZQAAAAAcrz/IW1UmRLvrDycf\u002B85TWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "410ms" + }, + "ResponseBody": { + "value": [ + { + "name": "optin_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Reply {{1}} to receive {{2}}. Txt {{3}} for HELP, Txt {{4}} to opt-out.", + "example": { + "body_text": [ + [ + "Y", + "appointment reminders", + "HELP", + "STOP" + ] + ] + } + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "This is your flight confirmation for {{1}}-{{2}} on {{3}}." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Esta \u00E9 a sua confirma\u00E7\u00E3o de voo para {{1}}-{{2}} em {{3}}." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Confirmamos tu vuelo a {{1}}-{{2}} para el {{3}}." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Ini merupakan konfirmasi penerbangan Anda untuk {{1}}-{{2}} di {{3}}." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Terima kasih sudah membeli {{1}}! Kami menghargai masukan Anda dan ingin mempelajari lebih lanjut terkait pengalaman Anda." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Ikuti survei", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Thank you for purchasing {{1}}! We value your feedback and would like to learn more about your experience." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Take Survey", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Agradecemos a aquisi\u00E7\u00E3o de {{1}}! Valorizamos seu feedback e gostar\u00EDamos de saber mais sobre sua experi\u00EAncia." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Responder \u00E0 pesquisa", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "\u00A1Gracias por comprar {{1}}! Valoramos tus comentarios y nos gustar\u00EDa saber c\u00F3mo fue tu experiencia." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Responder encuesta", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "Jam diskon telah tiba! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nBergembiralah dan nikmati hari Anda. \uD83C\uDF89\nTempat: {{1}}\nWaktu: {{2}}" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "\u00A1Lleg\u00F3 el happy hour! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nA divertirse y disfrutar. \uD83C\uDF89\nLugar: {{1}}\nHora: {{2}}" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "O happy hour chegou! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nSeja feliz e aproveite o dia. \uD83C\uDF89\nLocal: {{1}}\nHor\u00E1rio: {{2}}" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "Happy hour is here! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nPlease be merry and enjoy the day. \uD83C\uDF89\nVenue: {{1}}\nTime: {{2}}" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Oi, {{1}}. N\u00F3s conseguimos resolver o problema que voc\u00EA estava enfrentando?" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Sim" + }, + { + "type": "QUICK_REPLY", + "text": "N\u00E3o" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Hi {{1}}, were we able to solve the issue that you were facing?" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Yes" + }, + { + "type": "QUICK_REPLY", + "text": "No" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Halo {{1}}, apakah kami bisa mengatasi masalah yang sedang Anda hadapi?" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Ya" + }, + { + "type": "QUICK_REPLY", + "text": "Tidak" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Hola, {{1}}. \u00BFPudiste solucionar el problema que ten\u00EDas?" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "S\u00ED" + }, + { + "type": "QUICK_REPLY", + "text": "No" + } + ] + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Tu entrada para *{{1}}*\n*Hora* - {{2}}\n*Lugar* - {{3}}\n*Asientos* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Seu ingresso para *{{1}}*\n*Hor\u00E1rio* - {{2}}\n*Local* - {{3}}\n*Assentos* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Your ticket for *{{1}}*\n*Time* - {{2}}\n*Venue* - {{3}}\n*Seats* - {{4}}" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Tiket Anda untuk *{{1}}*\n*Waktu* - {{2}}\n*Tempat* - {{3}}\n*Kursi* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Your package has been shipped. It will be delivered in {{1}} business days." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Seu pacote foi enviado. Ele ser\u00E1 entregue em {{1}} dias \u00FAteis." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "\u00F3 tu paquete. La entrega se realizar\u00E1 en {{1}} d\u00ED." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Paket Anda sudah dikirim. Paket akan sampai dalam {{1}} hari kerja." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "appointment_reminder", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Dear {{1}} {{2}}, your next appointment with {{3}} is scheduled for {{4}}. Reply YES to confirm.", + "example": { + "body_text": [ + [ + "Eugenia", + "Lopez", + "Lamna Healthcare", + "September 25, 2022 at 9:00 AM" + ] + ] + } + } + ] + } + }, + { + "name": "order_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Your {{1}} order has been placed. Track order updates {{2}} Reply HELP for help." + } + ] + } + } + ], + "nextLink": "/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview\u0026continuationToken=MjQZD" + } + }, + { + "RequestUri": "https://sanitized.communication.azure.com/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview\u0026continuationToken=MjQZD", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-1bac7abff5f0e9ef2f00b3df2e6f5926-c6333d834b580bae-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "9a89f7751bc9c5e37a78c0a96dab4187", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:18 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "12", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:18 GMT", + "MS-CV": "npKJcuovqEeZPHWdTALfCQ.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "0360gZQAAAAAfHNNQWWPoTbJsMpzdwlP6WVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "339ms" + }, + "ResponseBody": { + "value": [] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "2063248734", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesWithAzureKeyCredentialShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesWithAzureKeyCredentialShouldSucceedAsync.json new file mode 100644 index 0000000000000..c680676a6d3a9 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/MessageTemplateClientLiveTests/GetTemplatesWithAzureKeyCredentialShouldSucceedAsync.json @@ -0,0 +1,723 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-002f3498c8a48460f230f8ff846da6eb-22c6d8db6ac095e3-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "2ee392ebecdd6b787b444eccb46c4e43", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:20 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "9833", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:20 GMT", + "MS-CV": "W/UMsv\u002BlckS20OBwgQILcA.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "04K0gZQAAAABW8m13NEJySJPAVxyfnx0AWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "367ms" + }, + "ResponseBody": { + "value": [ + { + "name": "optin_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Reply {{1}} to receive {{2}}. Txt {{3}} for HELP, Txt {{4}} to opt-out.", + "example": { + "body_text": [ + [ + "Y", + "appointment reminders", + "HELP", + "STOP" + ] + ] + } + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "This is your flight confirmation for {{1}}-{{2}} on {{3}}." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Esta \u00E9 a sua confirma\u00E7\u00E3o de voo para {{1}}-{{2}} em {{3}}." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Confirmamos tu vuelo a {{1}}-{{2}} para el {{3}}." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_flight_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "DOCUMENT" + }, + { + "type": "BODY", + "text": "Ini merupakan konfirmasi penerbangan Anda untuk {{1}}-{{2}} di {{3}}." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Terima kasih sudah membeli {{1}}! Kami menghargai masukan Anda dan ingin mempelajari lebih lanjut terkait pengalaman Anda." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Ikuti survei", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Thank you for purchasing {{1}}! We value your feedback and would like to learn more about your experience." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Take Survey", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Agradecemos a aquisi\u00E7\u00E3o de {{1}}! Valorizamos seu feedback e gostar\u00EDamos de saber mais sobre sua experi\u00EAncia." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Responder \u00E0 pesquisa", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_purchase_feedback", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "\u00A1Gracias por comprar {{1}}! Valoramos tus comentarios y nos gustar\u00EDa saber c\u00F3mo fue tu experiencia." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "URL", + "text": "Responder encuesta", + "url": "https://www.example.com/" + } + ] + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "Jam diskon telah tiba! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nBergembiralah dan nikmati hari Anda. \uD83C\uDF89\nTempat: {{1}}\nWaktu: {{2}}" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "\u00A1Lleg\u00F3 el happy hour! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nA divertirse y disfrutar. \uD83C\uDF89\nLugar: {{1}}\nHora: {{2}}" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "O happy hour chegou! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nSeja feliz e aproveite o dia. \uD83C\uDF89\nLocal: {{1}}\nHor\u00E1rio: {{2}}" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_happy_hour_announcement", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "VIDEO" + }, + { + "type": "BODY", + "text": "Happy hour is here! \uD83C\uDF7A\uD83D\uDE00\uD83C\uDF78\nPlease be merry and enjoy the day. \uD83C\uDF89\nVenue: {{1}}\nTime: {{2}}" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Oi, {{1}}. N\u00F3s conseguimos resolver o problema que voc\u00EA estava enfrentando?" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Sim" + }, + { + "type": "QUICK_REPLY", + "text": "N\u00E3o" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Hi {{1}}, were we able to solve the issue that you were facing?" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Yes" + }, + { + "type": "QUICK_REPLY", + "text": "No" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Halo {{1}}, apakah kami bisa mengatasi masalah yang sedang Anda hadapi?" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "Ya" + }, + { + "type": "QUICK_REPLY", + "text": "Tidak" + } + ] + } + ] + } + }, + { + "name": "sample_issue_resolution", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Hola, {{1}}. \u00BFPudiste solucionar el problema que ten\u00EDas?" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + }, + { + "type": "BUTTONS", + "buttons": [ + { + "type": "QUICK_REPLY", + "text": "S\u00ED" + }, + { + "type": "QUICK_REPLY", + "text": "No" + } + ] + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Tu entrada para *{{1}}*\n*Hora* - {{2}}\n*Lugar* - {{3}}\n*Asientos* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Seu ingresso para *{{1}}*\n*Hor\u00E1rio* - {{2}}\n*Local* - {{3}}\n*Assentos* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Your ticket for *{{1}}*\n*Time* - {{2}}\n*Venue* - {{3}}\n*Seats* - {{4}}" + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_movie_ticket_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "HEADER", + "format": "IMAGE" + }, + { + "type": "BODY", + "text": "Tiket Anda untuk *{{1}}*\n*Waktu* - {{2}}\n*Tempat* - {{3}}\n*Kursi* - {{4}}" + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Your package has been shipped. It will be delivered in {{1}} business days." + }, + { + "type": "FOOTER", + "text": "This message is from an unverified business." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "pt_BR", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Seu pacote foi enviado. Ele ser\u00E1 entregue em {{1}} dias \u00FAteis." + }, + { + "type": "FOOTER", + "text": "Esta mensagem \u00E9 de uma empresa n\u00E3o verificada." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "es", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "\u00F3 tu paquete. La entrega se realizar\u00E1 en {{1}} d\u00ED." + }, + { + "type": "FOOTER", + "text": "Este mensaje proviene de un negocio no verificado." + } + ] + } + }, + { + "name": "sample_shipping_confirmation", + "language": "id", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Paket Anda sudah dikirim. Paket akan sampai dalam {{1}} hari kerja." + }, + { + "type": "FOOTER", + "text": "Pesan ini berasal dari bisnis yang tidak terverifikasi." + } + ] + } + }, + { + "name": "appointment_reminder", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Dear {{1}} {{2}}, your next appointment with {{3}} is scheduled for {{4}}. Reply YES to confirm.", + "example": { + "body_text": [ + [ + "Eugenia", + "Lopez", + "Lamna Healthcare", + "September 25, 2022 at 9:00 AM" + ] + ] + } + } + ] + } + }, + { + "name": "order_confirmation", + "language": "en_US", + "channelType": "whatsApp", + "status": "approved", + "whatsApp": { + "content": [ + { + "type": "BODY", + "text": "Your {{1}} order has been placed. Track order updates {{2}} Reply HELP for help." + } + ] + } + } + ], + "nextLink": "/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview\u0026continuationToken=MjQZD" + } + }, + { + "RequestUri": "https://sanitized.communication.azure.com/messages/channels/59aced66-68ae-4b7a-8430-36f4c5dfa328/templates?api-version=2023-08-24-preview\u0026continuationToken=MjQZD", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-63e66c13220b3335fcbdb4df1ed96f6a-eb2f17bfb01d43af-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "1aa6ae78185f51d4580dc8de10c4a984", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:20 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "12", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:20 GMT", + "MS-CV": "rqf4J1VvAk212bBLYuXaeQ.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "04K0gZQAAAAAl4x0KVzvNRaJ8koPoFkw/WVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "337ms" + }, + "ResponseBody": { + "value": [] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1377625755", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendFlightConfirmationTemplateMessageShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendFlightConfirmationTemplateMessageShouldSucceed.json new file mode 100644 index 0000000000000..590a7dd4bda07 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendFlightConfirmationTemplateMessageShouldSucceed.json @@ -0,0 +1,104 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "584", + "Content-Type": "application/json", + "traceparent": "00-5b302ea9abb9c00f631dfe69dbe8d2d0-b87cd84b819a53a5-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "c0cebc46eeecc75e0bc5b321ea6d0f82", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:21 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_flight_confirmation", + "language": "en_us", + "values": { + "document": { + "kind": "document", + "document": { + "url": "https://go.microsoft.com/fwlink/?linkid=2131549" + } + }, + "firstName": { + "kind": "text", + "text": { + "text": "Gloria" + } + }, + "lastName": { + "kind": "text", + "text": { + "text": "Li" + } + }, + "date": { + "kind": "text", + "text": { + "text": "July 1st, 2023" + } + } + }, + "bindings": { + "whatsApp": { + "header": [ + { + "refValue": "document" + } + ], + "body": [ + { + "refValue": "firstName" + }, + { + "refValue": "lastName" + }, + { + "refValue": "date" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:21 GMT", + "MS-CV": "x/NvXQjmrEKJhELrhdK9lQ.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "04a0gZQAAAABGakUZz/AzQ63klzOmukJMWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "870ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "973115cb-7c71-4447-8b69-ca63f52107e3", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1148499426", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendFlightConfirmationTemplateMessageShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendFlightConfirmationTemplateMessageShouldSucceedAsync.json new file mode 100644 index 0000000000000..11bb274c003e0 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendFlightConfirmationTemplateMessageShouldSucceedAsync.json @@ -0,0 +1,104 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "584", + "Content-Type": "application/json", + "traceparent": "00-dac936a57341dff0d9745b4fa978bab5-7ef27d78253f922e-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "16559d33213de4b550542f081050671e", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:28 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_flight_confirmation", + "language": "en_us", + "values": { + "document": { + "kind": "document", + "document": { + "url": "https://go.microsoft.com/fwlink/?linkid=2131549" + } + }, + "firstName": { + "kind": "text", + "text": { + "text": "Gloria" + } + }, + "lastName": { + "kind": "text", + "text": { + "text": "Li" + } + }, + "date": { + "kind": "text", + "text": { + "text": "July 1st, 2023" + } + } + }, + "bindings": { + "whatsApp": { + "header": [ + { + "refValue": "document" + } + ], + "body": [ + { + "refValue": "firstName" + }, + { + "refValue": "lastName" + }, + { + "refValue": "date" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:28 GMT", + "MS-CV": "JqdH6Sk4wUGI1V5eW7VAzA.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "06K0gZQAAAABzg34ku7ZrRrkccoq7KgiZWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "803ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "1851243d-de4d-4923-a39d-c31016e6e0d1", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1598327269", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendHappyHourAnnocementTemplateMessageShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendHappyHourAnnocementTemplateMessageShouldSucceed.json new file mode 100644 index 0000000000000..8ea56a2b5aef9 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendHappyHourAnnocementTemplateMessageShouldSucceed.json @@ -0,0 +1,95 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "519", + "Content-Type": "application/json", + "traceparent": "00-3d664034721f674f6386bfb96f8c9ec6-68032dc64a7533b3-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "ed9f2d6c6e5bd4362604199b56d95a69", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:22 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_happy_hour_announcement", + "language": "en_us", + "values": { + "venue": { + "kind": "text", + "text": { + "text": "Starbucks" + } + }, + "time": { + "kind": "text", + "text": { + "text": "Today 2-4PM" + } + }, + "video": { + "kind": "video", + "video": { + "url": "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4" + } + } + }, + "bindings": { + "whatsApp": { + "header": [ + { + "refValue": "video" + } + ], + "body": [ + { + "refValue": "venue" + }, + { + "refValue": "time" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:22 GMT", + "MS-CV": "AnsPlmXunUCI1P4Wejk6xQ.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "04q0gZQAAAADnbAFnc4G6SLP6f6LHfdtmWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "837ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "d6254a6d-0556-4a81-8627-f75320bd7d09", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1238209351", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendHappyHourAnnocementTemplateMessageShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendHappyHourAnnocementTemplateMessageShouldSucceedAsync.json new file mode 100644 index 0000000000000..781daf6ccf761 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendHappyHourAnnocementTemplateMessageShouldSucceedAsync.json @@ -0,0 +1,95 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "519", + "Content-Type": "application/json", + "traceparent": "00-8c1ba28a05a241978bb05ee096a24826-e540bf11a4767a89-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "1f70ecea5a455aa5532a232266791aac", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:29 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_happy_hour_announcement", + "language": "en_us", + "values": { + "venue": { + "kind": "text", + "text": { + "text": "Starbucks" + } + }, + "time": { + "kind": "text", + "text": { + "text": "Today 2-4PM" + } + }, + "video": { + "kind": "video", + "video": { + "url": "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4" + } + } + }, + "bindings": { + "whatsApp": { + "header": [ + { + "refValue": "video" + } + ], + "body": [ + { + "refValue": "venue" + }, + { + "refValue": "time" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:29 GMT", + "MS-CV": "Zh/m2eCriEeW8MvEapZZQQ.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "06a0gZQAAAABjP7mBv30CTKjJeqm72qMhWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "818ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "194c60fb-0ff1-4492-8afe-abfccb052f34", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1767657619", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendIssueResolutionTemplateMessageShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendIssueResolutionTemplateMessageShouldSucceed.json new file mode 100644 index 0000000000000..ba304e3c0bf58 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendIssueResolutionTemplateMessageShouldSucceed.json @@ -0,0 +1,97 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "507", + "Content-Type": "application/json", + "traceparent": "00-c91ff39b5d9256151777c286fb2930d4-bc6a49d24b15a8ba-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "5682e393246220dc2ffa1c9a29a74f06", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:23 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_issue_resolution", + "language": "en_us", + "values": { + "name": { + "kind": "text", + "text": { + "text": "Gloria" + } + }, + "yes": { + "kind": "quick_action", + "quickAction": { + "payload": "Yay!" + } + }, + "no": { + "kind": "quick_action", + "quickAction": { + "payload": "Nay!" + } + } + }, + "bindings": { + "whatsApp": { + "body": [ + { + "refValue": "name" + } + ], + "button": [ + { + "subType": "quickReply", + "refValue": "yes" + }, + { + "subType": "quickReply", + "refValue": "no" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:23 GMT", + "MS-CV": "ZrDgRvpSJEKn45UDZqY6lA.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "0460gZQAAAAAczrG8lIWTRr\u002BH\u002BKmjZUHYWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "642ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "77673d05-57de-4926-b22a-973e348ce44f", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1388647227", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendIssueResolutionTemplateMessageShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendIssueResolutionTemplateMessageShouldSucceedAsync.json new file mode 100644 index 0000000000000..4cb36c0ae984c --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendIssueResolutionTemplateMessageShouldSucceedAsync.json @@ -0,0 +1,97 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "507", + "Content-Type": "application/json", + "traceparent": "00-6d0fb03b868c08da6478265c59bbf923-d6fab23b44ad7f92-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "3605649c32ad65980526ecd19e6f197e", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:30 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_issue_resolution", + "language": "en_us", + "values": { + "name": { + "kind": "text", + "text": { + "text": "Gloria" + } + }, + "yes": { + "kind": "quick_action", + "quickAction": { + "payload": "Yay!" + } + }, + "no": { + "kind": "quick_action", + "quickAction": { + "payload": "Nay!" + } + } + }, + "bindings": { + "whatsApp": { + "body": [ + { + "refValue": "name" + } + ], + "button": [ + { + "subType": "quickReply", + "refValue": "yes" + }, + { + "subType": "quickReply", + "refValue": "no" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:30 GMT", + "MS-CV": "fye6SSfDHkezlLGxvthDhw.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "06q0gZQAAAADi54HnAk3eQJokVKM\u002B/YCMWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "745ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "eaaba955-e6f9-4cd9-96c8-f645f9d250e9", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1703708581", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageShouldSucceed.json new file mode 100644 index 0000000000000..81e91fe198631 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageShouldSucceed.json @@ -0,0 +1,55 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "126", + "Content-Type": "application/json", + "traceparent": "00-a19b8d7e5b13fd1afce0167aec3bce86-b4d288d5ee0b9624-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "fb098fd65d54824e5e846fc9674db0c4", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:24 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "text", + "content": "LiveTest" + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:24 GMT", + "MS-CV": "ZIHd9FLNMU6nhxdZ3\u002Bjfbg.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "05K0gZQAAAADyMGec3lgrR5g0sQsmsXQJWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "728ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "3627b7be-1d1b-4506-9aa9-f38e07235191", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1281624781", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageShouldSucceedAsync.json new file mode 100644 index 0000000000000..27686b24ba572 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageShouldSucceedAsync.json @@ -0,0 +1,55 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "126", + "Content-Type": "application/json", + "traceparent": "00-28291313fcabb2734dbbbe464f6b17bc-30b2b90f988ba3c2-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "b66516d31b3a94219e3ab990d3b7247e", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:31 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "text", + "content": "LiveTest" + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:31 GMT", + "MS-CV": "GO2FCAzOUkaLPShPRD5Umw.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "0660gZQAAAACtE3\u002BLpKqTRKUjpLdT6sUmWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "724ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "82eff05b-8d81-43e8-b760-a0fcf81d2764", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "800021773", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageWithAzureKeyCredentialShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageWithAzureKeyCredentialShouldSucceed.json new file mode 100644 index 0000000000000..b6d591cbe9326 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageWithAzureKeyCredentialShouldSucceed.json @@ -0,0 +1,55 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "126", + "Content-Type": "application/json", + "traceparent": "00-b9ccba99cf859a0f08517056b168adf5-f31f09e84ac8fdba-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "0594c92d3d032fa3b57b67c8e02b4ef6", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:24 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "text", + "content": "LiveTest" + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:25 GMT", + "MS-CV": "Gpo\u002BsOhLAkON12CWErZSow.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "05a0gZQAAAAAvIsKSMUUhQ6cSzgGCdixFWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "731ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "b77d2e27-721a-4a85-b8c2-49229592ed7e", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1061618726", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageWithAzureKeyCredentialShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageWithAzureKeyCredentialShouldSucceedAsync.json new file mode 100644 index 0000000000000..928767a21d976 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMessageWithAzureKeyCredentialShouldSucceedAsync.json @@ -0,0 +1,55 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "126", + "Content-Type": "application/json", + "traceparent": "00-0f206a1b799efa69be54d322bcfeac63-d8a8563506aaecf6-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "fb76eef7f35060afa689256f8e41d40b", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:31 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "text", + "content": "LiveTest" + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:32 GMT", + "MS-CV": "LJRUTRFezk\u002BjQZcBHC0fGQ.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "0660gZQAAAACGCnGn5Q9STbDvRqzmwqTXWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "747ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "e909a302-c3a7-4a8e-b606-e2441411c1e8", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1573986230", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMovieTicketConfirmationTemplateMessageShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMovieTicketConfirmationTemplateMessageShouldSucceed.json new file mode 100644 index 0000000000000..22e33c9e7eb63 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMovieTicketConfirmationTemplateMessageShouldSucceed.json @@ -0,0 +1,113 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "679", + "Content-Type": "application/json", + "traceparent": "00-28a069dec931b615a4a192902c7bdae4-ccbe83da90024398-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "c6d70676df5992d30b28968e6ddee0d0", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:25 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_movie_ticket_confirmation", + "language": "en_us", + "values": { + "image": { + "kind": "image", + "image": { + "url": "https://upload.wikimedia.org/wikipedia/commons/3/30/Building92microsoft.jpg" + } + }, + "title": { + "kind": "text", + "text": { + "text": "Avengers" + } + }, + "time": { + "kind": "text", + "text": { + "text": "July 1st, 2023 12:30PM" + } + }, + "venue": { + "kind": "text", + "text": { + "text": "Cineplex" + } + }, + "seats": { + "kind": "text", + "text": { + "text": "Seat 1A" + } + } + }, + "bindings": { + "whatsApp": { + "header": [ + { + "refValue": "image" + } + ], + "body": [ + { + "refValue": "title" + }, + { + "refValue": "time" + }, + { + "refValue": "venue" + }, + { + "refValue": "seats" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:26 GMT", + "MS-CV": "eeFMv\u002BsqPUiznrNh9XsuRA.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "05a0gZQAAAABORaHDlyiKTZjQiCJGKEyFWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "789ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "ef59fa36-dec4-415e-b784-ebc01082370f", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1486206713", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMovieTicketConfirmationTemplateMessageShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMovieTicketConfirmationTemplateMessageShouldSucceedAsync.json new file mode 100644 index 0000000000000..bbfb48d3fe32b --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendMovieTicketConfirmationTemplateMessageShouldSucceedAsync.json @@ -0,0 +1,113 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "679", + "Content-Type": "application/json", + "traceparent": "00-373af7b647622765e299dec47f79fae4-1d0c7e7a9dd25051-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "ac66a37a6fc67070d329bcc5bb9fef70", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:32 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_movie_ticket_confirmation", + "language": "en_us", + "values": { + "image": { + "kind": "image", + "image": { + "url": "https://upload.wikimedia.org/wikipedia/commons/3/30/Building92microsoft.jpg" + } + }, + "title": { + "kind": "text", + "text": { + "text": "Avengers" + } + }, + "time": { + "kind": "text", + "text": { + "text": "July 1st, 2023 12:30PM" + } + }, + "venue": { + "kind": "text", + "text": { + "text": "Cineplex" + } + }, + "seats": { + "kind": "text", + "text": { + "text": "Seat 1A" + } + } + }, + "bindings": { + "whatsApp": { + "header": [ + { + "refValue": "image" + } + ], + "body": [ + { + "refValue": "title" + }, + { + "refValue": "time" + }, + { + "refValue": "venue" + }, + { + "refValue": "seats" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:32 GMT", + "MS-CV": "0P0MHOLtSEW5XPRLAshBuA.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "07K0gZQAAAABcrp2ZajUFS4N\u002BBuFIG/KLWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "788ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "afda89b5-906f-4131-b98b-3f25f6f7564c", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "48928599", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendPurchaseFeedbackTemplateMessageShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendPurchaseFeedbackTemplateMessageShouldSucceed.json new file mode 100644 index 0000000000000..b270369016485 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendPurchaseFeedbackTemplateMessageShouldSucceed.json @@ -0,0 +1,86 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "456", + "Content-Type": "application/json", + "traceparent": "00-c7c3e7a3626b5967930ed5cf378fa681-e72bfd2a03a8e038-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "f3855ba96456edafd257c159fe5a515e", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:26 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_purchase_feedback", + "language": "en_us", + "values": { + "image": { + "kind": "image", + "image": { + "url": "https://upload.wikimedia.org/wikipedia/commons/3/30/Building92microsoft.jpg" + } + }, + "product": { + "kind": "text", + "text": { + "text": "Microsoft Office" + } + } + }, + "bindings": { + "whatsApp": { + "header": [ + { + "refValue": "image" + } + ], + "body": [ + { + "refValue": "product" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:26 GMT", + "MS-CV": "3XJpA1EE\u002BEuvg8eA5pH9qw.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "05q0gZQAAAACv3m4YFraBS4ouf/dAwXXPWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "772ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "9d32a9ba-535a-45a3-b314-cf89f2d1c6fc", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "200691319", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendPurchaseFeedbackTemplateMessageShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendPurchaseFeedbackTemplateMessageShouldSucceedAsync.json new file mode 100644 index 0000000000000..cdface20e8650 --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendPurchaseFeedbackTemplateMessageShouldSucceedAsync.json @@ -0,0 +1,86 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "456", + "Content-Type": "application/json", + "traceparent": "00-913861f2b409168794dfe53454963f50-7adf8c14a29e5b7d-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "9af600b4717209ed7b6413a938b3c74a", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:33 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_purchase_feedback", + "language": "en_us", + "values": { + "image": { + "kind": "image", + "image": { + "url": "https://upload.wikimedia.org/wikipedia/commons/3/30/Building92microsoft.jpg" + } + }, + "product": { + "kind": "text", + "text": { + "text": "Microsoft Office" + } + } + }, + "bindings": { + "whatsApp": { + "header": [ + { + "refValue": "image" + } + ], + "body": [ + { + "refValue": "product" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:33 GMT", + "MS-CV": "/Fs2gutpikuYNqK17XF8sw.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "07a0gZQAAAAB767DXOlxrSJyaGRAqau0jWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "818ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "a8224921-46df-4880-95a9-fcf7a4552047", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1926562621", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendShippingConfirmationTemplateMessageShouldSucceed.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendShippingConfirmationTemplateMessageShouldSucceed.json new file mode 100644 index 0000000000000..7a4b8f0aad25c --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendShippingConfirmationTemplateMessageShouldSucceed.json @@ -0,0 +1,75 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "298", + "Content-Type": "application/json", + "traceparent": "00-c5094b4dab6e94babfa4474517fdceca-b63405a9b5f0ba06-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "64ad9df3e9f199cd4d8163643796ea15", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:27 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_shipping_confirmation", + "language": "en_us", + "values": { + "threeDays": { + "kind": "text", + "text": { + "text": "3" + } + } + }, + "bindings": { + "whatsApp": { + "body": [ + { + "refValue": "threeDays" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:27 GMT", + "MS-CV": "sgJSvemGzkS2nQ7\u002BkUAV0g.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "0560gZQAAAADh70gXXPljTLoAHPCD1L9mWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "731ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "f9b7d2c0-2203-4efa-ab44-7ce810564491", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1830441038", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendShippingConfirmationTemplateMessageShouldSucceedAsync.json b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendShippingConfirmationTemplateMessageShouldSucceedAsync.json new file mode 100644 index 0000000000000..4085a444bcb6b --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/SessionRecords/NotificationMessagesClientLiveTests/SendShippingConfirmationTemplateMessageShouldSucceedAsync.json @@ -0,0 +1,75 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/messages/notifications/:send?api-version=2023-08-24-preview", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "Content-Length": "298", + "Content-Type": "application/json", + "traceparent": "00-eb20ca5d3d660ee50b61e27d7de4b63b-09c1259b41262bc8-00", + "User-Agent": "azsdk-net-Communication.Messages/1.0.0-alpha.20231006.1 (.NET 7.0.11; Microsoft Windows 10.0.22621)", + "x-ms-client-request-id": "09535b8bdef4aa8251b74a2a35a5ab0b", + "x-ms-content-sha256": "Sanitized", + "x-ms-date": "Sat, 07 Oct 2023 01:01:34 GMT", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": { + "channelRegistrationId": "59aced66-68ae-4b7a-8430-36f4c5dfa328", + "to": [ + "\u002B16041234567" + ], + "type": "template", + "template": { + "name": "sample_shipping_confirmation", + "language": "en_us", + "values": { + "threeDays": { + "kind": "text", + "text": { + "text": "3" + } + } + }, + "bindings": { + "whatsApp": { + "body": [ + { + "refValue": "threeDays" + } + ] + } + } + } + }, + "StatusCode": 202, + "ResponseHeaders": { + "api-supported-versions": "2023-02-01-preview, 2023-08-24-preview", + "Content-Length": "87", + "Content-Type": "application/json; charset=utf-8", + "Date": "Sat, 07 Oct 2023 01:01:34 GMT", + "MS-CV": "bl2BfznVskaJWGHFBBpgHg.0", + "Request-Context": "appId=", + "Strict-Transport-Security": "max-age=2592000", + "X-Azure-Ref": "07q0gZQAAAADXuVvCzWUGSoBtUN5uY4NzWVZSMzExMDAwMTE1MDQ1ADlmYzdiNTE5LWE4Y2MtNGY4OS05MzVlLWM5MTQ4YWUwOWU4MQ==", + "X-Cache": "CONFIG_NOCACHE", + "X-Processing-Time": "766ms" + }, + "ResponseBody": { + "receipts": [ + { + "messageId": "0f574fa9-8357-41f1-b86a-cf86ac83d306", + "to": "\u002B16041234567" + } + ] + } + } + ], + "Variables": { + "COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING": "endpoint=https://sanitized.communication.azure.com/;accesskey=Kg==", + "RandomSeed": "1946321366", + "RECIPIENT_IDENTIFIER": "\u002B16041234567", + "SENDER_CHANNEL_REGISTRATION_ID": "59aced66-68ae-4b7a-8430-36f4c5dfa328" + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/TemplateClient/MessageTemplateClientLiveTests.cs b/sdk/communication/Azure.Communication.Messages/tests/TemplateClient/MessageTemplateClientLiveTests.cs new file mode 100644 index 0000000000000..bbb7787da395d --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/TemplateClient/MessageTemplateClientLiveTests.cs @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading.Tasks; +using Azure.Core.TestFramework; +using NUnit.Framework; + +namespace Azure.Communication.Messages.Tests +{ + public class MessageTemplateClientLiveTests : MessagesLiveTestBase + { + public MessageTemplateClientLiveTests(bool isAsync) : base(isAsync) + { + } + + [Test] + public Task GetTemplatesShouldSucceed() + { + // Arrange + MessageTemplateClient messageTemplateClient = CreateInstrumentedMessageTemplateClient(); + string channelRegistrationId = TestEnvironment.SenderChannelRegistrationId; + + // Act + AsyncPageable templates = messageTemplateClient.GetTemplatesAsync(channelRegistrationId); + + // Assert + Assert.IsNotNull(templates); + var templatesEnumerable = templates.ToEnumerableAsync().Result; + Assert.IsNotEmpty(templatesEnumerable); + foreach (MessageTemplateItem template in templatesEnumerable) + { + Assert.IsNotNull(template.Name); + Assert.IsNotNull(template.Language); + } + + return Task.CompletedTask; + } + + [Test] + public Task GetTemplatesWithAzureKeyCredentialShouldSucceed() + { + // Arrange + MessageTemplateClient messageTemplateClient = CreateInstrumentedMessageTemplateClientWithAzureKeyCredential(); + string channelRegistrationId = TestEnvironment.SenderChannelRegistrationId; + + // Act + AsyncPageable templates = messageTemplateClient.GetTemplatesAsync(channelRegistrationId); + + // Assert + Assert.IsNotNull(templates); + var templatesEnumerable = templates.ToEnumerableAsync().Result; + Assert.IsNotEmpty(templatesEnumerable); + foreach (MessageTemplateItem template in templatesEnumerable) + { + Assert.IsNotNull(template.Name); + Assert.IsNotNull(template.Language); + } + + return Task.CompletedTask; + } + } +} diff --git a/sdk/communication/Azure.Communication.Messages/tests/TemplateClient/MessageTemplateClientTests.cs b/sdk/communication/Azure.Communication.Messages/tests/TemplateClient/MessageTemplateClientTests.cs new file mode 100644 index 0000000000000..bc4ef6d54886d --- /dev/null +++ b/sdk/communication/Azure.Communication.Messages/tests/TemplateClient/MessageTemplateClientTests.cs @@ -0,0 +1,95 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading.Tasks; +using Azure.Core.TestFramework; +using NUnit.Framework; + +namespace Azure.Communication.Messages.Tests +{ + public class MessageTemplateClientTests : ClientTestBase + { + protected const string ConnectionString = "endpoint=https://contoso.azure.com/;accesskey=ZHVtbXlhY2Nlc3NrZXk="; + private const string GetTemplatesApiResponsePayload = "{\"value\":[{\"name\":\"optin_confirmation\",\"language\":\"en_US\",\"channelType\":\"whatsApp\",\"status\":\"approved\",\"whatsApp\":{\"content\":[{\"type\":\"BODY\",\"text\":\"Reply {{1}} to receive {{2}}. Txt {{3}} for HELP, Txt {{4}} to opt-out.\"}]}},{\"name\":\"sample_flight_confirmation\",\"language\":\"en_US\",\"channelType\":\"whatsApp\",\"status\":\"approved\",\"whatsApp\":{\"content\":[{\"type\":\"HEADER\",\"format\":\"DOCUMENT\"},{\"type\":\"BODY\",\"text\":\"This is your flight confirmation for {{1}}-{{2}} on {{3}}.\"},{\"type\":\"FOOTER\",\"text\":\"This message is from an unverified business.\"}]}},{\"name\":\"sample_happy_hour_announcement\",\"language\":\"pt_BR\",\"channelType\":\"whatsApp\",\"status\":\"approved\",\"whatsApp\":{\"content\":[{\"type\":\"HEADER\",\"format\":\"VIDEO\"},{\"type\":\"BODY\",\"text\":\"O happy hour chegou! \\ud83c\\udf7a😀\\ud83c\\udf78\\nSeja feliz e aproveite o dia. \\ud83c\\udf89\\nLocal: {{1}}\\nHorário: {{2}}\"},{\"type\":\"FOOTER\",\"text\":\"Esta mensagem é de uma empresa não verificada.\"}]}}]}"; + + public MessageTemplateClientTests(bool isAsync) : base(isAsync) + { + } + + [Test] + public void Constructor_InvalidParamsThrows() + { + Assert.Throws(() => new MessageTemplateClient(null)); + Assert.Throws(() => new MessageTemplateClient(string.Empty)); + Assert.Throws(() => new MessageTemplateClient(" ")); + Assert.Throws(() => new MessageTemplateClient("test")); + } + + [Test] + public async Task GetTemplates_ValidParams_ShouldSucceed() + { + //arrange + MessageTemplateClient messageTemplateClient = CreateMockMessageTemplateClient(200, GetTemplatesApiResponsePayload); + var channelId = Guid.NewGuid().ToString(); + + //act + AsyncPageable templates = messageTemplateClient.GetTemplatesAsync(channelId); + + //assert + await foreach (MessageTemplateItem template in templates) + { + Assert.IsNotNull(template.Name); + Assert.IsNotNull(template.Language); + Assert.IsNotNull(template.Status); + Assert.AreEqual(template.ChannelType, CommunicationMessagesChannelType.WhatsApp); + } + } + + [Test] + public void GetTemplates_NullChannelId_Throws() + { + //arrange + MessageTemplateClient messageTemplateClient = CreateMockMessageTemplateClient(); + + //act & assert + Assert.Throws(() => messageTemplateClient.GetTemplatesAsync(null)); + } + + [Test] + public Task GetTemplates_InvalidChannelRegistrationId_ThrowsBadRequestException() + { + //arrange + MessageTemplateClient messageTemplateClient = CreateMockMessageTemplateClient(400); + + try + { + //act + messageTemplateClient.GetTemplatesAsync("invalidChannelRegistrationId"); + } + catch (RequestFailedException requestFailedException) + { + //assert + Assert.AreEqual(400, requestFailedException.Status); + } + + return Task.CompletedTask; + } + + private MessageTemplateClient CreateMockMessageTemplateClient(int responseCode = 200, string responseContent = null) + { + var mockResponse = new MockResponse(responseCode); + if (responseContent != null) + { + mockResponse.SetContent(responseContent); + } + + var MessageTemplateClientOptions = new CommunicationMessagesClientOptions + { + Transport = new MockTransport(mockResponse) + }; + + return new MessageTemplateClient(ConnectionString, MessageTemplateClientOptions); + } + } +} diff --git a/sdk/communication/Azure.Communication.sln b/sdk/communication/Azure.Communication.sln index d44b404a05aed..e0dd68e827437 100644 --- a/sdk/communication/Azure.Communication.sln +++ b/sdk/communication/Azure.Communication.sln @@ -68,6 +68,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Communication.CallAut EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Communication.CallAutomation.Tests", "Azure.Communication.CallAutomation\tests\Azure.Communication.CallAutomation.Tests.csproj", "{8E628698-3ECB-4FA0-BDDF-62E018FDA0CA}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Communication.Messages", "Azure.Communication.Messages\src\Azure.Communication.Messages.csproj", "{EC7299A9-8563-4FF3-97E2-CB3DDE8AEFBE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Communication.Messages.Tests", "Azure.Communication.Messages\tests\Azure.Communication.Messages.Tests.csproj", "{4232B393-700D-4AC5-9358-70ED4B98B0ED}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -190,6 +194,14 @@ Global {8E628698-3ECB-4FA0-BDDF-62E018FDA0CA}.Debug|Any CPU.Build.0 = Debug|Any CPU {8E628698-3ECB-4FA0-BDDF-62E018FDA0CA}.Release|Any CPU.ActiveCfg = Release|Any CPU {8E628698-3ECB-4FA0-BDDF-62E018FDA0CA}.Release|Any CPU.Build.0 = Release|Any CPU + {EC7299A9-8563-4FF3-97E2-CB3DDE8AEFBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC7299A9-8563-4FF3-97E2-CB3DDE8AEFBE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC7299A9-8563-4FF3-97E2-CB3DDE8AEFBE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC7299A9-8563-4FF3-97E2-CB3DDE8AEFBE}.Release|Any CPU.Build.0 = Release|Any CPU + {4232B393-700D-4AC5-9358-70ED4B98B0ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4232B393-700D-4AC5-9358-70ED4B98B0ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4232B393-700D-4AC5-9358-70ED4B98B0ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4232B393-700D-4AC5-9358-70ED4B98B0ED}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/sdk/communication/ci.yml b/sdk/communication/ci.yml index e1d00ba3b8e4c..fd304e1b64119 100644 --- a/sdk/communication/ci.yml +++ b/sdk/communication/ci.yml @@ -39,6 +39,8 @@ extends: safeName: AzureCommunicationCallingServer - name: Azure.Communication.Chat safeName: AzureCommunicationChat + - name: Azure.Communication.Messages + safeName: AzureCommunicationMessages - name: Azure.Communication.Common safeName: AzureCommunicationCommon - name: Azure.Communication.Email