{"id":19651685,"url":"https://github.com/tanaikech/fetchapp","last_synced_at":"2025-04-28T16:31:39.293Z","repository":{"id":79705756,"uuid":"182347891","full_name":"tanaikech/FetchApp","owner":"tanaikech","description":"This is a GAS library for creating and requesting the type of multipart/form-data using Google Apps Script. This library enhances Class UelFetchApp of Google Apps Script.","archived":false,"fork":false,"pushed_at":"2021-03-21T12:47:15.000Z","size":18,"stargazers_count":48,"open_issues_count":3,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-05T09:51:08.392Z","etag":null,"topics":["developer-tools","fetch","gas-library","google-apps-script","library","multipart-formdata"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tanaikech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-04-20T02:01:25.000Z","updated_at":"2025-01-04T17:31:04.000Z","dependencies_parsed_at":"2023-06-19T13:10:11.822Z","dependency_job_id":null,"html_url":"https://github.com/tanaikech/FetchApp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanaikech%2FFetchApp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanaikech%2FFetchApp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanaikech%2FFetchApp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanaikech%2FFetchApp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tanaikech","download_url":"https://codeload.github.com/tanaikech/FetchApp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251345968,"owners_count":21574810,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["developer-tools","fetch","gas-library","google-apps-script","library","multipart-formdata"],"created_at":"2024-11-11T15:07:30.043Z","updated_at":"2025-04-28T16:31:37.362Z","avatar_url":"https://github.com/tanaikech.png","language":"JavaScript","readme":"# FetchApp\r\n\r\n\u003ca name=\"top\"\u003e\u003c/a\u003e\r\n\r\n[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENCE)\r\n\r\n\u003ca name=\"overview\"\u003e\u003c/a\u003e\r\n\r\n# Overview\r\n\r\n**This is a Google Apps Script library which enhances Class UrlFetchApp to assist in creating and requesting multipart/form-data.**\r\n\r\n\u003ca name=\"description\"\u003e\u003c/a\u003e\r\n\r\n# Description\r\n\r\nGoogle Apps Script provides [Class UrlFetchApp](https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app) with a fetch method [`fetch(url, params)`](\u003chttps://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)\u003e), however, the request body for [multipart/form-data](https://www.w3.org/TR/html5/sec-forms.html#multipart-form-data), must be created by the user, and it is [a bit difficult to do so](https://gist.github.com/tanaikech/d595d30a592979bbf0c692d1193d260c). I've created this library in the hope that simplification of this process would be useful for others.\r\n\r\n\u003ca name=\"methods\"\u003e\u003c/a\u003e\r\n\r\n# Methods\r\n\r\n| Method                                | Description                                                                                                                                                                                                                                                                                                                                               |\r\n| :------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\r\n| [fetch(url, params)](#fetch)          | This method is used for running a single request. This method uses `UrlFetchApp.fetch()`. The type of \"url\" and \"params\" are string and object, respectively. \"params\" uses the object of `UrlFetchApp.fetch(url, params)`. In this method, a property of `body` is added. This is demonstrated in the sample script below. |\r\n| [fetchAll(requests[])](#fetchall)     | This method is used for running multiple requests. This method uses `UrlFetchApp.fetchAll()`. Each request is processed asynchronously. The type of \"requests\" is an object. \"requests\" uses the object of `UrlFetchApp.fetchAll(requests)`. In this method, a property of `body` is added. This is demonstrated in the sample script below. |\r\n| [createFormData()](#createformdata)   | This method is used for creating an instance of formData.                                                                                                                                                                                                                                                                                                 |\r\n| [append(key, value)](#createformdata) | This method appends a formData using key and value to created formData. The type of \"key\" and \"value\" are string and blob, respectively. This is demonstrated in the sample script below.                                                                                                                                                    |\r\n\r\n\u003e - `params` of `FetchApp.fetch(url, params)` and `requests[]` of `FetchApp.fetchAll(requests[])` are basically the same with `params` of [`UrlFetchApp.fetch(url, params)`](https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetchurl-params) and `requests[]` of [`UrlFetchApp.fetchAll(requests[])`](https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetchallrequests), respectively. At `FetchApp`, the property of `body` is used for giving the form data. Other properties are the same as in `UrlFetchApp`.\r\n\r\n\u003e - If `payload` of property is used in `params` and `requests[]`, `body` is not used; it is completely the same as the default `UrlFetchApp`. Only when `body` is used is multipart/form-data requested.\r\n\r\nI would like to add more methods in the future.\r\n\r\n# Library's project key\r\n\r\n```\r\n1sm9V-w8-0i3U4-10N6XyaRjHk5voiuJ1ArKSLo3htOUasB6GcPcIq8Kb\r\n```\r\n\r\n# How to install\r\n\r\n- Open Script Editor. Click as follows:\r\n- -\u003e Resource\r\n- -\u003e Library\r\n- -\u003e Input the Script ID in the text box. The Script ID is **`1sm9V-w8-0i3U4-10N6XyaRjHk5voiuJ1ArKSLo3htOUasB6GcPcIq8Kb`**.\r\n- -\u003e Add library\r\n- -\u003e Please select the latest version\r\n- -\u003e Developer mode ON (Or select others if you don't want to use the latest version)\r\n- -\u003e The identifier is \"**`FetchApp`**\". This is set under the default.\r\n\r\n[You can read more about libraries in Apps Script here](https://developers.google.com/apps-script/guide_libraries).\r\n\r\n## About scopes\r\n\r\nThis library uses the following scope. This is installed in the library, and nothing further is required from the user.\r\n\r\n- `https://www.googleapis.com/auth/script.external_request`\r\n\r\n# Methods\r\n\r\n\u003ca name=\"fetch\"\u003e\u003c/a\u003e\r\n\r\n## 1. fetch(url, params)\r\n\r\nThis method is used for running a single request. This method uses `UrlFetchApp.fetch()`. The type of \"url\" and \"params\" are string and object, respectively. \"params\" uses the object of `UrlFetchApp.fetch(url, params)`. In this method, a property of `body` is added.\r\n\r\n### Sample script 1\r\n\r\nAs an example, this is how one may convert a PDF file to a new Google Document using the method of [files.create](https://developers.google.com/drive/api/v3/reference/files/create). (Drive API v3)\r\n\r\n```javascript\r\nfunction sample1() {\r\n  var fileId = \"### fileId of PDF ###\";\r\n  var metadata = {\r\n    name: \"sampleDocument\", // Filename of created Google Document\r\n    mimeType: MimeType.GOOGLE_DOCS, // MimeType of Google Document\r\n  };\r\n  var fileBlob = DriveApp.getFileById(fileId).getBlob();\r\n  var form = FetchApp.createFormData(); // Create form data\r\n  form.append(\r\n    \"metadata\",\r\n    Utilities.newBlob(JSON.stringify(metadata), \"application/json\")\r\n  );\r\n  form.append(\"file\", fileBlob);\r\n  var url =\r\n    \"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart\";\r\n  var params = {\r\n    method: \"POST\",\r\n    headers: { Authorization: \"Bearer \" + ScriptApp.getOAuthToken() },\r\n    body: form,\r\n  };\r\n  var res = FetchApp.fetch(url, params);\r\n  Logger.log(res);\r\n  // DriveApp.createFile(blob) // This comment line is used for automatically detecting scope for running this sample script.\r\n}\r\n```\r\n\r\n\u003ca name=\"sample2\"\u003e\u003c/a\u003e\r\n\r\n### Sample script 2\r\n\r\nAt the following sample script, `blob` is sent as `files`.\r\n\r\n```javascript\r\nfunction multipartformdata_files() {\r\n  var url = \"###\";\r\n  var blob = Utilities.newBlob(\"sample value\", MimeType.PLAIN_TEXT, \"sample.txt\");\r\n  var form = FetchApp.createFormData();\r\n  form.append(\"sample\", blob);\r\n  var params = {\r\n    method: \"POST\",\r\n    headers: { Authorization: \"Bearer sampleToken\"},\r\n    body: form,\r\n  };\r\n  var res = FetchApp.fetch(url, params);\r\n  console.log(res.getContentText());\r\n}\r\n```\r\n\r\nAbove script is the same with the following curl command.\r\n\r\n```bash\r\n$ curl -X POST \\\r\n  -F sample='@sample.txt;type=text/plain' \\\r\n  -H 'Content-Type: multipart/form-data' \\\r\n  '### URL ###'\r\n```\r\n\r\n\u003ca name=\"fetchall\"\u003e\u003c/a\u003e\r\n\r\n## 2. fetchAll(requests)\r\n\r\nThis method is used for running multiple requests. This method uses `UrlFetchApp.fetchAll()`. Each request is processed asynchronously. The type of \"requests\" is an object. \"requests\" uses the object of `UrlFetchApp.fetchAll(requests)`. In this method, a property of `body` is added.\r\n\r\n### Sample script\r\n\r\nAs an example, this shows how to overwrite two existing Google Documents using the content of two text files using the method of [files.update](https://developers.google.com/drive/api/v3/reference/files/update). (Drive API v3) Currently, [the Drive API batch request cannot use the file media](https://developers.google.com/drive/api/v3/batch). This sample script might become a workaround for updating files by quasi-batching requests via an asynchronous process.\r\n\r\n```javascript\r\nfunction sample2() {\r\n  var contents = [\r\n    {\r\n      fileName: \"newFilename1\", // new filename\r\n      docs: \"### GoogleDocumentId1 ###\", // Destination fileId of existing Google Document.\r\n      textFile: \"### textFileId1 ###\", // Source fileId of text file.\r\n    },\r\n    {\r\n      fileName: \"newFilename2\",\r\n      docs: \"### GoogleDocumentId2 ###\",\r\n      textFile: \"### textFileId2 ###\",\r\n    },\r\n  ];\r\n  var accessToken = ScriptApp.getOAuthToken();\r\n  var requests = contents.map(function (e) {\r\n    var metadata = { name: e.fileName };\r\n    var form = FetchApp.createFormData(); // Create form data\r\n    form.append(\r\n      \"metadata\",\r\n      Utilities.newBlob(JSON.stringify(metadata), \"application/json\")\r\n    );\r\n    form.append(\"file\", DriveApp.getFileById(e.textFile).getBlob());\r\n    var url =\r\n      \"https://www.googleapis.com/upload/drive/v3/files/\" +\r\n      e.docs +\r\n      \"?uploadType=multipart\";\r\n    params = {\r\n      url: url,\r\n      method: \"PATCH\",\r\n      headers: { Authorization: \"Bearer \" + accessToken },\r\n      body: form,\r\n    };\r\n    return params;\r\n  });\r\n  var res = FetchApp.fetchAll(requests);\r\n  Logger.log(res);\r\n  // DriveApp.createFile(blob) // This comment line is used for automatically detecting scope for running this sample script.\r\n}\r\n```\r\n\r\n\u003ca name=\"createformdata\"\u003e\u003c/a\u003e\r\n\r\n## 3. createFormData(), append(key, value)\r\n\r\n`createFormData()` and `append(key, value)` are used for creating an instance of formData, and appending an object to formData, respectively.\r\n\r\n**Sample scripts may be seen under the sections for [`fetch(url, params)`](#fetch) and [`fetchAll(requests)`](#fetchall).**\r\n\r\n- I referred to Javascript's [`Form​Data()`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData) and [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch) methods in creating these methods.\r\n\r\n# IMPORTANT\r\n\r\nI created this library for requesting multipart/form-data using Google Apps Script. While in my test scenarios, I could confirm that this script works, I am sorry to say that I cannot guarantee it will work for all purposes. I would like to make this library more encompassing; please report any issues you encounter.\r\n\r\nI sincerely hope this library is useful for you.\r\n\r\n---\r\n\r\n\u003ca name=\"Licence\"\u003e\u003c/a\u003e\r\n\r\n# Licence\r\n\r\n[MIT](LICENCE)\r\n\r\n\u003ca name=\"Author\"\u003e\u003c/a\u003e\r\n\r\n# Author\r\n\r\n[Tanaike](https://tanaikech.github.io/about/)\r\n\r\nIf you have any questions or comments, feel free to contact me.\r\n\r\n\u003ca name=\"Update_History\"\u003e\u003c/a\u003e\r\n\r\n# Update History\r\n\r\n- v1.0.0 (April 20, 2019)\r\n\r\n  1. Initial release.\r\n\r\n- v1.0.1 (April 13, 2020)\r\n\r\n  1. When V8 runtime is enabled, it was found that an error occurred. So this bug was removed. [Ref](#sample2)\r\n\r\n- v1.0.2 (September 19, 2020)\r\n\r\n  1. From this version, when a blob is sent, the blob is sent to `files`.\r\n\r\n[TOP](#top)\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftanaikech%2Ffetchapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftanaikech%2Ffetchapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftanaikech%2Ffetchapp/lists"}