Skip to content

Commit 012e2a5

Browse files
authored
Merge pull request #291458 from dbasantes/main
Create SMS Opt-out-api learning docs
2 parents 1c1ac0b + 1c1c1fe commit 012e2a5

File tree

6 files changed

+479
-2
lines changed

6 files changed

+479
-2
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
title: Short Message Service (SMS) Opt-Out Management API for Azure Communication Services
3+
titleSuffix: An Azure Communication Services concept document
4+
description: Provides an overview of the SMS Opt-Out Management API
5+
author: dbasantes
6+
services: azure-communication-services
7+
8+
ms.author: dbasantes
9+
ms.date: 12/04/2024
10+
ms.topic: conceptual
11+
ms.service: azure-communication-services
12+
ms.subservice: sms
13+
---
14+
# Opt-Out management overview
15+
The Opt-Out Management API enables you to manage opt-out requests for SMS messages. It provides a self-service platform for businesses to handle opt-out requests, ensuring compliance with regulations and protecting customer privacy.
16+
Currently, opt-out handling includes configuring responses to mandatory opt-out keywords, such as STOP/START/HELP and others. The responses are stored and the list of opted-out numbers is maintained in the Azure Communication Services Opt-Out database. This database management is automatic.
17+
The Opt-Out database contains entries added when a recipient sends an opt-out keyword. An entry includes the fields: Sender, Recipient, and Country. If a recipient opts back in, the corresponding entry is deleted.
18+
To learn more about how opt-out is handled at Azure Communication Services, read our [FAQ](https://learn.microsoft.com/azure/communication-services/concepts/sms/sms-faq#how-does-azure-communication-services-handle-opt-outs-for-short-codes.md) page.
19+
20+
## Opt-Out management API
21+
We're extending opt-out management by enabling you to manage the Opt-Out database via an API. This API allows adding, removing, or checking opt-out entries, overriding the automatic management.
22+
Key features include:
23+
24+
- **Maintaining an Opt-Out List:** The API maintains a centralized list of opt-out requests, enabling businesses to easily add, remove, and check individuals opting out of SMS communications.
25+
- **Enforcing Opt-Out Preferences:** The API integrates with the opt-out list to ensure that preferences are respected. No SMS messages should be sent to individuals who opt out.
26+
27+
## Next steps
28+
29+
Let's get started with the [SMS Opt-out API quickstart](../../quickstarts/sms/opt-out-api-quickstart.md).
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
title: Include file
3+
description: include file
4+
services: azure-communication-services
5+
author: dbasantes
6+
7+
ms.service: azure-communication-services
8+
ms.subservice: azure-communication-services
9+
ms.date: 12/06/2024
10+
ms.topic: include
11+
ms.custom: Include file
12+
ms.author: dbasantes
13+
---
14+
15+
Get started with Azure Communication Services SMS Opt-out API by applying the following C# sample code.
16+
17+
## Prerequisites
18+
19+
- An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
20+
- The .NET Core SDK version must be higher than v6 for your operating system.
21+
- An active Communication Services resource and connection string. See [Create a Communication Services resource](https://learn.microsoft.com/azure/communication-services/quickstarts/create-communication-resource).
22+
- An SMS-enabled telephone number. See [Get a phone number](https://learn.microsoft.com/azure/communication-services/quickstarts/telephony/get-phone-number).
23+
24+
## Sample code to use Opt-Out API
25+
26+
This sample demonstrates how to use the Opt-Out Management API in C# to programmatically add, remove, or check opt-out entries.
27+
28+
```cs
29+
using System.Globalization;
30+
using System.Security.Cryptography;
31+
using System.Text;
32+
33+
// Sample for Add action. Replace with Check or Remove as necessary.
34+
async Task SendOptOutAdd(string acsResourceConnectionString, string payload)
35+
{
36+
const string ApiPrivatePreviewVersion = "2024-12-10-preview";
37+
38+
const string dateHeader = "x-ms-date";
39+
40+
string accesskey = GetConnectionStringPart(acsResourceConnectionString, "accesskey");
41+
var endpointUri = new Uri(GetConnectionStringPart(acsResourceConnectionString, "endpoint"));
42+
43+
using var httpClient = new HttpClient();
44+
httpClient.BaseAddress = endpointUri;
45+
46+
string method = "POST";
47+
string baseAddress = httpClient.BaseAddress.ToString().TrimEnd('/');
48+
var requestUri = new Uri($"{baseAddress}/sms/optouts:add?api-version={ApiPrivatePreviewVersion }", UriKind.RelativeOrAbsolute);
49+
string hashedBody = ComputeSha256Hash(payload);
50+
string utcNowString = DateTimeOffset.UtcNow.ToString("r", CultureInfo.InvariantCulture);
51+
string stringToSign = $"{method}\n{requestUri.PathAndQuery}\n{utcNowString};{requestUri.Host};{hashedBody}";
52+
string signature = ComputeHmacSha256Hash(accesskey, stringToSign);
53+
string authHeader = $"HMAC-SHA256 SignedHeaders={dateHeader};host;x-ms-content-sha256&Signature={signature}";
54+
55+
using HttpRequestMessage request = new();
56+
request.Headers.TryAddWithoutValidation(dateHeader, utcNowString);
57+
request.Headers.TryAddWithoutValidation("x-ms-content-sha256", hashedBody);
58+
request.Headers.TryAddWithoutValidation("Authorization", authHeader);
59+
request.RequestUri = requestUri;
60+
request.Method = new HttpMethod(method);
61+
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");
62+
63+
HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
64+
65+
Console.WriteLine(response.StatusCode);
66+
Console.WriteLine(await response.Content.ReadAsStringAsync());
67+
Console.WriteLine(response.Headers.ToString());
68+
}
69+
70+
string ComputeSha256Hash(string rawData)
71+
{
72+
using SHA256 sha256Hash = SHA256.Create();
73+
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
74+
return Convert.ToBase64String(bytes);
75+
}
76+
77+
string ComputeHmacSha256Hash(string key, string rawData)
78+
{
79+
using HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(key));
80+
byte[] bytes = hmacSha256.ComputeHash(Encoding.ASCII.GetBytes(rawData));
81+
return Convert.ToBase64String(bytes);
82+
}
83+
84+
string GetConnectionStringPart(string acsResourceConnectionString, string key)
85+
{
86+
return acsResourceConnectionString.Split($"{key}=").Last().Split(';').First();
87+
}
88+
89+
// Usage
90+
91+
const string ConnectionString = "endpoint=https://[CONTOSO].communication.azure.com/;accesskey=******";
92+
var payload = System.Text.Json.JsonSerializer.Serialize(new
93+
{
94+
from = "+15551234567", //replace with your allowed sender number
95+
recipients = new[] {
96+
new { to = "+15550112233" } //replace with your recipient
97+
},
98+
});
99+
100+
await SendOptOutAdd(ConnectionString, payload);
101+
102+
```
103+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
---
2+
title: Include file
3+
description: Include file
4+
services: azure-communication-services
5+
author: dbasantes
6+
7+
ms.service: azure-communication-services
8+
ms.subservice: azure-communication-services
9+
ms.date: 12/06/2024
10+
ms.topic: include
11+
ms.custom: include file
12+
ms.author: dbasantes
13+
---
14+
15+
Get started with Azure Communication Services SMS Opt-out API by applying the following Java sample code.
16+
17+
## Prerequisites
18+
19+
- An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
20+
- Java Development Kit (JDK) version 8 or above.
21+
- An active Communication Services resource and connection string. See [Create a Communication Services resource](https://learn.microsoft.com/azure/communication-services/quickstarts/create-communication-resource).
22+
- An SMS-enabled telephone number. See [Get a phone number](https://learn.microsoft.com/azure/communication-services/quickstarts/telephony/get-phone-number).
23+
24+
## Sample code to use Opt-Out API
25+
26+
This sample demonstrates how to use the Opt-Out Management API in Java to programmatically add, remove, or check opt-out entries.
27+
28+
29+
```java
30+
// Sample for Add action. Replace with Check or Remove as necessary.
31+
public class App
32+
{
33+
public static void main(String[] args) throws Exception
34+
{
35+
String connectionString = "endpoint=https://[CONTOSO].communication.azure.com/;accesskey=******";
36+
37+
OptOutRequest payload = new OptOutRequest();
38+
payload.from = "+15551234567";
39+
payload.recipients = new ArrayList<Recipient>();
40+
payload.recipients.add(new Recipient("+15550112233"));
41+
42+
SendOptOut(connectionString, payload);
43+
}
44+
45+
public static void SendOptOutAdd(String connectionString, OptOutRequest payload) throws Exception
46+
{
47+
String apiVersion = "2024-12-10-preview";
48+
49+
String[] arrOfStr = connectionString.split(";");
50+
String endpoint = arrOfStr[0].split("=")[1];
51+
String accessKey = arrOfStr[1].split("=")[1];
52+
String body = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT).writeValueAsString(payload);
53+
String dateHeaderName = "x-ms-date";
54+
DateTimeFormatter headerDateFormat = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH).withZone(ZoneId.of("GMT"));
55+
String dateHeader = headerDateFormat.format(Instant.now());
56+
String verb = "POST";
57+
URI uri = URI.create(endpoint + "sms/optouts:add?api-version==" + apiVersion);
58+
String hostName = uri.getHost();
59+
String pathAndQuery = uri.getPath() + "?" + uri.getQuery();
60+
String encodedHash = Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-256").digest(body.getBytes(StandardCharsets.UTF_8)));
61+
String stringToSign = verb + '\n' + pathAndQuery + '\n' + dateHeader + ';' + hostName + ';' + encodedHash;
62+
Mac mac = Mac.getInstance("HmacSHA256");
63+
SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(accessKey.getBytes()), "HmacSHA256");
64+
mac.init(secretKeySpec);
65+
String signature = Base64.getEncoder().encodeToString(mac.doFinal(stringToSign.getBytes()));
66+
String authHeader = "HMAC-SHA256 SignedHeaders=" + dateHeaderName + ";host;x-ms-content-sha256&Signature=" + signature;
67+
68+
HttpClient client = HttpClients.custom().build();
69+
HttpUriRequest request = RequestBuilder
70+
.post(uri)
71+
.setHeader(HttpHeaders.CONTENT_TYPE, "application/json")
72+
.setHeader(dateHeaderName, dateHeader)
73+
.setHeader("x-ms-content-sha256", encodedHash)
74+
.setHeader("Authorization", authHeader)
75+
.setEntity(new StringEntity(body, "UTF-8"))
76+
.build();
77+
HttpResponse r = client.execute(request);
78+
HttpEntity entity = r.getEntity();
79+
}
80+
}
81+
82+
public class OptOutRequest
83+
{
84+
public String from;
85+
public ArrayList<Recipient> recipients;
86+
}
87+
88+
public class Recipient
89+
{
90+
public String to;
91+
}
92+
```
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: Include file
3+
description: include file
4+
services: azure-communication-services
5+
author: dbasantes
6+
7+
ms.service: azure-communication-services
8+
ms.subservice: azure-communication-services
9+
ms.date: 12/06/2024
10+
ms.topic: Include
11+
ms.custom: Include file
12+
ms.author: dbasantes
13+
---
14+
15+
Get started with Azure Communication Services SMS Opt-out API by using the following JavaScript sample code.
16+
17+
## Prerequisites
18+
19+
- An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
20+
- Browser or Node.js Active LTS and Maintenance LTS versions (8.11.1 and 10.14.1 are recommended).
21+
- An active Communication Services resource and connection string. See [Create a Communication Services resource](https://learn.microsoft.com/azure/communication-services/quickstarts/create-communication-resource).
22+
- An SMS-enabled telephone number. See [Get a phone number](https://learn.microsoft.com/azure/communication-services/quickstarts/telephony/get-phone-number).
23+
- [CryptoJS](https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/crypto-js/CryptoJS%20v3.1.2.zip) is JavaScript implementations of standard and secure cryptographic algorithms.
24+
25+
## Sample code to use Opt-Out API
26+
27+
This sample demonstrates how to use the Opt-Out Management API in JavaScript to programmatically add, remove, or check opt-out entries.
28+
29+
```html
30+
<script src="Scripts/CryptoJS/sha256-min.js" type="text/javascript"></script>
31+
<script src="Scripts/CryptoJS/hmac-sha256.js" type="text/javascript"></script>
32+
<script src="Scripts/CryptoJS/enc-base64-min.js" type="text/javascript"></script>
33+
34+
```
35+
36+
```js
37+
const ConnectionString = "endpoint=https://[CONTOSO].communication.azure.com/;accesskey=******";
38+
39+
// Sample for Add action. Replace with Check or Remove as necessary.
40+
function sendOptOutAdd(acsResourceConnectionString, payload, apiVersion = "2024-12-10-preview")
41+
{
42+
try
43+
{
44+
var acsRCS = acsResourceConnectionString
45+
.split(";")
46+
.map(i =>
47+
{
48+
var p = i.indexOf("=");
49+
return [i.substr(0, p), i.substr(p + 1)];
50+
})
51+
.reduce((a, i) => ({ ...a, [i[0]]: i[1] }), {});
52+
var uri = `${trimEnd(acsRCS.endpoint, "/")}/sms/optouts:add?api-version=${apiVersion}`;
53+
var url = new URL(uri);
54+
var method = "POST";
55+
var utcNow = new Date().toUTCString();
56+
var bodyJson = JSON.stringify(payload);
57+
var hashedBody = CryptoJS.SHA256(bodyJson).toString(CryptoJS.enc.Base64);
58+
var stringToSign = `${method}\n${url.pathname}${url.search}\n${utcNow};${url.host};${hashedBody}`;
59+
var signature = CryptoJS.HmacSHA256(stringToSign, CryptoJS.enc.Base64.parse(acsRCS.accesskey)).toString(CryptoJS.enc.Base64);
60+
61+
fetch(uri, {
62+
method: method,
63+
headers: {
64+
"content-type": "application/json",
65+
"x-ms-date": utcNow,
66+
"x-ms-content-sha256": hashedBody,
67+
Authorization: `HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=${signature}`
68+
},
69+
body: bodyJson
70+
})
71+
.then(response => response.json())
72+
.then(console.warn)
73+
.catch(console.error);
74+
}
75+
catch (ex)
76+
{
77+
console.error(ex);
78+
}
79+
}
80+
81+
function trimEnd(s, c)
82+
{
83+
while (s.slice(-1) == c)
84+
s = s.slice(0, -1);
85+
return s;
86+
}
87+
88+
// Usage
89+
90+
var payload = {
91+
from: "+15551234567",
92+
recipients: [
93+
{ to: "+15550112233" }
94+
],
95+
};
96+
97+
sendOptOutAdd(ConnectionString, payload);
98+
99+
```
100+

0 commit comments

Comments
 (0)