Search code examples
google-apps-scripthttp-status-code-404

Error : Invalid ID while creating projects in map using library ProjectApp2 by tanaike


My script worked flawlessly until recently, but it's been throwing an error for about a week now. Updating projects with the help of this library, as well as obtaining information about projects are flawless, but it is with the creation of projects inside the map gives me an error

Here's my current code:

/**
 * Создает проекты Google Apps Script из исходного кода, представленного в виде блобов (бинарных объектов).
 * Проекты создаются на основе данных, взятых из определенного листа.
 */
function создать_проекты_из_блоб_файлов__createProjectByBlob() {
  // Получение строк с названиями файлов и исходным кодом из листа SheetProject.
  // Исключение заголовков и пустых строк.
  const rows = Utils.values(SheetProject).filter(row => row[0] && row[0] != 'fileName');

  // Формирование массива объектов с информацией о файлах скрипта.
  const scriptFilesInfo = rows.map(row => ({ name: row[0].toString(), code: row[1].toString() }));

  // Перевод информации о файлах скрипта в объекты Blob. 
  const blobs = scriptFilesInfo.map(({ name, code }) =>
    Utilities.newBlob(code, 'text/plain', name));

  try {
    // Получение имен проектов для создания из листа, исключение заголовков и пустых строк.
    const data = Utils.values(SheetProject).filter(row => row[2] && row[2] !== 'projectName').map(row => row[2]);

    // Создание проектов с использованием функции ProjectApp2.createProjectByBlob
    // и данных о файлах скрипта.
    const creations = data.map((projectName) => {

      const projectCreationResult = ProjectApp2.createProjectByBlob(projectName, blobs);
      console.log(projectCreationResult);
      // Возвращаем объект с информацией о созданном проекте.
      return {
        url: `https://script.google.com/u/0/home/projects/${projectCreationResult.scriptId}/edit`,
        name: projectCreationResult.name,
        result: projectCreationResult
      };
    });

    // Логирование результатов создания проектов.
    console.log('Created projects:', JSON.stringify(creations, null, 2));

    // Отображение результатов создания проектов пользователя.
    show(creations.map(({ url, name }) => [url, name]));
  } catch (error) {
    // Логирование ошибок в случае их возникновения.
    console.error('Error in createProjectByBlob function:', JSON.stringify({ error: error.toString() }, null, 2));
  }
};

Now I'm getting this error:

Error: {"error":{"code":404,"message":"Invalid ID","status":"NOT_FOUND","details":[{"@type":"type.googleapis.com/google.rpc.LocalizedMessage","locale":"en-US","message":"Invalid ID"}]}}
updateProject   @ Code.gs:218
createProject   @ Code.gs:192
ProjectApp2.createProjectByBlob @ Code.gs:106
createProjectByBlob @ Code.gs:30
(функция без названия)  @ testing.gs:24

I tried using forEach instead of map, but I still get the current error the same way However, when I try to run the test script, it works:

function myFunction() {
  var json = {
    timeZone: "Asia/Tokyo",
    dependencies: {
      enabledAdvancedServices: [
        {
          userSymbol: "Drive",
          serviceId: "drive",
          version: "v2",
        },
      ],
    },
    exceptionLogging: "STACKDRIVER",
    oauthScopes: ["https://www.googleapis.com/auth/drive"],
  };

  const names = ['ghbdtn', 'gjrf', 'ljcdblfybz'];
  var blob = Utilities.newBlob(Utils.stringify(json), 'text/plain', "appsscript.json");
  var blobs = [blob, Utilities.newBlob('// тесты', 'text/plain', 'ntcn')];
  var res = names.map(name => ProjectApp2.createProjectByBlob(name, blobs))
  // var res = ProjectApp2.updateProjectByBlob(projectId, blob); // If this is used, the Manifests in the existing project is updated.
  Logger.log(res);

}

sample of scriptFilesInfo:

[ { name: 'appsscript.json',
    code: '{\n  "timeZone": "Asia/Yekaterinburg",\n  "dependencies": {\n    "libraries": [\n      {\n        "userSymbol": "Trigger_lib",\n        "libraryId": "1JqffuBy8rTgiUSudJYAbR8qokG-3MUSRClmyWRrY5S8",\n        "version": 0,\n        "developmentMode": true\n      },\n      {\n        "userSymbol": "Tg_lib",\n        "libraryId": "1UbzKANMiHPB7PImDQDEXmJygTlvlDVSRe-kUV68JgTE",\n        "version": 0,\n        "developmentMode": true\n      }\n    ]\n  },\n  "oauthScopes": [\n    "https://www.googleapis.com/auth/script.external_request",\n    "https://www.googleapis.com/auth/script.scriptapp",\n    "https://www.googleapis.com/auth/drive",\n    "https://www.googleapis.com/auth/drive.file",\n    "https://www.googleapis.com/auth/drive.readonly",\n    "https://www.googleapis.com/auth/spreadsheets",\n    "https://www.googleapis.com/auth/spreadsheets.readonly",\n    "https://mail.google.com/",\n    "https://www.google.com/calendar/feeds",\n    "https://www.google.com/m8/feeds",\n    "https://www.googleapis.com/auth/admin.directory.group",\n    "https://www.googleapis.com/auth/admin.directory.user",\n    "https://www.googleapis.com/auth/documents",\n    "https://www.googleapis.com/auth/drive",\n    "https://www.googleapis.com/auth/forms.currentonly",\n    "https://www.googleapis.com/auth/groups",\n    "https://www.googleapis.com/auth/script.deployments",\n    "https://www.googleapis.com/auth/script.deployments.readonly",\n    "https://www.googleapis.com/auth/script.metrics",\n    "https://www.googleapis.com/auth/script.processes",\n    "https://www.googleapis.com/auth/script.projects",\n    "https://www.googleapis.com/auth/script.projects.readonly",\n    "https://www.googleapis.com/auth/spreadsheets",\n    "https://www.googleapis.com/auth/userinfo.email"\n  ],\n  "exceptionLogging": "STACKDRIVER",\n  "runtimeVersion": "V8"\n}' },
  { name: 'settings',
    code: '/** \n* постоянные перменные\n*/\n\nconst ss = SpreadsheetApp.openbyUrl();\nconst ssID = ss.getId();\n\n// Получение доступа к свойствам скрипта\nconst properties = PropertiesService.getScriptProperties();\n\n/**\n* вспомогательные функции\n*/\n' } ]

It's not clear to me why the test function works and mine won't. Can you tell me where I'm going wrong?


Solution

  • Modification points:

    When I saw your provided value of scriptFilesInfo, I thought that the value of libraryId was invalid value as follows.

    "libraries": [
      {
        "userSymbol": "Trigger_lib",
        "libraryId": "1JqffuBy8rTgiUSudJYAbR8qokG-3MUSRClmyWRrY5S8", // In the current stage, this is an invalid value.
        "version": 0,
        "developmentMode": true
      },
      {
        "userSymbol": "Tg_lib",
        "libraryId": "1UbzKANMiHPB7PImDQDEXmJygTlvlDVSRe-kUV68JgTE", // In the current stage, this is an invalid value.
        "version": 0,
        "developmentMode": true
      }
    ]
    

    The length of your library ID is 44. I guessed that this library ID might be the old ID.

    In the current stage, the library ID is the same as the file ID of the Google Apps Script project. So, in that case, the length of ID is 57. I guessed that the reason for the current issue of Error: {"error":{"code":404,"message":"Invalid ID","status":"NOT_FOUND","details":[{"@type":"type.googleapis.com/google.rpc.LocalizedMessage","locale":"en-US","message":"Invalid ID"}]}} is due to this.

    Unfortunately, I do not know the valid library ID of the libraries you are using. So, in this answer, I would like to propose a modified script for removing the error "message":"Invalid ID". In order to remove this error, please modify it as follows.

    From:

    const scriptFilesInfo = rows.map(row => ({ name: row[0].toString(), code: row[1].toString() }));
    

    To:

    const orgScriptFilesInfo = rows.map(row => ({ name: row[0].toString(), code: row[1].toString() }));
    const scriptFilesInfo = orgScriptFilesInfo.map(({ name, code }) => {
      if (name == "appsscript.json") {
        const obj = JSON.parse(code);
    
        obj.dependencies.libraries = obj.dependencies.libraries.filter(({ libraryId }) => libraryId.length > 44);
        // or delete obj.dependencies.libraries;
    
        code = JSON.stringify(obj);
      }
      return { name, code };
    });
    
    • I modified the variable name from scriptFilesInfo to orgScriptFilesInfo of const scriptFilesInfo = rows.map(row => ({ name: row[0].toString(), code: row[1].toString() }));.
    • I added a script for creating new scriptFilesInfo by removing the old library IDs.
    • If you want to remove all of them, please use delete obj.dependencies.libraries; instead of obj.dependencies.libraries = obj.dependencies.libraries.filter(({ libraryId }) => libraryId.length > 44);.
    • When I tested your showing script by reflecting my modification using your provided value of scriptFilesInfo, I confirmed that the script worked without errors.

    Note:

    • Of course, if you have already known the valid library IDs of Trigger_lib and Tg_lib, when you use them, I think that your current script works.