Lặp lại thông qua phản hồi API Python

Bài viết này giải thích cách lặp lại hiệu quả các yêu cầu GET API REST trong Salesforce Marketing Cloud

Điều gì xảy ra với tất cả các vòng lặp?

Salesforce Marketing Cloud có API mạnh mẽ cho phép chúng tôi truy xuất nhiều thông tin khác nhau về các phần khác nhau của ứng dụng

Ví dụ: chúng tôi có thể truy xuất tên của tất cả Tiện ích mở rộng dữ liệu, chi tiết của tất cả Hành trình hoặc, tại sao không, tất cả các khối HTML từ Trình tạo nội dung

Điều đó đang được nói, khi nói đến các yêu cầu GET từ API REST, mọi thứ có thể hơi rắc rối, vì số lượng mục có thể được truy xuất trên mỗi yêu cầu được cố định ở mức tối đa

Hãy xem xét trường hợp gây tò mò về Hành trình tiếp thị trên đám mây và cách truy xuất tất cả chúng theo cách hiệu quả nhất có thể bằng cách sử dụng kỹ thuật vòng lặp

Truy xuất tất cả các Hành trình

Để truy xuất tất cả Hành trình từ Đơn vị kinh doanh đám mây tiếp thị, chúng ta chỉ cần gửi yêu cầu NHẬN API REST đến điểm cuối sau. /interaction/v1/interactions

Không hoàn toàn đúng

Như đã nêu trong tài liệu chính thức, kết quả của yêu cầu GET này được phân trang và trả về số lượng tối đa 50 mục trên mỗi trang

Điều này có nghĩa là nếu có 75 Hành trình trong Đơn vị Kinh doanh của chúng tôi, yêu cầu sẽ chỉ truy xuất 50

{
  "count": 75,
  "page": 1,
  "pageSize": 50,
  "links": {},
  "items": [...]
}

Làm thế nào để chúng tôi khắc phục điều đó?

Câu chuyện về vòng lặp

Việc lặp qua các yêu cầu GET yêu cầu một số tối ưu hóa, vì chúng tôi không muốn thực hiện nhiều yêu cầu hơn mức cần thiết

Để đạt được điều đó, trước tiên chúng ta cần tạo một chức năng chuyên dụng để thực hiện các yêu cầu GET

function performGetRequest[url, token] {

    var req = new Script.Util.HttpRequest[url];
        req.emptyContentHandling = 0;
        req.retries = 2;
        req.continueOnError = true;
        req.setHeader["Authorization", "Bearer " + token];
        req.method = "GET";
        req.contentType = "application/json";
        req.encoding = "UTF-8";

    var res = req.send[];

    return Platform.Function.ParseJSON[String[res.content]];
}
Note: this function requires an endpoint URL and a REST API token. Learn how to retrieve them thanks to my previous article about How to create, store and use REST API tokens in Salesforce Marketing Cloud.

Bây giờ, hãy tạo một hàm để lặp qua các yêu cầu GET và truy xuất tất cả các Hành trình có sẵn

Làm thế nào nó hoạt động

  1. Chúng tôi thực hiện một yêu cầu ban đầu để truy xuất 50 mặt hàng đầu tiên và tổng số mặt hàng có sẵn
  2. Nếu tổng số lượng lớn hơn 50, điều đó có nghĩa là chúng tôi cần nhiều yêu cầu hơn để truy xuất các mục còn lại
  3. Chúng tôi xác định số vòng lặp cần thực hiện bằng cách chia tổng số vòng lặp cho số mục được trả về trên mỗi trang
  4. Xem xét chúng tôi đã có các mục từ trang đầu tiên, chúng tôi cần bắt đầu vòng lặp ở trang #2
  5. Lặp qua các trang trong yêu cầu GET là vấn đề cung cấp tham số $page ở cuối URL
  6. Chúng tôi cần chức năng này để trả về một mảng các đối tượng và do đó, một for loop đơn giản là cần thiết để tập hợp tất cả các mục từ tất cả các trang
function retrieveAllJourneys[] {

    var output = [];

    var page = 1;
    var pageSize = 50;

    var requestURL = BASE_URL + "interaction/v1/interactions?$page=" + page + "&$pageSize=" + pageSize;  

	// #1
    var result = performGetRequest[requestURL, TOKEN];

    if[result.count == 0] return [];

    output = result.items;
	
	// #2
    if[result.count > pageSize] {

		// #3
        var loops = result.count / pageSize;

		// #4
        for[var i = 1; i < loops; i++] {

            var nextPage = i + 1;

			// #5
            var requestURL = BASE_URL + "interaction/v1/interactions?$page=" + nextPage + "&$pageSize=" + pageSize; 

            var result = performGetRequest[requestURL, TOKEN]

            var items = result.items;

			// #6
            for[var k in items] {

                var item = items[k];

                output.push[item];

            }

        }

    } 

    return output;
}

Mã đầy đủ

Tất cả những gì còn lại là tích hợp 2 chức năng này trong một SSJS để truy xuất mã thông báo API REST và xuất bản nó trên trang Đám mây hoặc thực thi nó từ Hoạt động tập lệnh trong Tự động hóa

Note: please replace everything between {{ .. }} with the data from your account.

    Platform.Load['core', '1'];

    var api = new Script.Util.WSProxy[];

    var config = {
        endpoint: "//{{ DOMAIN }}.auth.marketingcloudapis.com/",
        bu: Platform.Function.AuthenticatedMemberID[],
        credentials: {
            "{{ BU ID }}": {
                "client_id": "{{ CLIENT ID }}",
                "client_secret": "{{ CLIENT SECRET }}",
                "grant_type": "client_credentials"
            }
        },
        storage: {
            de: "REST_Tokens",
            name: "JB_ALL"
        },
        localDate: DateTime.SystemDateToLocalDate[Now[]]
    }

    try { 

        var auth = retrieveToken[];

        var journeys = retrieveAllJourneys[auth]; 

        Write[Stringify[journeys]];

    } catch[error] {

        delete error.jintException;
        error.status = "Error";
        Write[Stringify[error]];
    }

    function performGetRequest[url, token] {

        var req = new Script.Util.HttpRequest[url];
            req.emptyContentHandling = 0;
            req.retries = 2;
            req.continueOnError = true;
            req.setHeader["Authorization", "Bearer " + token];
            req.method = "GET";
            req.contentType = "application/json";
            req.encoding = "UTF-8";

        var res = req.send[];

        return Platform.Function.ParseJSON[String[res.content]];
    }

    function retrieveAllJourneys[] {

        var output = [];

        var page = 1;
        var pageSize = 50;

        var requestURL = auth.url + "interaction/v1/interactions?$page=" + page + "&$pageSize=" + pageSize;  

        var result = performGetRequest[requestURL, auth.token]

        if[result.count == 0] return [];

        output = result.items;

        if[result.count > pageSize] {

            var loops = result.count / pageSize;

            for[var i = 1; i < loops; i++] {

                var nextPage = i + 1;

                var requestURL = auth.url + "interaction/v1/interactions?$page=" + nextPage + "&$pageSize=" + pageSize; 

                var result = performGetRequest[requestURL, auth.token]

                var items = result.items;

                for[var k in items] {

                    var item = items[k];

                    output.push[item];

                }

            }

        } 
        return output;
    }

    /* AUTH */

    function retrieveToken[] {

        var request = Platform.Function.LookupRows[config.storage.de, "Name", config.storage.name];

        var result = request[0];

        if[result != null && [new Date[config.localDate] < new Date[result.ExpirationDate]]] {

            return {
                "token": decryptSymmetric[result.access_token],
                "url": decryptSymmetric[result.rest_instance_url],
                "expires": result.ExpirationDate
            }

        } else {

            var result = requestToken[];

            var upsert = storeToken[result];

            if[upsert > 0] {
                return result;
            } else {
                throw "Token not saved"
            }
        }
    }

    function requestToken[] {

        var request = HTTP.Post[config.endpoint + "/v2/token", "application/json", Stringify[config.credentials[config.bu]]];

        if [request.StatusCode == 200] {

            var result = Platform.Function.ParseJSON[request.Response[0]];

            var parsedDate = new Date[config.localDate];

            var expirationDate = new Date[parsedDate.getTime[] + [result.expires_in * 1000]];

            return {
                "token": result.access_token,
                "url": result.rest_instance_url,
                "expires": expirationDate
            }

        } else {
            throw "Couldn't request the token. Status: " + request.StatusCode;
        }
    }

    function storeToken[result] {

        var rows = Platform.Function.UpsertData[
            config.storage.de,
            ["Name"], [config.storage.name],
            ["access_token", "rest_instance_url", "ExpirationDate"],
            [encryptSymmetric[result.token], encryptSymmetric[result.url], result.expires]
        ];

        if[rows > 0] {
            return rows; 
        } else {
            throw "Token storage failed"
        }

    }

    /* HELPERS */

    function encryptSymmetric[str] {

        Variable.SetValue["@ToEncrypt", str]

        var scr = "";
            scr += "\%\%[";
            scr += "SET @Encrypted = EncryptSymmetric[@ToEncrypt, 'AES', '{{ PASSWORD LABEL }}', @null, '{{ SALT LABEL }}', @null, '{{ VECTOR LABEL }}', @null]";
            scr += "Output[Concat[@Encrypted]]";
            scr += "]\%\%";

        return Platform.Function.TreatAsContent[scr];
    }

    function decryptSymmetric[str] {

        Variable.SetValue["@ToDecrypt", str]

        var scr = "";
            scr += "\%\%[";
            scr += "SET @Decrypted = DecryptSymmetric[@ToDecrypt, 'AES', '{{ PASSWORD LABEL }}', @null, '{{ SALT LABEL }}', @null, '{{ VECTOR LABEL }}', @null]";
            scr += "Output[Concat[@Decrypted]]";
            scr += "]\%\%";

        return Platform.Function.TreatAsContent[scr];
    }

Phần kết luận

Đây là một cách phổ biến để lặp qua các yêu cầu GET của API REST của đám mây tiếp thị, nhưng đừng quên rằng nó chỉ áp dụng cho các yêu cầu trả về kết quả được phân trang

Chủ Đề