2

I am aware of q&a on how to check if file exists by name (using hasnext()). I need to check however by file ID, preferably without the advanced Drive API.

Disclosure: I wrote a solution based on error handling:

function ifFileExists(id){
  try {DriveApp.getFileById(id);return true;}
  catch(e) {return false}
}

But this feels like clumsy. Anyone knows a better solution?

Rubén
  • 34,714
  • 9
  • 70
  • 166
WillemS
  • 121
  • 1
  • 1
  • 9
  • I don't think there is but you can always check the DriveApp reference documentation. Maybe there is a function in there that's cleaner than what you have here. – TheAddonDepot Oct 29 '22 at 18:44
  • Although I'm not sure whether I could correctly understand your expected situation, I proposed an answer. Could you please confirm it? If that was not useful, I apologize. – Tanaike Oct 29 '22 at 23:35
  • Please define what are you looking as a *better solution* – Rubén Oct 30 '22 at 04:04

2 Answers2

5

I believe your goal is as follows.

  • You want to check whether the file ID is existing using Google Apps Script.
  • You don't want to use DriveApp.getFileById(id) and Drive API.

In this case, as a workaround, how about checking it using the thumbnail link? Ref In this case, when the file ID is existing, the sign-in HTML with the status code of 200 is returned. On the other hand, when the file ID is not existing, an error like Error 404 (Not Found) occurs. I thought that this situation might be able to be used for your situation. When this is reflected in a sample script, how about the following sample script? In this sample script, UrlFetchApp is used.

Sample script:

function myFunction() {
  const fileId = "###"; // Please set the file ID.

  const res = UrlFetchApp.fetch(`https://drive.google.com/thumbnail?id=${fileId}`, { muteHttpExceptions: true }).getResponseCode() == 200 ? true : false;

  console.log(res);
}
  • In this case, when res is true and false, it indicates that the file ID is existing and not existing, respectively.

  • In this case, Drive API is not required to be enabled and only the scope of https://www.googleapis.com/auth/script.external_request is used.

  • When your script is modified, how about the following modified script?

      function ifFileExists(id){
        return UrlFetchApp.fetch(`https://drive.google.com/thumbnail?id=${id}`, { muteHttpExceptions: true }).getResponseCode() == 200 ? true : false;
      }
    

Reference:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Hi Tanaike. I just posted an answer that I think complements yours and makes reference to it --> https://stackoverflow.com/a/74250399/1595451. What do you think? – Rubén Oct 30 '22 at 04:20
  • 1
    @Rubén Thank you for your comment. I think that the combination of try-catch and `DriveApp.getFileById(id)` and Drive API can be used for achieving OP's goal. But, from OP's question, I'm worried that the scope might be limited in OP's situation. (I'm not sure about OP's detailed situation.) So, as another method except for them, I proposed a method for achieving the goal using UrlFetchApp and the common endpoint. But, this is just my guess. I'm not sure whether my understanding is correct. I apologize for this. – Tanaike Oct 30 '22 at 07:34
  • 1
    Thanks Tanaike for your reply. I think that your answer is helpful to learn about an alternative to `DriveApp.getFileById`. Regarding the question it's not clear to me why the OP thinks that using DriveApp.getFileById and try..catch is "clumpsy" and what it means "better solution" for them. – Rubén Oct 30 '22 at 07:45
  • 1
    @Rubén Thank you for replying. I agree with your reply. From this situation, I guessed about the limitation of scopes. But, even if this workaround was not useful for OP's situation, I think that this method might be useful for other users. For example, in this method, they can confirm whether the file of the file ID is existing from outside of Google without using the access token and the API key. I think that this might be useful. – Tanaike Oct 30 '22 at 07:53
1

There is nothing wrong on using DriveApp.getFileById(id) to check if a file "exists" based on it's id, other than the file might actually exists but the Google Apps Script effective user hasn't access to that file.

The above because the reference documentation specify that this method will throw an exception, so it's perfectly fine to use try...catch to catch that exception.

If you might want to do something more sofisthicated like having a default handler for the expected exception and another for unexpected exceptions. If your scripts users is a small group that all have set their Google account language to English it is something easy, but if you are planning to write and addon, this could be hard as Google Apps Script exceptions only return a string message and it depends on the effective account language. Fortunately someone already did a lot of work to handel this, created a library and shared in GitHub --> https://github.com/RomainVialard/ErrorHandler

From https://github.com/RomainVialard/ErrorHandler/blob/master/src/ErrorHandler.gs.js

// "No item with the given ID could be found, or you do not have permission to access it." - eg:Drive App.getFileById
  "No item with the given ID could be found, or you do not have permission to access it.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'en' },
  "Không tìm thấy mục nào có ID đã cung cấp hoặc bạn không có quyền truy cập vào mục đó.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'vi' },
  "No se ha encontrado ningún elemento con el ID proporcionado o no tienes permiso para acceder a él.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'es' },
  "No se ha encontrado ningún elemento con la ID proporcionada o no tienes permiso para acceder a él.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'es_419' },
  "Nessun elemento trovato con l'ID specificato o non disponi di autorizzazioni per accedervi.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'it' },
  "Det gick inte att hitta någon post med angivet ID eller så saknar du behörighet för att få åtkomst till den.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'sv' },
  "Er is geen item met de opgegeven id gevonden of je hebt geen toestemming om het item te openen.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'nl' },
  "Nenhum item com o ID fornecido foi encontrado ou você não tem permissão para acessá-lo.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'pt' },
  "Impossible de trouver l'élément correspondant à cet identifiant. Vous n'êtes peut-être pas autorisé à y accéder.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'fr' },
  "No s'ha trobat cap element amb aquest identificador o no teniu permís per accedir-hi.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'ca' },
  "Элемент с заданным кодом не найден или у вас нет прав доступа к нему.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'ru' },
  "Nebyly nalezeny žádné položky se zadaným ID nebo nemáte oprávnění k nim přistupovat.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'cs' },
  "Item dengan ID yang diberikan tidak dapat ditemukan atau Anda tidak memiliki izin untuk mengaksesnya.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'in' },
  "指定された ID のアイテムは見つからなかったか、アクセスする権限がありません。": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'ja' },
  "Не вдалося знайти елемент із зазначеним ідентифікатором. Або у вас немає дозволу на доступ до нього.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'uk' },
  "Verilen kimliğe sahip öğe bulunamadı veya bu öğeye erişme iznine sahip değilsiniz.": { ref: NORMALIZED_ERRORS.NO_ITEM_WITH_GIVEN_ID_COULD_BE_FOUND, locale: 'tr' },

Another option might be use other Google Apps Script services instead on DriveApp like the Advanced Drive Service or calling the Google Drive API by using Url Fetch Service (for details on this option see Tanaike's answer but this will not make your code smaller or easier to read.

Rubén
  • 34,714
  • 9
  • 70
  • 166