Manifest v2とv3ではだいぶ実装方法が異なるようで、Web上にはv3の情報が少なかったため、最小実装の方法を調べて実装してみました。
(結局、Query Stringをどう書くのかを調べるのが一番大変だった、、というAPIあるある、、でしたがw)
AuthTokenをゲットする方法は前回のpostを参照ください。
fileをGoogle Drive内の特定のParentフォルダ内に作成するには以下のコードを使います。変数parentはファイルidです。
ちなみにGoogle Driveではfolderとfile、どちらもfileとして扱い、mimeTypeによって区別されます。
公式DocumentによるとSheets APIは現時点では特定のフォルダにspreadsheetを作成することができないため、作成後にファイルを移動するか、Drive APIを使用します。
また、このようなネットワーク通信などのAsynchronous(非同期)な処理はPromiseを使って、コールする時にasync/awaitできるようにしておくと勝手が良いです。
// using Drive API
function createSpreadsheet(token, parent, fileName) {
return new Promise((resolve, reject)=>{
const fileMetadata = {
"name" : fileName,
"mimeType" : "application/vnd.google-apps.spreadsheet",
// by specifying the parents, the API will create the file in that folder
"parents" : [parent]
}
fetch("https://www.googleapis.com/drive/v3/files", {
method: "POST",
headers: {
"Content-Type" : "application/json",
"Authorization" : `Bearer ${token}`
},
body: JSON.stringify(fileMetadata)
}).then((document)=>{
return document.json();
}).then(async (result)=>{
menus[result.name] = result.id;
await initialSetupOfSheet(token, result.id);
resolve();
}).catch((error)=>{
console.log("in createSpreadsheet: ", error);
reject(error);
});
});
}
以下は、ファイル名でサーチするコード。
ちなみに、Google Drive APIではsearch query部分を以下のようにq=mimeType=とし、また、’application/vnd.google-apps.spreadsheet’とクォートで囲まなければ認識しないようで、URLSearchParamsをすんなりと使わせてくれなかったためこのようにしています。
function getFileByName(token, fileType, fileName) {
fetch(`https://www.googleapis.com/drive/v3/files?fields=files(name,id,kind,mimeType,trashed)&q=mimeType='application/vnd.google-apps.${fileType}'+and+name+contains+'${fileName}'`, {
method: "GET",
headers: {
"Authorization" : "Bearer " + token,
},
// can't have body in this method
}).then((response) => {
return response.json();
});
}
Parentフォルダ内のファイルをゲットするコード
function getTheFilesOrCreateIfNone(token, fileId){
return new Promise((resolve, reject)=>{
fetch(`https://www.googleapis.com/drive/v3/files?q="${fileId}"+in+parents&mimeType='application/vnd.google-apps.spreadsheet'&fields=files(name,kind,id,mimeType,trashed)`, {
method: "GET",
headers: {
"Authorization": "Bearer " + token
},
}).then((result)=>{
console.log("checking if working: ", result);
return result.json();
}).then(async (result)=>{
// do what ever...
console.log(result.files);
console.log("files including in trash: ", result.files.length);
let files = result.files.filter((file)=>{
return file.trashed == false;
})
// if there is (are) spreadsheet(s), set the context menu
if (files.length > 0) {
for (const file of files) {
menus[file.name] = file.id;
}
} else {
// create new spreadsheet called "Words" in the app folder
await createSpreadsheet(token, _folderId, "Words");
}
// success
setMenus();
resolve();
}).catch((error)=>{
// fail
reject(error);
});
});
}
Spreadsheetにデータを挿入するためのコード
function writeToSheet(token, fileId, text, context, url) {
console.log("writing data to the sheet");
return new Promise((resolve, reject) => {
const range = "A1:E1";
const date = Date();
const bodyData = {
"range" : range,
"majorDimension" : "ROWS",
"values" : [
[text, context, "", url, date]
]
};
fetch(`https://sheets.googleapis.com/v4/spreadsheets/${fileId}/values/${range}:append?insertDataOption=INSERT_ROWS&valueInputOption=RAW`, {
method: "POST",
headers: {
// Content-Type is needed, otherwise "parse error"
"Content-Type" : "application/json",
"Authorization" : `Bearer ${token}`
},
body: JSON.stringify(bodyData),
}).then((response) => {
return response.json();
}).then((response) => {
console.log(response);
resolve();
}).catch((error) => {
console.log(error);
reject("in writeToSheet", error);
});
});
}