{"id":19651754,"url":"https://github.com/tanaikech/specifying-output-types-for-gemini-api-with-google-apps-script","last_synced_at":"2026-04-02T01:09:20.805Z","repository":{"id":232733506,"uuid":"785055460","full_name":"tanaikech/Specifying-Output-Types-for-Gemini-API-with-Google-Apps-Script","owner":"tanaikech","description":"This repository is for \"Specifying Output Types for Gemini API with Google Apps Script\".","archived":false,"fork":false,"pushed_at":"2024-04-11T05:28:30.000Z","size":6,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-30T19:48:42.195Z","etag":null,"topics":["gemini","gemini-api","generative-ai","google-apps-script"],"latest_commit_sha":null,"homepage":"https://medium.com/@tanaike/specifying-output-types-for-gemini-api-with-google-apps-script-c2f6a753c8d7","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"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,"dei":null}},"created_at":"2024-04-11T05:21:55.000Z","updated_at":"2025-04-24T19:45:06.000Z","dependencies_parsed_at":"2024-04-11T06:44:46.742Z","dependency_job_id":null,"html_url":"https://github.com/tanaikech/Specifying-Output-Types-for-Gemini-API-with-Google-Apps-Script","commit_stats":null,"previous_names":["tanaikech/specifying-output-types-for-gemini-api-with-google-apps-script"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tanaikech/Specifying-Output-Types-for-Gemini-API-with-Google-Apps-Script","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanaikech%2FSpecifying-Output-Types-for-Gemini-API-with-Google-Apps-Script","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanaikech%2FSpecifying-Output-Types-for-Gemini-API-with-Google-Apps-Script/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanaikech%2FSpecifying-Output-Types-for-Gemini-API-with-Google-Apps-Script/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanaikech%2FSpecifying-Output-Types-for-Gemini-API-with-Google-Apps-Script/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tanaikech","download_url":"https://codeload.github.com/tanaikech/Specifying-Output-Types-for-Gemini-API-with-Google-Apps-Script/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanaikech%2FSpecifying-Output-Types-for-Gemini-API-with-Google-Apps-Script/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31293647,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T01:05:07.454Z","status":"ssl_error","status_checked_at":"2026-04-02T00:56:46.496Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["gemini","gemini-api","generative-ai","google-apps-script"],"created_at":"2024-11-11T15:07:50.729Z","updated_at":"2026-04-02T01:09:20.785Z","avatar_url":"https://github.com/tanaikech.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Specifying Output Types for Gemini API with Google Apps Script\r\n\r\nThis repository is for [\"Specifying Output Types for Gemini API with Google Apps Script\"](https://medium.com/@tanaike/specifying-output-types-for-gemini-api-with-google-apps-script-c2f6a753c8d7).\r\n\r\n![](https://tanaikech.github.io/image-storage/20240410b/fig1.jpg)\r\n\r\n# Abstract\r\n\r\nThe Gemini API generates different outputs depending on the prompts. This report explains how to use function calling in the new Gemini 1.5 API to control the output format (string, number, etc.) within a script during a chat session. This allows for more flexibility in using the Gemini API's results.\r\n\r\n# Introduction\r\n\r\nThe appearance of Gemini has already brought a wave of innovation to various fields. When the Gemini API returns a response, the format of the response is highly dependent on the input text provided as a prompt. For instance, to retrieve the output value as a JSON object, you need to explicitly include a prompt like \"Return JSON\" within your input. However, there can be situations where the API doesn't return the data in the desired format.\r\n\r\nIt's crucial to control the output type from the Gemini API. There might be scenarios where you specifically require the output to be in a particular format, such as a string, number, array, or object. Here's where the function calling for the Gemini API comes into play. This functionality allows you to process the output value using a script during a chat session. [Ref](https://medium.com/google-cloud/guide-to-function-calling-with-gemini-and-google-apps-script-0e058d472f45)\r\n\r\nIn essence, function calling empowers you to control the output type. We've previously explored this concept in reports focusing on specific use cases. [Ref](https://medium.com/google-cloud/categorization-using-gemini-pro-api-with-google-apps-script-804df0101161), [Ref](https://medium.com/google-cloud/flexible-labeling-for-gmail-using-gemini-pro-api-with-google-apps-script-part-2-08015af6b2e6) [Ref](https://medium.com/google-cloud/creating-image-bot-using-gemini-with-google-apps-script-51457cce03d7) [Ref](https://medium.com/google-cloud/attempting-reverse-engineering-with-gemini-api-and-google-apps-script-821b5e63ed79)\r\n\r\nThis report introduces a general-purpose script that enables control over the output type from the Gemini API. It's important to note that function calling is now supported in the latest Gemini 1.5 API, which is utilized in the script for this report.\r\n\r\n# Usage\r\n\r\nIn order to test this script, please do the following steps.\r\n\r\n## 1. Create an API key\r\n\r\nPlease access [https://makersuite.google.com/app/apikey](https://makersuite.google.com/app/apikey) and create your API key. At that time, please enable Generative Language API at the API console. This API key is used for this sample script.\r\n\r\nThis official document can be also seen. [Ref](https://ai.google.dev/).\r\n\r\n## 2. Create a Google Apps Script project\r\n\r\nIn this report, Google Apps Script is used. Of course, the method introducing this report can be also used in other languages.\r\n\r\nPlease create a standalone Google Apps Script project. Of course, this script can be also used with the container-bound script.\r\n\r\nAnd, please open the script editor of the Google Apps Script project.\r\n\r\n## 3. Base script\r\n\r\nThis is the base script of Class Gemini. This is used with the following sample script.\r\n\r\n```javascript\r\n/**\r\n * Output value by controlling the type.\r\n */\r\nclass Gemini {\r\n  /**\r\n   *\r\n   * @param {String} apiKey API key for Gemini API.\r\n   */\r\n  constructor(apiKey) {\r\n    const model = \"models/gemini-1.5-pro-latest\"; // or const model = \"models/gemini-pro\";\r\n    const version = \"v1beta\";\r\n    this.url = `https://generativelanguage.googleapis.com/${version}/${model}:generateContent?key=${apiKey}`;\r\n\r\n    this.functions = {\r\n      params_: {\r\n        customType_string: {\r\n          description:\r\n            \"Output type is string type. When the output type is string type, this is used. No descriptions and explanations.\",\r\n          parameters: {\r\n            type: \"OBJECT\",\r\n            properties: {\r\n              items: {\r\n                type: \"STRING\",\r\n                description:\r\n                  \"Output type is string type. When the output type is string type, this is used. No descriptions and explanations.\",\r\n              },\r\n            },\r\n            required: [\"items\"],\r\n          },\r\n        },\r\n        customType_number: {\r\n          description:\r\n            \"Output type is number type. When the output type is number type, this is used. No descriptions and explanations.\",\r\n          parameters: {\r\n            type: \"OBJECT\",\r\n            properties: {\r\n              items: {\r\n                type: \"NUMBER\",\r\n                description:\r\n                  \"Output type is number type. When the output type is number type, this is used. No descriptions and explanations.\",\r\n              },\r\n            },\r\n            required: [\"items\"],\r\n          },\r\n        },\r\n        customType_boolean: {\r\n          description:\r\n            \"Output type is boolean type. When the output type is boolean type, this is used. No descriptions and explanations.\",\r\n          parameters: {\r\n            type: \"OBJECT\",\r\n            properties: {\r\n              items: {\r\n                type: \"BOOLEAN\",\r\n                description:\r\n                  \"Output type is boolean type. When the output type is boolean type, this is used. No descriptions and explanations.\",\r\n              },\r\n            },\r\n            required: [\"items\"],\r\n          },\r\n        },\r\n        customType_array: {\r\n          description:\r\n            \"Output type is array type. When the output type is array type, this is used. No descriptions and explanations.\",\r\n          parameters: {\r\n            type: \"OBJECT\",\r\n            properties: {\r\n              items: {\r\n                type: \"ARRAY\",\r\n                description:\r\n                  \"Output type is array type. When the output type is array type, this is used. No descriptions and explanations.\",\r\n              },\r\n            },\r\n            required: [\"items\"],\r\n          },\r\n        },\r\n        customType_object: {\r\n          description:\r\n            \"Output type is JSON object type. When the output type is object type, this is used. No descriptions and explanations.\",\r\n          parameters: {\r\n            type: \"OBJECT\",\r\n            properties: {\r\n              items: {\r\n                type: \"OBJECT\",\r\n                description:\r\n                  \"Output type is JSON object type. When the output type is object type, this is used. No descriptions and explanations.\",\r\n              },\r\n            },\r\n            required: [\"items\"],\r\n          },\r\n        },\r\n      },\r\n      customType_string: (e) =\u003e e.items,\r\n      customType_number: (e) =\u003e e.items,\r\n      customType_boolean: (e) =\u003e e.items,\r\n      customType_array: (e) =\u003e e.items,\r\n      customType_object: (e) =\u003e e.items,\r\n    };\r\n  }\r\n\r\n  /**\r\n   * ### Description\r\n   * Main method.\r\n   *\r\n   * @param {String} q Input text.\r\n   * @returns {(String|Number|Array|Object|Boolean)} Output value.\r\n   */\r\n  run(q) {\r\n    const function_declarations = Object.keys(this.functions).flatMap((k) =\u003e\r\n      k != \"params_\"\r\n        ? {\r\n            name: k,\r\n            description: this.functions.params_[k].description,\r\n            parameters: this.functions.params_[k]?.parameters,\r\n          }\r\n        : []\r\n    );\r\n    const contents = [{ parts: [{ text: q }], role: \"user\" }];\r\n    let check = true;\r\n    const results = [];\r\n    let retry = 5;\r\n    do {\r\n      retry--;\r\n      const payload = { contents, tools: [{ function_declarations }] };\r\n      const res = UrlFetchApp.fetch(this.url, {\r\n        payload: JSON.stringify(payload),\r\n        contentType: \"application/json\",\r\n        muteHttpExceptions: true,\r\n      });\r\n      if (res.getResponseCode() == 500 \u0026\u0026 retry \u003e 0) {\r\n        console.warn(\"Retry by the status code 500.\");\r\n        this.run(q);\r\n      } else if (res.getResponseCode() != 200) {\r\n        throw new Error(res.getContentText());\r\n      }\r\n      const { candidates } = JSON.parse(res.getContentText());\r\n      if (candidates \u0026\u0026 !candidates[0]?.content?.parts) {\r\n        results.push(candidates[0]);\r\n        break;\r\n      }\r\n      const parts = (candidates \u0026\u0026 candidates[0]?.content?.parts) || [];\r\n      check = parts.find((o) =\u003e o.hasOwnProperty(\"functionCall\"));\r\n      if (check) {\r\n        contents.push({ parts: parts.slice(), role: \"model\" });\r\n        const functionName = check.functionCall.name;\r\n        const res2 = this.functions[functionName](\r\n          check.functionCall.args || null\r\n        );\r\n        if (/^customType_.*/.test(functionName)) {\r\n          return res2.items || res2;\r\n        }\r\n        contents.push({\r\n          parts: [\r\n            {\r\n              functionResponse: {\r\n                name: functionName,\r\n                response: { name: functionName, content: res2 },\r\n              },\r\n            },\r\n          ],\r\n          role: \"function\",\r\n        });\r\n        parts.push({ functionResponse: res2 });\r\n      }\r\n      results.push(...parts);\r\n    } while (check \u0026\u0026 retry \u003e 0);\r\n    const output = results.pop();\r\n    if (\r\n      !output ||\r\n      (output.finishReason \u0026\u0026\r\n        [\"OTHER\", \"RECITATION\"].includes(output.finishReason))\r\n    ) {\r\n      return \"No values.\";\r\n    }\r\n    return output.text.split(\"\\n\").map((e) =\u003e e.trim());\r\n  }\r\n}\r\n```\r\n\r\n## 4. Sample script 1\r\n\r\n```javascript\r\nfunction sample1() {\r\n  const apiKey = \"###\"; // Please set your API key.\r\n  const q = \"Return one randam word.\";\r\n\r\n  const res = new Gemini(apiKey).run(q);\r\n  console.log(res);\r\n}\r\n```\r\n\r\nWhen this script is run, the following result is obtained.\r\n\r\n```\r\nHello\r\n```\r\n\r\n## 5. Sample script 2\r\n\r\n```javascript\r\nfunction sample2() {\r\n  const apiKey = \"###\"; // Please set your API key.\r\n  const q = \"Return one randam number.\";\r\n\r\n  const res = new Gemini(apiKey).run(q);\r\n  console.log(res);\r\n}\r\n```\r\n\r\nWhen this script is run, the following result is obtained.\r\n\r\n```\r\n2\r\n```\r\n\r\n## 6. Sample script 3\r\n\r\n```javascript\r\nfunction sample3() {\r\n  const apiKey = \"###\"; // Please set your API key.\r\n  const q = \"Return 10 randam texts as an array.\";\r\n\r\n  const res = new Gemini(apiKey).run(q);\r\n  console.log(res);\r\n}\r\n```\r\n\r\nWhen this script is run, the following result is obtained.\r\n\r\n```\r\n[\"text1\",\"text2\",\"text3\",\"text4\",\"text5\",\"text6\",\"text7\",\"text8\",\"text9\",\"text10\"]\r\n```\r\n\r\n## 7. Sample script 4\r\n\r\n```javascript\r\nfunction sample4() {\r\n  const apiKey = \"###\"; // Please set your API key.\r\n  const q =\r\n    \"Think of 5 random animals and each size (meter), and return the result as JSON data with the format that the key and values are the name of the animal and the size, respectively.\";\r\n\r\n  const res = new Gemini(apiKey).run(q);\r\n  console.log(res);\r\n}\r\n```\r\n\r\nWhen this script is run, the following result is obtained.\r\n\r\n```\r\n{\"dog\":1,\"cat\":0.5,\"elephant\":3,\"mouse\":0.1,\"giraffe\":5.5}\r\n```\r\n\r\n## 8. Sample script 5\r\n\r\n```javascript\r\nfunction sample5() {\r\n  const apiKey = \"###\"; // Please set your API key.\r\n  const q =\r\n    \"Return the current population of Kyoto, Osaka, Aichi, Fukuoka, Tokyo in Japan as JSON data with the format that the key and values are the prefecture name and the population, respectively.\";\r\n\r\n  const res = new Gemini(apiKey).run(q);\r\n  console.log(res);\r\n}\r\n```\r\n\r\nWhen this script is run, the following result is obtained.\r\n\r\n```\r\n{\"Fukuoka\":5135214,\"Aichi\":7552873,\"Tokyo\":14047594,\"Osaka\":8837686,\"Kyoto\":1463723}\r\n```\r\n\r\n## 9. Sample script 6\r\n\r\n```javascript\r\nfunction sample6() {\r\n  const apiKey = \"###\"; // Please set your API key.\r\n  const q =\r\n    \"The longest river in the world is the Nile River. Return the result as a boolean.\";\r\n\r\n  const res = new Gemini(apiKey).run(q);\r\n  console.log(res);\r\n}\r\n```\r\n\r\nWhen this script is run, the following result is obtained.\r\n\r\n```\r\ntrue\r\n```\r\n\r\n# Summary\r\n\r\nIt is considered that the output type can be controlled by the function calling.\r\n\r\n# Note\r\n\r\nThe top image was created by [Gemini](https://gemini.google.com/app).\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftanaikech%2Fspecifying-output-types-for-gemini-api-with-google-apps-script","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftanaikech%2Fspecifying-output-types-for-gemini-api-with-google-apps-script","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftanaikech%2Fspecifying-output-types-for-gemini-api-with-google-apps-script/lists"}