I need help to pull tiktok organic data using tiktok API script as my script is facing errors

418 Views Asked by At
function generateToken() {  // Don't need remove all
    const SPREADSHEET_URL = SpreadsheetApp.getActive().getUrl();
    const ss = SpreadsheetApp.openByUrl(SPREADSHEET_URL);

    var sheet = ss.getSheetByName('(1) Generate Token');
    const SHEET = ss.getSheetByName('(1) Generate Token');

    var APP_ID = '';
    var AUTH_CODE = '';
    var APP_SECRET = '';
    
    console.log("REQUEST START");

    var url = 'https://business-api.tiktok.com/open_api/v1.2/oauth2/access_token/'; 

    Logger.log(url)

    var encodedTiktokUrl = encodeURI(url);
    var options = {
      "method": "post",
      "headers" : {"Content-Type": "application/json",},
      "contentType":"application/json",
      "payload":JSON.stringify({
        "app_id": APP_ID,
        "auth_code": AUTH_CODE,
        "secret": APP_SECRET 
      }) 
    }

    // Fetches & parses the URL //getting the task id
    var fetchRequest = UrlFetchApp.fetch(encodedTiktokUrl, options);
    console.log(fetchRequest);
    var results = JSON.parse(fetchRequest.getContentText());
    
    console.log(results);

    // Caches the report run ID
    var reportId = results.data.access_token;
    var cache = CacheService.getScriptCache();
    var cached = cache.get("Access-Token");
    
    if (cached != null) {
      cache.put("Access-Token", [], 1);
      Utilities.sleep(1001);
      cache.put("Access-Token", reportId, 21600);
      }
    else {
      cache.put("Access-Token" , reportId, 21600); 
      }
    console.log(cache.get("Access-Token"));
    console.log("REQUEST SUCCESS");
    
    SHEET.getRange("B5").setValue(reportId);  
    
    var timeZone = 'GMT+7';
    date = Utilities.formatDate(new Date(), timeZone, "MM-dd-yyyy | HH:mm:ss");
    SHEET.getRange("B6").setValue(date);
}
// Looping through each client to request and get reports.
function pullData() {
    for (id in CLIENTS) {
      requestTiktokReport(CLIENTS[id]); //local function in FUNCTIONS.gs
    }
      
    // Give time to pull all data.
    Utilities.sleep(10 * 1000);

    for (id in CLIENTS) {
      getTaskStatus(CLIENTS[id]);
    }

      // Give time to pull all data.
    Utilities.sleep(100 * 1000);

    for (id in CLIENTS) {
      getTiktokReport(CLIENTS[id]);
    }

}

Object.defineProperty(Array.prototype, 'find', {
    value: function(predicate) {
      // 1. Let O be ? ToObject(this value).
      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }
      
      var o = Object(this);
      
      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;
      
      // 3. If IsCallable(predicate) is false, throw a TypeError exception.
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }
      
      // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
      var thisArg = arguments[1];
      
      // 5. Let k be 0.
      var k = 0;
      
      // 6. Repeat, while k < len
      while (k < len) {
        // a. Let Pk be ! ToString(k).
        // b. Let kValue be ? Get(O, Pk).
        // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
        // d. If testResult is true, return kValue.
        var kValue = o[k];
        if (predicate.call(thisArg, kValue, k, o)) {
          return kValue;
        }
        // e. Increase k by 1.
        k++;
      }
      
      // 7. Return undefined.
      return undefined;
    },
    configurable: true,
    writable: true
  
});

var CLIENTS = [
    {
      CLIENT_NAME: "",
      TCM_ACCOUNT_ID: '',
      METRICS: '["engagement_count","video_views","likes","shares", "comments", "reach", "total_play_time", "average_view_time", "two_seconds_view", "six_seconds_views"]',
  //  FILTERING: "[{field:'campaign.name',operator:'CONTAIN',value:'mktz'}]"
    },
    {
      CLIENT_NAME: "",
      TCM_ACCOUNT_ID: '',
      METRICS: '["engagement_count","video_views","likes","shares", "comments", "reach", "total_play_time", "average_view_time", "two_seconds_view", "six_seconds_views"]',
  //  FILTERING: "[{field:'campaign.name',operator:'CONTAIN',value:'mktz'}]"
    },
];

var ACCESS_TOKEN = "";

for (id in CLIENTS) {
    Logger.log(CLIENTS[id].CLIENT_NAME); //local function in FUNCTIONS.gs
}

function requestTiktokReport(CLIENT) { 

    var CLIENT_NAME = CLIENT.CLIENT_NAME;
    var TCM_ACCOUNT_ID = CLIENT.TCM_ACCOUNT_ID;
    var METRICS = CLIENT.METRICS;

    var DATES = new Date();
    DATES.setDate(DATES.getDate());

    var DATESF = DATES.toISOString().split('T')[0]

    var DATEE = new Date();
    DATEE.setDate(DATEE.getDate()-120);

    var DATEEF = DATEE.toISOString().split('T')[0]


    if (CLIENT.FILTERING != null) {
      var FILTERING = CLIENT.FILTERING;
    } else {
      var FILTERING = '';
    }

  console.log("REQUEST START - " + CLIENT_NAME);

      var tiktokurl = //must check this
      'https://biz-api.tiktok.com/open_api/v1.3/tcm/report/get/v2' + 
      '?creatormktplc_id=' + TCM_ACCOUNT_ID +
      '&metrics='  + METRICS +
      '&start_date=' + DATEEF +
      '&end_date=' + DATESF +
      '&filtering=' + FILTERING;

      Logger.log(tiktokurl)

    var encodedTiktokUrl = encodeURI(tiktokurl);
    var options = {
      "method": "post",
      "headers" : {"Content-Type": "application/json",
                  "Access-Token": ACCESS_TOKEN
                  },  
    }
      console.log(options);

  // Fetches & parses the URL //getting the task id
    var fetchRequest = UrlFetchApp.fetch(encodedTiktokUrl, options);
    var results = JSON.parse(fetchRequest.getContentText());
    console.log(fetchRequest);
    
    // Caches the report run ID
    var reportId = results.data.task_id;
    var requestId = results.request_id;
    var cache = CacheService.getScriptCache();
    var cached = cache.get("campaign-report-id-" + CLIENT_NAME); //what's this campaign_report_id
    
    if (cached != null) {
      cache.put("campaign-report-id-" + CLIENT_NAME, [], 1);
      Utilities.sleep(1001);
      cache.put("campaign-report-id-" + CLIENT_NAME, reportId, 21600);
      }
    else {
      cache.put("campaign-report-id-" + CLIENT_NAME, reportId, 21600); 
      }
    console.log(cache.get("campaign-report-id-" + CLIENT_NAME));
    console.log("REQUEST SUCCESS - " + CLIENT_NAME);
    console.log(requestId);
}
///The End of getting task id


//get task status from task id 
function getTaskStatus(CLIENT){
    var CLIENT_NAME = CLIENT.CLIENT_NAME;
    var TCM_ACCOUNT_ID = CLIENT.TCM_ACCOUNT_ID;

    var cache = CacheService.getScriptCache();
    var reportId = cache.get("campaign-report-id-" + CLIENT_NAME);

    var url =     
        'https://business-api.tiktok.com/open_api/v1.3/tcm/order/create/v2/' + 
        '?creatormktplc_id=' + TCM_ACCOUNT_ID +
        '&task_id=' + reportId;

    var options = {
        "method": "get",
        "headers" : {"Content-Type": "application/json",
                    "Access-Token": ACCESS_TOKEN},  
      }
      Logger.log(url)
      
      var fetchRequest = UrlFetchApp.fetch(url, options);
      
      
      Logger.log(fetchRequest)

      var results = JSON.parse(fetchRequest.getContentText());

      
      var reportStatus = results.data.status;
      var cache = CacheService.getScriptCache();
      var cached = cache.get("report-status-" + CLIENT_NAME);
      
      if (cached != 'SUCCESS') {
        cache.put("report-status-" + CLIENT_NAME, [], 1);
        Utilities.sleep(200000);
        cache.put("report-status-" + CLIENT_NAME, reportStatus, 51600);
        }
      else {
        cache.put("report-status-" + CLIENT_NAME, reportStatus, 51600); 
        }
      console.log(cache.get("report-status-" + CLIENT_NAME));
      console.log("REQUEST SUCCESS - " + CLIENT_NAME);
      console.log(reportStatus);
}


function getTiktokReport(CLIENT) {
    var SPREADSHEET_URL = SpreadsheetApp.getActive().getUrl();
    var ss = SpreadsheetApp.openByUrl(SPREADSHEET_URL);


    // client name just for logging & cache name
    var CLIENT_NAME = CLIENT.CLIENT_NAME;
    var TCM_ACCOUNT_ID = CLIENT.TCM_ACCOUNT_ID;
    
    var TAB_NAME = "Tiktok_" + CLIENT_NAME;
    
    console.log("GETFILE START - " + CLIENT_NAME);

    var sheet = ss.getSheetByName(TAB_NAME);
    // Check if there's a sheet there
    if (sheet == null){
      ss.insertSheet(TAB_NAME);
      sheet = ss.getSheetByName(TAB_NAME);
    }

    // Gets the Tiktok report run ID
    var cache = CacheService.getScriptCache();
    var reportId = cache.get("campaign-report-id-" + CLIENT_NAME);


  var url = 
      'https://business-api.tiktok.com/open_api/v1.3/tcm/order/download/v2/' + 
      '?advertiser_id=' + TCM_ACCOUNT_ID +
      '&task_id=' + reportId;

  var options = {
      "method": "get",
      "headers" : {"Content-Type": "text/csv",
                  "Access-Token": ACCESS_TOKEN
                  },

    }

    console.log(url, options);
    var results = undefined;

    try {
      console.log("GETFILE LOADING - " + CLIENT_NAME);
      var fetchRequest = UrlFetchApp.fetch(url, options);
      results = Utilities.parseCsv(fetchRequest);
    }
    catch (e) {
      console.log("GETFILE LOADING FAILED - " + CLIENT_NAME);
      try {
        Utilities.sleep(60 * 1000);
        console.log("GETFILE LOADING (ATTEMPT 2) - " + CLIENT_NAME);
        var fetchRequest = UrlFetchApp.fetch(url, options);
        results = Utilities.parseCsv(fetchRequest);
      }
      catch (e) {
        console.log("GETFILE LOADING FAILED 2 - " + CLIENT_NAME);
        Utilities.sleep(100 * 1000);
        console.log("GETFILE LOADING (ATTEMPT 3) - " + CLIENT_NAME);
        var fetchRequest = UrlFetchApp.fetch(url, options);
        results = Utilities.parseCsv(fetchRequest);
      }
    }

    if (typeof results !== undefined) {
      console.log("GETFILE CSV DETECTED - " + CLIENT_NAME);
      // Clears the sheet
      sheet.getRange('A:K').clearContent();
      // Pastes the csv file in the sheet
      sheet.getRange(1, 1, results.length, results[0].length).setValues(results);
      console.log("GETFILE CSV PARSE SUCCESSFULLY - " + CLIENT_NAME);
    } else {
      console.log("GETFILE FAILED - " + CLIENT_NAME);
    }
    console.log("GETFILE STOP - " + CLIENT_NAME);
}

The first function generates the token, using some of the parameters required by the API. I'm not sure which parameters and how many of them to use. I also have a CLIENTS variable with a list of tiktok accounts I want to pull from, and a requestTikTokReport function that will be pulling the data. I'm not sure if my tiktokurl is accurate. I also keep getting error for CLIENT.CLIENT_NAME and it says that the variable doesn't exist, but i'm not sure why that is the case.

I also have a getTaskStatus function, and I'm not too sure what eat of the var URL do and how to know what URL to use for each case. There are 3 different URLs but I'm not sure what are their uses.

0

There are 0 best solutions below