API (HMAC) を使用して OptOut API 要求を送信する

Von Bedeutung

Azure Communication Services のこの機能は現在プレビュー中です。 プレビュー段階の機能は一般公開されており、新規および既存の Microsoft のすべてのお客様が使用できます。

プレビューAPIとSDKは、サービスレベル契約なしで提供されます。 運用環境のワークロードには使用しないことをお勧めします。 特定の機能がサポートされていないか、機能が制約されている可能性があります。

詳細については、「 Microsoft Azure プレビューの追加使用条件」を参照してください。

この記事では、ハッシュ メッセージ認証コード (HMAC) ベースの認証を使用して、Azure Communication Services リソースのオプトアウト管理を有効にする方法について説明します。

クイック スタート: API (HMAC) を使用して OptOut API 要求を送信する

オプトアウト API 要求の送信は、Azure Communication Services Postman チュートリアルで説明されている SMS に似ています。ただし、OptOut アクション (追加、削除、またはチェック) のエンドポイントと本文が異なります。 要求本文は、すべてのアクションで同じ構造を持ちますが、応答の内容は若干異なります。

エンドポイント

アクション エンドポイント
追加 {{endpoint}}/sms/optouts:add?api-version=2024-12-10-preview
[削除] {{endpoint}}/sms/optouts:remove?api-version=2024-12-10-preview
{{endpoint}}/sms/optouts:check?api-version=2024-12-10-preview

さまざまな言語の例を次に示します。

要求のサンプル

要求ヘッダー

ヘッダー
コンテンツタイプ application/json
x-ms-date 2023年8月10日(木) 12:39:55 GMT
x-ms-content-sha256 JKUqoPANwVA55u/NOCsS0Awa4cYrKKNtBwUqoaqrob0=
承認 HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=IMbd3tE3nOgEkeUQGng6oQew5aEcrZJQqHkyq8qsbLg=

要求本文

{
    "from": "+15551234567",
    "recipients": [
        {
            "to": "+15550112233"
        },
        {
            "to": "+15550112234"
        }
    ]
}

応答のサンプル

一般に、応答の内容はすべてのアクションで同じであり、受信者ごとに成功または失敗の HttpStatusCode が含まれます。 唯一の違いは、Check フラグも返す isOptedOut アクションです。

応答の状態

  • 200 OK

OptOut アクションの応答本文を追加する

{
    "value": [
        {
            "to": "+15550112233",
            "httpStatusCode": 200
        },
        {
            "to": "+15550112234",
            "httpStatusCode": 200
        }
    ]
}

OptOut アクションの応答本文を削除する

{
    "value": [
        {
            "to": "+15550112233",
            "httpStatusCode": 200
        },
        {
            "to": "+15550112234",
            "httpStatusCode": 200
        }
    ]
}

OptOut アクションの応答本文をチェックする

{
    "value": [
        {
            "to": "+15550112233",
            "httpStatusCode": 200,
            "isOptedOut": true
        },
        {
            "to": "+15550112234",
            "httpStatusCode": 200,
            "isOptedOut": false
        }
    ]
}

サンプル コード

次の C# サンプル コードを適用して、Azure Communication Services SMS オプトアウト API の使用を開始します。

前提条件

オプトアウト API を使用するサンプル コード

このサンプルでは、C# で Opt-Out Management API を使用して、プログラムによってオプトアウト エントリを追加、削除、またはチェックする方法を示します。

using System.Globalization;
using System.Security.Cryptography;
using System.Text;

// Sample for Add action. Replace with Check or Remove as necessary.
async Task SendOptOutAdd(string acsResourceConnectionString, string payload)
{
    const string ApiPrivatePreviewVersion = "2024-12-10-preview";

    const string dateHeader = "x-ms-date";

    string accesskey = GetConnectionStringPart(acsResourceConnectionString, "accesskey");
    var endpointUri = new Uri(GetConnectionStringPart(acsResourceConnectionString, "endpoint"));

    using var httpClient = new HttpClient();
    httpClient.BaseAddress = endpointUri;

    string method = "POST";
    string baseAddress = httpClient.BaseAddress.ToString().TrimEnd('/');
    var requestUri = new Uri($"{baseAddress}/sms/optouts:add?api-version={ApiPrivatePreviewVersion }", UriKind.RelativeOrAbsolute);
    string hashedBody = ComputeSha256Hash(payload);
    string utcNowString = DateTimeOffset.UtcNow.ToString("r", CultureInfo.InvariantCulture);
    string stringToSign = $"{method}\n{requestUri.PathAndQuery}\n{utcNowString};{requestUri.Host};{hashedBody}";
    string signature = ComputeHmacSha256Hash(accesskey, stringToSign);
    string authHeader = $"HMAC-SHA256 SignedHeaders={dateHeader};host;x-ms-content-sha256&Signature={signature}";

    using HttpRequestMessage request = new();
    request.Headers.TryAddWithoutValidation(dateHeader, utcNowString);
    request.Headers.TryAddWithoutValidation("x-ms-content-sha256", hashedBody);
    request.Headers.TryAddWithoutValidation("Authorization", authHeader);
    request.RequestUri = requestUri;
    request.Method = new HttpMethod(method);
    request.Content = new StringContent(payload, Encoding.UTF8, "application/json");

    HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

    Console.WriteLine(response.StatusCode);
    Console.WriteLine(await response.Content.ReadAsStringAsync());
    Console.WriteLine(response.Headers.ToString());
}

string ComputeSha256Hash(string rawData)
{
    using SHA256 sha256Hash = SHA256.Create();
    byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
    return Convert.ToBase64String(bytes);
}

string ComputeHmacSha256Hash(string key, string rawData)
{
    using HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(key));
    byte[] bytes = hmacSha256.ComputeHash(Encoding.ASCII.GetBytes(rawData));
    return Convert.ToBase64String(bytes);
}

string GetConnectionStringPart(string acsResourceConnectionString, string key)
{
    return acsResourceConnectionString.Split($"{key}=").Last().Split(';').First();
}

// Usage

const string ConnectionString = "endpoint=https://[CONTOSO].communication.azure.com/;accesskey=******";
var payload = System.Text.Json.JsonSerializer.Serialize(new
{
    from = "+15551234567", //replace with your allowed sender number
    recipients = new[] {
        new { to = "+15550112233" } //replace with your recipient
    },
});

await SendOptOutAdd(ConnectionString, payload);

次の JavaScript サンプル コードを適用して、Azure Communication Services SMS オプトアウト API の使用を開始します。

前提条件

  • アクティブなサブスクリプションが含まれる Azure アカウント。 無料でアカウントを作成できます
  • Browser または Node.js アクティブ LTS およびメンテナンス LTS バージョン (8.11.1 および 10.14.1 を推奨)。
  • アクティブな Communication Services リソースと接続文字列。 「Communication Services リソースを作成する」を参照してください。
  • SMS が有効になっている電話番号。 「電話番号を取得する」を参照してください。
  • CryptoJS は、標準およびセキュリティで保護された暗号アルゴリズムの JavaScript 実装です。

オプトアウト API を使用するサンプル コード

このサンプルでは、JavaScript で Opt-Out Management API を使用して、プログラムによってオプトアウト エントリを追加、削除、またはチェックする方法を示します。

<script src="Scripts/CryptoJS/sha256-min.js" type="text/javascript"></script>
<script src="Scripts/CryptoJS/hmac-sha256.js" type="text/javascript"></script>
<script src="Scripts/CryptoJS/enc-base64-min.js" type="text/javascript"></script>

const ConnectionString = "endpoint=https://[CONTOSO].communication.azure.com/;accesskey=******";

// Sample for Add action. Replace with Check or Remove as necessary.
function sendOptOutAdd(acsResourceConnectionString, payload, apiVersion = "2024-12-10-preview")
{
    try
    {
        var acsRCS = acsResourceConnectionString
            .split(";")
            .map(i =>
            {
                var p = i.indexOf("=");
                return [i.substr(0, p), i.substr(p + 1)];
            })
            .reduce((a, i) => ({ ...a, [i[0]]: i[1] }), {});
        var uri = `${trimEnd(acsRCS.endpoint, "/")}/sms/optouts:add?api-version=${apiVersion}`;
        var url = new URL(uri);
        var method = "POST";
        var utcNow = new Date().toUTCString();
        var bodyJson = JSON.stringify(payload);
        var hashedBody = CryptoJS.SHA256(bodyJson).toString(CryptoJS.enc.Base64);
        var stringToSign = `${method}\n${url.pathname}${url.search}\n${utcNow};${url.host};${hashedBody}`;
        var signature = CryptoJS.HmacSHA256(stringToSign, CryptoJS.enc.Base64.parse(acsRCS.accesskey)).toString(CryptoJS.enc.Base64);

        fetch(uri, {
            method: method,
            headers: {
                "content-type": "application/json",
                "x-ms-date": utcNow,
                "x-ms-content-sha256": hashedBody,
                Authorization: `HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=${signature}`
            },
            body: bodyJson
        })
        .then(response => response.json())
        .then(console.warn)
        .catch(console.error);
    }
    catch (ex)
    {
        console.error(ex);
    }
}

function trimEnd(s, c)
{
    while (s.slice(-1) == c)
        s = s.slice(0, -1);
    return s;
}

// Usage

var payload = {
    from: "+15551234567",
    recipients: [
        { to: "+15550112233" }
    ],
};

sendOptOutAdd(ConnectionString, payload);

次の Java サンプル コードを適用して、Azure Communication Services SMS オプトアウト API の使用を開始します。

前提条件

オプトアウト API を使用するサンプル コード

このサンプルでは、Java で Opt-Out Management API を使用して、プログラムによってオプトアウト エントリを追加、削除、またはチェックする方法を示します。

// Sample for Add action. Replace with Check or Remove as necessary.
public class App
{
    public static void main(String[] args) throws Exception
    {
        String connectionString = "endpoint=https://[CONTOSO].communication.azure.com/;accesskey=******";

        OptOutRequest payload = new OptOutRequest();
        payload.from = "+15551234567";
        payload.recipients = new ArrayList<Recipient>();
        payload.recipients.add(new Recipient("+15550112233"));

        SendOptOut(connectionString, payload);
    }

    public static void SendOptOutAdd(String connectionString, OptOutRequest payload) throws Exception
    {
        String apiVersion = "2024-12-10-preview";

        String[] arrOfStr = connectionString.split(";");
        String endpoint = arrOfStr[0].split("=")[1];
        String accessKey = arrOfStr[1].split("=")[1];
        String body = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT).writeValueAsString(payload);
        String dateHeaderName = "x-ms-date";
        DateTimeFormatter headerDateFormat = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH).withZone(ZoneId.of("GMT"));
        String dateHeader = headerDateFormat.format(Instant.now());
        String verb = "POST";
        URI uri = URI.create(endpoint + "sms/optouts:add?api-version==" + apiVersion);
        String hostName = uri.getHost();
        String pathAndQuery = uri.getPath() + "?" + uri.getQuery();
        String encodedHash = Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-256").digest(body.getBytes(StandardCharsets.UTF_8)));
        String stringToSign = verb + '\n' + pathAndQuery + '\n' + dateHeader + ';' + hostName + ';' + encodedHash;
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(accessKey.getBytes()), "HmacSHA256"); 
        mac.init(secretKeySpec);
        String signature = Base64.getEncoder().encodeToString(mac.doFinal(stringToSign.getBytes()));
        String authHeader = "HMAC-SHA256 SignedHeaders=" + dateHeaderName + ";host;x-ms-content-sha256&Signature=" + signature;

        HttpClient client = HttpClients.custom().build();
        HttpUriRequest request = RequestBuilder
            .post(uri)
            .setHeader(HttpHeaders.CONTENT_TYPE, "application/json")
            .setHeader(dateHeaderName, dateHeader)
            .setHeader("x-ms-content-sha256", encodedHash)
            .setHeader("Authorization", authHeader)
            .setEntity(new StringEntity(body, "UTF-8"))
            .build();
        HttpResponse r = client.execute(request);
        HttpEntity entity = r.getEntity();
    }
}

public class OptOutRequest
{
    public String from;
    public ArrayList<Recipient> recipients;
}

public class Recipient
{
    public String to;
}

次のステップ

このクイックスタートでは、オプトアウト要求の送信方法について説明しました。