You are currently viewing Refresh một lúc hàng loạt triggered send trong MC

Refresh một lúc hàng loạt triggered send trong MC

Như ta đã biết một khi Journey hoạt động thì dữ liệu, các trigger trong nó hoạt động khép kín hầu như không tương tác với thay đổi bên ngoài nữa. Thật may vì ta đã biết cách refresh email trong một journey.
Vậy trường hợp nếu có thay đổi ở nhiều email content liên quan đến nhiều journey khác nhau, mà các content block này không phải reference content block (không có khả năng reflect những thay đổi đến journey) thì ta phải làm sao?

Ừ thì ta đã biết cách refresh content để cập nhật những thay đổi vào journey rồi đấy nhưng ở trường hợp trên mà làm hết tất cả các journey/triggered send chắc gãy cả tay. Hôm nay Gâu Đần sẽ chỉ các bạn cách để giải quyết vấn đề hóc búa đó nhé.

Nguyên lý hoạt động

Việc refresh email content trong journey thực tế chính là ta đang refresh các triggered send definition trong Journey này. Các bước để refresh một triggered send definition đó là Pause – Publish – Start như ở solution 03 trong bài refresh email trong jouney.

Update 17/7/2023: cách 1 không sử dụng được, hãy sử dụng cách thứ 2

Cách 1: Sử dụng tính năng đi kèm trong Auto Suppression List

Tạo một auto-suppression list trong MC

Email Studio/Admin/Send Management/Auto-Suppression Configuration

Sao khi tạo một list rỗng ta sẽ thấy một pop-up cho phép ta restart các triggered send.

Result

Kết quả khi nhận thông báo về từ email

All triggered sends that empty list auto-suppression is assigned to have been updated successfully.
Any other unpublished changes to triggered sends (including changes to emails, sender profiles, delivery profiles, or send classifications) were not published as part of this update.

How to check if it works?

Cách để kiểm tra liệu triggered send đã được refresh chưa thì bạn vào

Email studio/ Interactions/ Triggered Emails

Thử click vào phần Triggered Send hoặc Journey

Nếu thấy tất cả các triggered send đã được publish với ngày hiện tại và status của chúng không đổi – cái nào đang chạy hoặc dừng vẫn y vậy thì… xin chúc mừng. Các triggered send của bạn đã được refresh!

Cách 2: retrieve và thực hiện các action đối với các object liên quan

Cách này nặng hơn nhiều về kĩ thuật, đòi hỏi kiến thức về hệ thống.

Bản chất

Về bản chất thì không thay đổi, ta vẫn cần phải Stop Publish Start triggered send như solution 3 trong bài trước.

Vậy bạn cần phải:

  • Làm sao để gọi ra các triggered send này
  • Làm sao để mimic các hành động trên → refresh được các triggered send

Note: Đây là một cách phức tạp, đòi hỏi kiến thức rộng nên để tránh đưa quá nhiều thông tin, Gâu Đần sẽ lược bỏ đi bớt/không nhắc đến những chi tiết có thể khiến gây nhiễu.

Retrieve tất cả triggered send definition

Việc đầu tiên của ta cần phải làm là làm sao có dữ liệu các triggered send đúng chưa? Và dữ liệu này thì cần những gì?

Ok vậy Gâu Đần vào ĐÂY đọc để xem cấu trúc của Triggered Send Definition object trông như thế nào.

Ta có thể thấy object này có một attribute tên là CustomerKey để phân biệt các Triggered send khác nhau và cũng chính là giá trị ở cột External Key ở mục How to check if it works? ở Cách 1 bên trên. Đây cũng chính là thứ ta cần biết để xác định ra các triggered send cần refresh.

Ta có thể dùng WSProxy để retrieve object này và pull hết giá trị lấy ta lấy được vào một array sau đó có thể dùng dữ liệu trong array này để xử lý.

<script runat="server">
Platform.Load("core", "1.1");
var prox = new Script.Util.WSProxy();
var updateObject = [];
var cols = ["Name", "CustomerKey", "TriggeredSendStatus", "TriggeredSendType", "EmailSubject"];
var filter = {Property: "TriggeredSendStatus", SimpleOperator: "IN", Value: ["Active", "Active"]};
var data = prox.retrieve("TriggeredSendDefinition", cols, filter);
// Check the total number of triggered send definitions
Write("There are " + data.Results.length + " active triggered send definitions")
for (var i=0; i< data.Results.length; i ++) {
    updateObject.push({CustomerKey: data.Results[i].CustomerKey, TriggeredSendStatus: data.Results[i].TriggeredSendStatus})
}
//Write(Stringify(updateObject));
</script>

Chú ý: Hãy filter các triggered send này với TriggeredSendStatus =“Active”, vì nếu không ở những bước tiếp theo ta có thể vô tình activate những triggered send mà lẽ ra nó phải inactive khiến các triggered automation bị hỏng và rất mất nhiều thời gian để sửa. Đó là kinh nghiệm đau thương của mình crying face 

Dòng thứ 6 trông hơi kì kì tại sao không viết filter như thế này?

var filter = {Property: "TriggeredSendStatus", SimpleOperator: "equals", Value: "Active"};

Đây là bug của MC từ rất lâu và vẫn còn tồn tại, Operator để so sánh ở đây phải dùng “IN” mới retrieve được, còn như filter mình vừa viết ở câu hỏi ở trên thì nó không retrieve không ra kết quả nào hết grinning face with sweat 

Note: Official document của Salesforce không phải lúc nào cũng đúng. Bạn vào ĐÂY đọc sẽ thấy, TriggeredSendDefinition object không cho phép retrieve

Nhưng… mình vừa retrieve cho bạn thấy đó thôi grinning squinting face 

Truy vấn tất cả các triggered send trong Journey?

Như ở trên ta đã có thể retrieve tất cả các active triggered send cần để refresh. Vậy trong trường hợp ta chỉ muốn refresh các triggered send có trong running journey thì sao?

Vậy ta sẽ cần truy vấn vào data views để lấy được các CustomerKey/External Key của các triggered send này.

Đầu tiên xem lại sơ đồ data views map với nhau thế nào ở ĐÂY (thanks Zuzanna)

TriggeredSendCustomerKey là thứ ta sẽ cần.
Giờ ta sẽ truy vấn vào các data views này

SELECT DISTINCT
a.JourneyName,
a.VersionNumber,
a.JourneyStatus,
b.ActivityName,
b.ActivityType,
c.TriggeredSendCustomerKey,
'Reset tsd' as remark
FROM
_Journey as a
INNER JOIN
_JourneyActivity as b
ON
a.VersionID = b.VersionID
INNER JOIN
_Job as c
ON
b.JourneyActivityObjectID = c.TriggererSendDefinitionObjectID
WHERE
a.JourneyStatus = 'Running'
AND
a.JourneyName = 'Plan Package Email'

Chúng ta chỉ cần triggered send CustomerKey thôi nhưng Gâu Đần recommend các bạn nên lấy thêm một số field khác nữa để có thể double check ta đang lấy đúng dữ liệu mình cần!

Ở truy vấn trên, Gâu Đần làm cho nhanh nên chỉ giới hạn trong một journey tên là ‘Plan Package Email’. Và ta có kết quả bên dưới:

  • Ta có thể map với các data view khác chẳng hạn như: Sent, Open, Bounce,… để lấy trigger send customer key tuy nhiên những data view này dữ liệu chỉ tồn tại trong 6 tháng. Nên hãy dùng _Job data view.
  • Thứ hai, bạn để ý Gâu Đần có dùng statement DISTINCT, là bởi mỗi lần republish thì một job mới (Id khác) cùng với dữ liệu các triggered send cũ được tạo ra cùng job này, vì thế để deduplicate ta phải dùng thêm statement này.

Kết quả trên được trữ trong một DE có tên là Reset TSD journey

Reset triggered send trong journey

Phần này dữ liệu được refresh là từ triggered send của journey bên trên

Nếu các bạn muốn refresh tất cả triggered send hoặc tất cả các triggered send nằm trong journey thì phải biến đổi một xíu nhé.

<script runat="server">
Platform.Load("core", "1.1");
var data,
    deName = 'Reset TSD journey',
    updateObject = [],
    debugging = true;
try {
    // Only for data with fewer than 2000 rows
    data = Platform.Function.LookupRows(deName, 'remark', 'Reset tsd');
}
catch (ex) {
    Write(Stringify(ex.message));
}
if (data.length > 0) {
    if(debugging) {Write('There are ' + data.length + ' records in the DE<br>')};
    for (var i =0; i < data.length; i++) {
        updateObject.push({"CustomerKey": data[i].TriggeredSendCustomerKey,"TriggeredSendStatus": "Inactive","RefreshContent": true});
    }
    //Write(Stringify(updateObject));
    var prox = new Script.Util.WSProxy();
    var options = {SaveOptions: [{'PropertyName': '*', SaveAction: 'UpdateOnly'}]};
    // Stop and publish
    var req = prox.updateBatch('TriggeredSendDefinition', updateObject, options);
    // Start
        updateObject = [];
    for (var i =0; i < data.length; i++) {
        updateObject.push({"CustomerKey": data[i].TriggeredSendCustomerKey,"TriggeredSendStatus": "Active "});
    }
        req = prox.updateBatch('TriggeredSendDefinition', updateObject, options);
    if(debugging) {Write('Process status: ' + req.Status)};
}
</script>

Lưu ý: chỉ cần một chút thay đổi về mặt dữ liệu, thì cách gọi dữ liệu sẽ khác nhau. 

Chẳng hạn nếu dữ liệu nằm ở Data Extension thì phải gọi từ DE đó còn không thì phải retrieve từ object về, dữ liệu dưới 2000 thì gọi cách này tiện hơn, từ 2000 đến 2500 thì gọi kiểu khác mà trên 2500 thì lại một kiểu khác nữa.

Để ở một bài khác mình sẽ giải thích về vấn đề này kissing face with smiling eyes 

Giờ thì enjoy thành quả nào!

This Post Has One Comment

  1. Tùng

    Cảm ơn Gâu Đần vì bài viết cực kỳ hữu ích ^^

Leave a Reply