<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>By @mhawksey</title>
	<atom:link href="https://hawksey.info/feed/" rel="self" type="application/rss+xml" />
	<link>https://hawksey.info</link>
	<description></description>
	<lastBuildDate>Sun, 08 Mar 2026 08:36:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Delegated Power: Showcasing a Google Workspace Admin Toolbox Concept in AppSheet and Apps Script</title>
		<link>https://hawksey.info/blog/2026/02/delegated-power-showcasing-a-google-workspace-admin-toolbox-concept-in-appsheet-and-apps-script/</link>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Fri, 27 Feb 2026 08:34:00 +0000</pubDate>
				<category><![CDATA[AppSheet]]></category>
		<category><![CDATA[GDE]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21066</guid>

					<description><![CDATA[The Google Admin Console is a powerful engine, but it often becomes a bottleneck for delegated tasks. IT teams frequently find themselves trapped in “Admin Debt,” repeating manual steps because granting full administrative access to others is a security risk. At the Google for Education IT Admin Summit in London, I shared a session on [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>The Google Admin Console is a powerful engine, but it often becomes a bottleneck for delegated tasks. IT teams frequently find themselves trapped in “Admin Debt,” repeating manual steps because granting full administrative access to others is a security risk.</p>



<p>At the Google for Education IT Admin Summit in London, I shared a session on how to move from a static interface to a dynamic, automated engine. The goal is to build an “Admin Toolbox” that showcases how some Admin SDK and other Workspace API capabilities can be integrated into secure, self-service applications using AppSheet and Google Apps Script.</p>



<p>For those who couldn’t attend, or for those who want to dig into the code, I’ve made the session guide available below.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>“We are building a data bridge that turns raw directory records into a functional database that understands who people are and, more importantly, who they report to.” — Session Guide: The Automated IT Toolbox</p>
</blockquote>



<h2 class="wp-block-heading"><strong>Practical Builds in the Toolbox</strong></h2>



<p>The session guide covers four distinct areas where these technologies intersect to solve common IT headaches:</p>



<ol class="wp-block-list">
<li><strong>Hierarchical Directory Apps</strong>: Building a connection to the Admin SDK to create a searchable directory with security filters based on reporting lines.</li>



<li><strong>Automated Shared Drive Provisioning</strong>: A workflow where AppSheet handles the request and Apps Script acts as the administrator to create and name drives automatically upon approval.</li>



<li><strong>ChromeOS Management</strong>: Using the Reports API to create a live activity feed of login events and issuing remote commands like “Lock Device.”</li>



<li><strong>AI-Powered Damage Reports</strong>: Utilising the Gemini API to analyse photos of damaged hardware. Users can snap a photo, and the AI provides a structured analysis of the severity and required parts.</li>
</ol>



<h2 class="wp-block-heading"><strong>Gemini as a Development Partner</strong></h2>



<p>A key takeaway from the session was that I didn’t write any of this code from scratch. Instead, I used the Gemini App as a pair programmer. While Gemini was excellent for standard data tasks, it reached its limits when handling more obscure or less documented API calls. In these areas, my existing knowledge of the Workspace platform was essential. I had to refine my prompts and provide specific technical context to guide the model toward a reliable solution. It highlights that while AI is a powerful assistant, it still needs a knowledgeable pilot to navigate the complexities of advanced APIs.</p>



<p>The full session guide includes code snippets as well as some of the advanced ‘watch’ and Gemini API structured output.</p>



<p><em>Source:&nbsp;<a href="https://docs.google.com/document/d/1rAEJ0wC3IqSUPWcfPg4fwpgvjfZSu8Fu0B00PjkImig/copy" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">Google Doc<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>&nbsp;|&nbsp;<a href="https://github.com/mhawksey/Session-Guide-The-Automated-IT-Toolbox/" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">GitHub Repo<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a></em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Unlocking Google&#8217;s Full API Universe and Authentication Flows in Google Apps Script</title>
		<link>https://hawksey.info/blog/2025/08/unlocking-googles-full-api-universe-and-authentication-flows-in-google-apps-script/</link>
					<comments>https://hawksey.info/blog/2025/08/unlocking-googles-full-api-universe-and-authentication-flows-in-google-apps-script/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Sun, 03 Aug 2025 16:04:18 +0000</pubDate>
				<category><![CDATA[GDE]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21055</guid>

					<description><![CDATA[Excited to share a project I've been working on to solve a common headache for Google Apps Script developers: accessing the full universe of Google APIs.
Ever hit a wall because the API you need isn't built-in, or found it impossible to use a service account with standard services? 

The Google API Client Library Generator for Apps Script is an open source repository containing pre-built Google Apps Script client libraries for over 400 Google APIs.

Key features include:
✅ Complete API Coverage: From Firebase to Cloud Billing, if it's in the Discovery Service, there's a library for it.
🔧 Flexible Authentication: Unlocks professional workflows with support for service accounts and custom OAuth clients.
⚙️ Robust Features: Built-in automatic exponential backoff for handling API errors gracefully.

I've written this article that walks through the "why" and shows a practical example of using a service account with the generated Drive library.]]></description>
										<content:encoded><![CDATA[
<p>For many developers, Google Apps Script is the go-to platform for rapidly automating and extending Google Workspace. Its simplicity and deep integration are powerful. But as projects grow in ambition, developers often encounter two significant walls: needing to connect to a Google API that isn&#8217;t built-in, or requiring an authentication flow, like a service account, that the standard services don&#8217;t support.</p>



<p>What if you could break through those walls? What if you could use a robust client library for&nbsp;<strong>almost any</strong>&nbsp;Google API—from Firebase to Cloud Billing—in seconds, right from Apps Script itself?</p>



<p>Today, I&#8217;m excited to introduce the <strong><a href="https://github.com/mhawksey/Google-API-Client-Library-Generator-for-Apps-Script" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Google API Client Library Generator for Apps Script<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a></strong>, a project and code repository designed to solve these very challenges. It comes with a full suite of pre-built libraries, enabling you to significantly expand what&#8217;s possible on the platform.</p>



<h2 class="wp-block-heading" id="-why-this-matters-beyond-the-built-in-services-"><strong>Why This Matters: Beyond the Built-in Services</strong></h2>



<p>While Apps Script&#8217;s built-in and advanced services are excellent, they represent just a fraction of Google&#8217;s vast API ecosystem. This collection of generated libraries unlocks the rest, offering two critical advantages:</p>



<ol class="wp-block-list">
<li><strong>Complete API Coverage:</strong> The generator uses the Google APIs Discovery Service to create clients for over 400 APIs. If it&#8217;s in the Google Discovery Service then there is a library for it in the repository.</li>



<li><strong>Flexible Authentication Flows:</strong> Generated libraries are not tied to the standard user-permission model. This means you can use service accounts for server-to-server authentication, or implement other OAuth2 flows as needed.</li>
</ol>



<h2 class="wp-block-heading" id="-getting-started-"><strong>Getting Started</strong></h2>



<p>Getting started is as simple as finding the library you need in the&nbsp;<code>build/</code>&nbsp;directory of the&nbsp;<a href="https://github.com/mhawksey/Google-API-Client-Library-Generator-for-Apps-Script/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">GitHub repository<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>&nbsp;and copying the code into your Apps Script project. For detailed setup instructions and other authentication options, please refer to the main&nbsp;<code>README.md</code>&nbsp;in the repository.</p>



<h2 class="wp-block-heading" id="-unlocking-professional-workflows-with-service-accounts-"><strong>Unlocking Professional Workflows with Service Accounts</strong></h2>



<p>The real power of this approach comes from flexible authentication. For Google Workspace developers, this also unlocks the ability to use service accounts with domain-wide delegation to make API calls on behalf of other users in your domain.</p>



<p>To handle the authentication flow, you&#8217;ll need an OAuth2 library. The following example uses the&nbsp;<a href="https://github.com/googleworkspace/apps-script-oauth2" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">OAuth2 for Apps Script<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>&nbsp;library, but other options are also available. Once you have your chosen library set up, you can use the following pattern:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: gas; title: ; notranslate">
// The email of the user to impersonate (for domain-wide delegation).
const USER_EMAIL = &#039;user-to-impersonate@yourdomain.com&#039;; 

function getService_() {
  // Credentials from the service account&#039;s JSON key file.
  const serviceAccountCreds = {
    &quot;private_key&quot;: &quot;-----BEGIN PRIVATE KEY-----\n...&quot;,
    &quot;client_email&quot;: &quot;your-service-account@your-project.iam.gserviceaccount.com&quot;,
  };

  // Use a unique name for the service, like &#039;Drive&#039; or &#039;BigQuery&#039;, to avoid
  // token collisions between different services.
  return OAuth2.createService(&#039;Drive:&#039; + USER_EMAIL)
      .setTokenUrl(&#039;https://oauth2.googleapis.com/token&#039;)
      .setPrivateKey(serviceAccountCreds.private_key)
      .setIssuer(serviceAccountCreds.client_email)
      .setSubject(USER_EMAIL)
      .setCache(CacheService.getUserCache())
      .setScope(&#039;https://www.googleapis.com/auth/drive&#039;);
}

/**
 * Lists files using the configured service account.
 */
function listFilesWithServiceAccount() {
  const service = getService_();
  if (!service.hasAccess()) {
    console.log(&#039;Service Account authentication failed: &#039; + service.getLastError());
    return;
  }
  
  const token = service.getAccessToken();

  // This is where the generated library is used with the custom token.
  const drive = new Drive({
    token: token 
  });

  const files = drive.files.list({
    supportsAllDrives: true,
    pageSize: 10
  });
  
  console.log(&#039;Files found via service account:&#039;, JSON.stringify(files, null, 2));
}
</pre></div>


<h2 class="wp-block-heading" id="-under-the-bonnet-the-generator-"><strong>Under the Bonnet: The Generator</strong></h2>



<p>For those who want to tweak the generation logic or integrate it into their own workflows, the generator itself is included in the repository. It&#8217;s a self-contained Apps Script project that fetches API metadata and programmatically constructs modern, robust ES6 classes with features like automatic exponential backoff for handling API errors.</p>



<h2 class="wp-block-heading" id="-join-the-community-and-contribute-"><strong>Join the Community and Contribute</strong></h2>



<p>This project was heavily inspired by the work of&nbsp;<a href="https://github.com/Spencer-Easton/Apps-Script-GoogleApis-Libraries" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Spencer Easton<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>&nbsp;and aims to build upon that foundation. It&#8217;s a community effort.</p>



<p>While libraries for all APIs are generated, not all have been extensively tested. If you use a library and find a bug, or have an idea for an improvement, please&nbsp;<a href="https://github.com/mhawksey/Google-API-Client-Library-Generator-for-Apps-Script/issues" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">open a GitHub Issue<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>. Pull requests are, of course, always welcome. Happy scripting!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hawksey.info/blog/2025/08/unlocking-googles-full-api-universe-and-authentication-flows-in-google-apps-script/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Streamlining Google Workspace Development: Editing JSON files in Google Drive with Apps Script (and a little help from AI)</title>
		<link>https://hawksey.info/blog/2025/04/streamlining-google-workspace-development-editing-json-files-in-google-drive-with-apps-script-and-a-little-help-from-ai/</link>
					<comments>https://hawksey.info/blog/2025/04/streamlining-google-workspace-development-editing-json-files-in-google-drive-with-apps-script-and-a-little-help-from-ai/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Wed, 23 Apr 2025 21:44:42 +0000</pubDate>
				<category><![CDATA[GDE]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<category><![CDATA[Google Drive]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21040</guid>

					<description><![CDATA[Storing JSON files in Google Drive offers a practical approach for Google Workspace developers, especially when combined with Google Apps Script. While Drive lacks a built-in JSON editor, AI tools like Gemini can rapidly prototype solutions, such as web-based editors. However, creating a robust application requires more than just a quick fix. It involves understanding syntax highlighting, managing dependencies, and navigating the constraints of the Apps Script platform, highlighting the importance of both rapid prototyping and robust engineering skills.]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading"><strong>Introduction</strong></h2>



<p>When developing solutions for Google Workspace, whether it&#8217;s add-ons, automations, or custom workflows, managing configuration data is a common requirement. JSON files are a natural fit for this – they are human-readable, easy to work with, and flexible. While there are many ways to store these configurations, using Google Drive offers some distinct advantages, particularly when combined with the power of Google Apps Script. This article explores the benefits of this approach, shares a real-world scenario where quick editing was needed, and discusses the journey from a rapid AI-assisted solution to a more robust tool.</p>



<h2 class="wp-block-heading"><strong>Why Store JSON Configuration or Data in Google Drive?</strong></h2>



<p>For developers already working within the Google Workspace platform, storing project-related JSON files directly in Google Drive makes a lot of sense:</p>



<ol class="wp-block-list">
<li><strong>Centralised &amp; Secure Storage: </strong>Store your JSON files within organised Google Drive folder hierarchies alongside other project assets. This not only centralises your project data but also allows you to utilise Drive&#8217;s robust sharing controls (Access Control Lists &#8211; ACLs) to securely manage who can view or edit sensitive configuration data.</li>



<li><strong>Version History:</strong> Google Drive automatically tracks file versions, providing a safety net if you need to revert changes.</li>



<li><strong>Native Workspace Data Format:</strong> Many Google Workspace APIs (like the Admin SDK, Calendar API, etc.) return data formatted as JSON. Storing these responses directly in Drive can be a convenient way to cache or process this information using Apps Script without immediate complex database setups.</li>



<li><strong>Seamless Apps Script Integration:</strong> This is the key technical benefit. Google Apps Script provides native services (DriveApp) to easily access and manipulate files stored in Drive, making reading, writing, and processing this JSON data straightforward.</li>
</ol>



<h2 class="wp-block-heading"><strong>The Editing Challenge: When Manual Tweaks are Needed</strong></h2>



<p>Recently, while working on a project, I encountered a situation where I needed to quickly manually modify several JSON configuration files stored in Google Drive.&nbsp;</p>



<p>The standard workflow would involve downloading, editing locally, and re-uploading – cumbersome for quick changes. Google Drive doesn&#8217;t have a built-in editor suitable for JSON syntax highlighting and validation. I needed a faster, in-browser solution.</p>



<h2 class="wp-block-heading"><strong>Gemini to the Rescue: &#8220;Vibe Coding&#8221; a Quick Fix</strong></h2>



<p>Not wanting to get sidetracked building a full-fledged tool, I turned to Gemini. My initial request was simple:</p>



<p><em>&#8220;Can you write me a google apps script web app for me to use to edit a json file in Google Drive. I would like to provide a drive url which open the json file in a basic code editor and includes a save button which updates the existing json file in drive&#8221;</em></p>



<p>Gemini immediately provided the necessary Apps Script code (Code.gs and index.html) for a basic, functional online editor. It solved my immediate problem rapidly and it even looked nice.</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="925" height="699" src="https://hawksey.info/wp-content/uploads/2025/04/Screenshot-2025-04-23-at-22.13.18.png" alt="" class="wp-image-21041" srcset="https://hawksey.info/wp-content/uploads/2025/04/Screenshot-2025-04-23-at-22.13.18.png 925w, https://hawksey.info/wp-content/uploads/2025/04/Screenshot-2025-04-23-at-22.13.18-300x227.png 300w, https://hawksey.info/wp-content/uploads/2025/04/Screenshot-2025-04-23-at-22.13.18-768x580.png 768w" sizes="(max-width: 925px) 100vw, 925px" /></figure>



<h2 class="wp-block-heading"><strong>From Quick Prototype to Robust Solution: The Development Reality</strong></h2>



<p>While the Gemini-generated solution was a lifesaver, the journey highlighted the significant difference between a quick fix and a more robust solution. To do so required a degree of technical knowledge and skill. My subsequent requests to Gemini illustrate this evolution:</p>



<ol class="wp-block-list">
<li><strong>Improving the UI/UX (Syntax Highlighting):</strong> The basic &lt;textarea&gt; worked, but for JSON, syntax highlighting and basic validation are crucial. My next prompt was: <em>&#8220;Is there a way to add a basic json linter/syntax highlighter to the web app?&#8221;</em> This introduced the need for external JavaScript libraries (like CodeMirror or Ace Editor) and the associated CSS, adding complexity.</li>



<li><strong>Managing Dependencies (Local Hosting):</strong> Relying on external CDNs can be problematic and introduces risks like external dependency, security vulnerabilities, and version inconsistencies. With this in mind I then asked: <em>&#8220;Rather than using cdn hosted versions&#8230; I would like to host locally in the apps script web app.&#8221;</em> This led down a rabbit hole of trying to include local files within Apps Script&#8217;s HTML Service, involving techniques like custom include functions and wrestling with HtmlService limitations (like the <em>&#8220;Malformed HTML content&#8221;</em> errors I encountered). This required specific knowledge of Apps Script templating, its constraints, and other existing solutions (in this case I was already aware of Bruce Mcpherson’s <a href="https://ramblings.mcpher.com/gassnippets2/reusing-html-stuff-between-apps-script-projects/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Reusing html stuff between Apps Script projects<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> method. I even explored alternative methods based on online examples.</li>



<li><strong>Evaluating Libraries:</strong> Realising the limitations of CodeMirror, I considered more powerful options that I already knew about: <em>&#8220;Ok &#8211; do you think it would be better to implement JSON Editor </em><a href="https://github.com/josdejong/jsoneditor" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><em>https://github.com/josdejong/jsoneditor</em><i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a><em>&#8220;</em>&nbsp;</li>
</ol>



<p>The AI was fantastic for the initial boost, but building the polished, reliable tool required specific technical knowledge, iterative refinement, and problem-solving based on understanding the underlying technologies and their limitations.If you would like to mark my final homework and some further Gemini wrangling/tweaking below is a screenshot of my own little <a href="https://script.google.com/d/1pSdDw11Hsx96A9zF5thg5D07_wun2lOaBzRS-zy060UVfCHdLePrM5vl/edit?usp=sharing" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">JSON Editor for Google Drive, which you can view/copy<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="911" height="799" src="https://hawksey.info/wp-content/uploads/2025/04/Screenshot-2025-04-23-at-22.28.06.png" alt="" class="wp-image-21042" srcset="https://hawksey.info/wp-content/uploads/2025/04/Screenshot-2025-04-23-at-22.28.06.png 911w, https://hawksey.info/wp-content/uploads/2025/04/Screenshot-2025-04-23-at-22.28.06-300x263.png 300w, https://hawksey.info/wp-content/uploads/2025/04/Screenshot-2025-04-23-at-22.28.06-768x674.png 768w" sizes="(max-width: 911px) 100vw, 911px" /></figure>



<h2 class="wp-block-heading"><strong>Conclusion</strong></h2>



<p>Storing JSON files in Google Drive is a practical and efficient strategy for Google Workspace developers, thanks to the ease of integration with Google Apps Script. While Drive lacks a native JSON editor, AI tools like Gemini can be incredibly effective at rapidly prototyping solutions for specific needs, such as the quick web-based editor described here.</p>



<p>However, it&#8217;s important to recognise the difference between a quick, functional prototype and a polished, robust application. As demonstrated by the evolution from a simple editor request to tackling syntax highlighting, local dependencies, and styling frameworks, building robust tools still requires development effort, knowledge of relevant frameworks, libraries, and the specific constraints of the Apps Script platform. Understanding both the power of quick solutions and the requirements of robust engineering is still a required skill for effective development in the Google Workspace ecosystem.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hawksey.info/blog/2025/04/streamlining-google-workspace-development-editing-json-files-in-google-drive-with-apps-script-and-a-little-help-from-ai/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Google Workspace Flows: A Developer&#8217;s First Look After Cloud Next &#8217;25</title>
		<link>https://hawksey.info/blog/2025/04/google-workspace-flows-a-developers-first-look-after-cloud-next-25/</link>
					<comments>https://hawksey.info/blog/2025/04/google-workspace-flows-a-developers-first-look-after-cloud-next-25/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Tue, 15 Apr 2025 17:51:16 +0000</pubDate>
				<category><![CDATA[GDE]]></category>
		<category><![CDATA[Google]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21047</guid>

					<description><![CDATA[Google Workspace Flows was the standout announcement for me at hashtag#GoogleCloudNext '25. My key takeaway is they are more than just simple automation; Flows brings AI agents into the loop to tackle complex workflows requiring context and reasoning.

The aspect I most excited about is the potential for developers to extend Flows. Whilst there are still limited details I dive into what Workspace Flows offers now and, crucially for developers, the exciting roadmap ahead: 

✨ Apps Script extensibility 
✨ A new Connector Platform 
✨ Potential for custom Vertex AI models]]></description>
										<content:encoded><![CDATA[
<p id="ember3477">Last week at Google Cloud Next &#8217;25 was packed with announcements, but one that particularly grabbed my attention was the unveiling of Google Workspace Flows. As Google Apps Script developers, many of us are familiar with automating simple tasks. However, the Flows demo hinted at a more accessible approach for tackling complex business processes.</p>



<p id="ember3478">Think about those workflows that go beyond basic if-this-then-that and into a world where you can easily configure Gemini to be your virtual assistant. Updating specific spreadsheet entries based on nuanced analysis, or finding and summarising information scattered across different files before replying to a customer. Traditional automation often hits a wall here because these tasks require context, reasoning, and sometimes even creative generation – capabilities standard automation tools lack.</p>



<h2 class="wp-block-heading" id="ember3479">Workspace Flows: AI Agents Joining the Workflow</h2>



<p id="ember3480">What Google presented with Flows is a new solution for Google Workspace designed to automate these kinds of multi-step processes with AI providing assistance. Instead of just triggering actions, Flows uses AI models, including Gemini, as <strong>agents within the loop</strong>. This means the AI isn&#8217;t just kicking off a process; it&#8217;s actively participating – researching, analysing, creating, and reasoning to help get work done more efficiently and intelligently.</p>



<p id="ember3481">Having used tools like IFTTT it feels like a conceptual shift from simple automation to building intelligent, agentic workflows directly within the Workspace environment, without writing a single line of code.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="577" src="https://hawksey.info/wp-content/uploads/2025/05/1744727972142-1024x577.jpeg" alt="" class="wp-image-21048" srcset="https://hawksey.info/wp-content/uploads/2025/05/1744727972142-1024x577.jpeg 1024w, https://hawksey.info/wp-content/uploads/2025/05/1744727972142-300x169.jpeg 300w, https://hawksey.info/wp-content/uploads/2025/05/1744727972142-768x433.jpeg 768w, https://hawksey.info/wp-content/uploads/2025/05/1744727972142.jpeg 1440w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Image credit: Google</figcaption></figure>



<p id="ember3483">If you would like to see Flows in action I highly recommend you check out the Google Cloud Next session ‘<a href="https://www.youtube.com/watch?v=ZO3CKEUOWS0" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">New ways to automate your work and integrate with Google Workspace<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>’.</p>



<h2 class="wp-block-heading" id="ember3484">Why Flows Looks Interesting for Developers: Current Capabilities and Future Vision</h2>



<p id="ember3485">Beyond the core AI capabilities shown in the demo, Google outlined a vision for Flows that is particularly relevant for developers, indicating where the platform is heading:</p>



<ul class="wp-block-list">
<li><strong>No-Code/Low-Code Interface (Current):</strong> The initial preview allows configuring triggers (like new emails, form responses, etc.) and actions across core Workspace apps and integrating Gemini and Gems for AI-driven steps, removing the need to find alternative solutions (code you write or third party solutions).</li>



<li><strong>Apps Script Extensibility (Future Vision): </strong>Google announced plans to allow developers to build their own custom triggers and actions using Apps Script. This creates the opportunity to integrate your own systems or add specific logic to get more out of Flows. The presentation briefly showed an example appsscript.json manifest snippet for declaring these elements <a href="https://youtu.be/ZO3CKEUOWS0?si=CN0mt0nuy2zTiEgs&amp;t=788" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">around 13:08<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>).</li>



<li><strong>Workspace Connectors Platform (Future Vision): </strong>A dedicated platform for third-party integrations was also announced in the presentation as part of the roadmap. The plan is to enable connections to tools like Jira, Asana, Salesforce, HubSpot, etc., allowing them to be used as triggers or actions. The stated goal is to include the ability to build end-to-end workflows spanning beyond Google Workspace, with connectors built once potentially working in both Flows and Gemini Extensions.</li>



<li><strong>Bring Your Own Models via Vertex AI (Future Vision): </strong>For advanced AI needs, Google shared the vision for integrating your own custom or fine-tuned models hosted on Google Cloud&#8217;s Vertex AI. The concept shown involved an &#8216;Ask an LLM&#8217; step where you could select a &#8216;Custom Model&#8217; directly within the flow builder, pointing towards future capabilities for incorporating highly specialized AI into Workspace automations.</li>
</ul>



<h2 class="wp-block-heading" id="ember3487">Looking Ahead</h2>



<p id="ember3488">Google Workspace Flows is definitely a platform I&#8217;ll be watching closely. The initial preview, focusing on AI agents-in-the-loop and core Workspace automation, is already compelling. But the announced roadmap for developer extensibility – adding Apps Script support, a robust connector platform, and the ability to call custom Vertex AI models – is what makes Flows truly exciting from a development perspective.</p>



<p id="ember3489">Flows is currently in alpha with its initial feature set. If this vision sounds as interesting to you as it did to me, you can <a href="https://cloud.google.com/events/next25-offer-02" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">sign up for the early access waitlist<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hawksey.info/blog/2025/04/google-workspace-flows-a-developers-first-look-after-cloud-next-25/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>GeminiApp Gets a Major Upgrade: Seamless Transition Between Google AI Studio and Vertex AI, Enhanced Functionality, Multimodal Input, and More!</title>
		<link>https://hawksey.info/blog/2025/01/geminiapp-gets-a-major-upgrade-seamless-transition-between-google-ai-studio-and-vertex-ai-enhanced-functionality-multimodal-input-and-more/</link>
					<comments>https://hawksey.info/blog/2025/01/geminiapp-gets-a-major-upgrade-seamless-transition-between-google-ai-studio-and-vertex-ai-enhanced-functionality-multimodal-input-and-more/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Mon, 27 Jan 2025 08:25:12 +0000</pubDate>
				<category><![CDATA[GDE]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21028</guid>

					<description><![CDATA[The GeminiApp library, designed to bring Google's Gemini AI models into your Google Apps Script projects, has just received a major update. This new release, version 2025.01, introduces significant enhancements that expand the library's capabilities for building sophisticated AI-powered applications within Google Workspace. This update marks a step forward for developers integrating Gemini into Google Workspace. ]]></description>
										<content:encoded><![CDATA[
<p>The&nbsp;<a href="https://github.com/mhawksey/GeminiApp/" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">GeminiApp library<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>, a solution I created for integrating Google&#8217;s Gemini AI models into your Google Apps Script projects, has had a major update!&nbsp;</p>



<p>Since its&nbsp;<a href="https://hawksey.info/blog/2024/01/genai-for-google-workspace-exploring-gemini-api-function-calling-with-google-apps-script-part-3/" target="_blank" rel="noreferrer noopener" data-wpel-link="internal">publication last year</a>&nbsp;it has been great to hear and see how GeminiApp is being used by the community, including members of Google&#8217;s DevRel team highlighting it as an option. This new release introduces significant enhancements, expanding the library&#8217;s capabilities for building sophisticated AI-powered applications directly within Google Workspace.</p>



<p>This post will explore the key enhancements included in the 2025.01 version bump, focusing on how these changes empower you to do even more with Gemini and Apps Script.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="771" src="https://hawksey.info/wp-content/uploads/2024/09/PXL_20240917_0857504282-1024x771.jpg" alt="Google Workspace Summit, Berlin" class="wp-image-21019" srcset="https://hawksey.info/wp-content/uploads/2024/09/PXL_20240917_0857504282-1024x771.jpg 1024w, https://hawksey.info/wp-content/uploads/2024/09/PXL_20240917_0857504282-300x226.jpg 300w, https://hawksey.info/wp-content/uploads/2024/09/PXL_20240917_0857504282-768x578.jpg 768w, https://hawksey.info/wp-content/uploads/2024/09/PXL_20240917_0857504282-1536x1157.jpg 1536w, https://hawksey.info/wp-content/uploads/2024/09/PXL_20240917_0857504282-2048x1542.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Google Workspace Developer Summit: Berlin &#8211; Plenary Session, September 2024</figcaption></figure>



<h3 class="wp-block-heading">What&#8217;s New?</h3>



<p>The latest update to the GeminiApp library is a significant leap forward in terms of functionality, flexibility, and ease of deployment. The library now boasts enhanced capabilities that allow for more intricate interactions with the Gemini API, and perhaps more importantly, it facilitates a smooth transition from the Google AI Studio environment to Vertex AI.&nbsp;</p>



<h3 class="wp-block-heading">Enhanced Functionality and Control</h3>



<p>Beyond cross-compatibility, the GeminiApp library has also evolved to offer enhanced control over how you interact with Gemini models. This includes the following new features:</p>



<ul class="wp-block-list">
<li><strong>JSON-Controlled Generation:</strong> Generate content in JSON format by providing a schema or letting the model infer the schema from your prompt. This is useful for creating structured outputs that can be easily integrated into applications.&nbsp;</li>



<li><strong>Code Execution:</strong> You can now generate and execute code directly within your prompts using the gemini-2.0 models. This feature lets the model perform calculations and execute programmatic logic within the API call, opening up new possibilities for dynamic and interactive applications.&nbsp;</li>



<li><strong>System Instructions:</strong> You can now guide the model’s behavior and persona by providing system instructions during the initialization of the GenerativeModel. This gives you fine-grained control over the model’s responses and allows you to tailor the AI’s output to specific contexts and user needs.&nbsp;</li>



<li><strong>Caching:</strong> Improve efficiency and reduce token usage by caching file uploads. This enables repeated processing of the same document without incurring the full token cost each time.  <br><strong>Note:</strong> For now the cache integration is limited to Google AI Studio, but I’ll be keeping an eye on changes to the Vertex AI APIs to make it possible there as well.</li>
</ul>



<h3 class="wp-block-heading">Easier Copy/Paste Programming&nbsp;</h3>



<p>One of the other small enhancements in this update is making it easier to copy/paste code generated with&nbsp; Google AI Studio. To make it easier to transition from Google AI Studio and other examples published for the Javascript client library, GeminiApp now supports initialization using both new GeminiApp() and new GoogleGenerativeAI(). This means you can use Google AI Studio to experiment with prompts and Gemini API advanced features then use the ‘Get code’ output in your Apps Script project. For example, if you&nbsp;<a href="https://github.com/google-gemini/generative-ai-js/tree/main/samples" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">explore the Google Gemini Generate AI JS sample<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>, you’ll see most of them are used in the GeminiApp&nbsp;<a href="https://github.com/mhawksey/GeminiApp/blob/main/tests/tests.js" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">tests/tests.js<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>.</p>



<h3 class="wp-block-heading">Key Code Changes</h3>



<p>The 2025.01 version bump isn;t just about the new features outlined above and if you dig into the commit there are over 1.5K new lines of code mostly across three key files:</p>



<ul class="wp-block-list">
<li>src/GeminiApp.js: This file contains the core logic of the GeminiApp library. The modifications here are extensive and include the implementation of the new features like code execution, JSON-controlled generation, system instructions, and caching.&nbsp;</li>



<li>src/GoogleAICacheManager.js: This optional file manages the caching mechanism, including the creation, listing, getting, updating, and deleting of cached content. The caching functionality helps improve efficiency and reduce token usage.</li>



<li>tests/tests.js: This file contains the test suite for the GeminiApp library. The new test cases ensure the library functions correctly after the update, covering features like text generation, chat, code execution, JSON-controlled generation, multimodal interactions, and function calling.</li>
</ul>



<h3 class="wp-block-heading">Updating existing GeminiApp projects</h3>



<p>If you have existing projects using the older version of the GeminiApp library you should be able to replace your existing&nbsp;<a href="https://github.com/mhawksey/GeminiApp/blob/main/src/GeminiApp.js" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">GeminiApp.gs<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>&nbsp;code with the updated library, with no additional changes, but if you have projects in production I would recommend testing before redeploying.</p>



<h3 class="wp-block-heading">Getting Started</h3>



<p>If you are new to the GeminiApp library it supports multiple setup options. To start using the new features, you can refer to the updated examples and test cases in the&nbsp;<a href="https://github.com/mhawksey/GeminiApp" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">README.md<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>&nbsp;file.&nbsp;</p>



<h3 class="wp-block-heading">Important Considerations</h3>



<p>While these updates bring significant enhancements, there are a few points to keep in mind:</p>



<ul class="wp-block-list">
<li>Model Selection: Always refer to the Google AI Studio and Vertex AI documentation for the latest information on model selection and API usage. Note that for certain features like code execution, you may need to specify the apiVersion as v1beta.</li>



<li>Prototyping vs. Production: Remember that Google AI Studio should be used for prototyping, while Vertex AI is suitable for both prototyping and production.</li>



<li>Caching: The caching mechanism requires including the GoogleAICacheManager.js file in your project..</li>
</ul>



<h3 class="wp-block-heading">A Step Forward for Google Workspace AI</h3>



<p>The 2025.01 update to the GeminiApp library marks a significant step forward for developers looking to integrate the power of Gemini into their Google Workspace applications. With the ability to seamlessly transition from Google AI Studio to Vertex AI, along with new features like code execution, JSON-controlled generation, system instructions and enhanced multimodal input, the possibilities are endless. This release provides developers with the tools they need to create more powerful, efficient, and user-friendly AI solutions.</p>



<p>By using these new capabilities and the cross-compatibility between Google AI Studio and Vertex AI, you can create more robust and versatile applications. This update not only improves functionality but also gives developers a broader set of tools to create more personalized and efficient workflows. As the Gemini API evolves, libraries like GeminiApp will continue to bridge the gap between powerful AI models and Google Workspace users. The easy transition between environments means that your projects can grow with your needs, starting with simple prototypes and evolving into full-fledged production applications.</p>



<p>If you have interesting use cases for the GeminiApp, code improvements or feature requests, please feel free to get in touch!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hawksey.info/blog/2025/01/geminiapp-gets-a-major-upgrade-seamless-transition-between-google-ai-studio-and-vertex-ai-enhanced-functionality-multimodal-input-and-more/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Gemini for Google Workspace: Empowering Enterprise Productivity While Preserving Critical Thinking</title>
		<link>https://hawksey.info/blog/2025/01/gemini-for-google-workspace-empowering-enterprise-productivity-while-preserving-critical-thinking/</link>
					<comments>https://hawksey.info/blog/2025/01/gemini-for-google-workspace-empowering-enterprise-productivity-while-preserving-critical-thinking/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Sun, 19 Jan 2025 21:06:29 +0000</pubDate>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[thinkingallowed]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21034</guid>

					<description><![CDATA[With the recent announcement that Google is bringing the latest generative AI capabilities to business customers without the need to purchase Gemini for Google Workspace, I thought I would look at the wider implications of this and specifically empowering enterprise productivity while preserving critical thinking.]]></description>
										<content:encoded><![CDATA[
<p id="ember917"><em>This article was co-authored by Martin Hawksey with the Gemini App and NotebookLM. You can </em><a href="https://docs.google.com/document/d/18HpmvPHmtYiWrEVhuZzAND0P4E6UOzEwY1SXkZpGrD4/edit" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><em>read some of the transcript of our conversation</em><i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a><em>, plus </em><a href="https://notebooklm.google.com/notebook/08223f4d-5570-437e-8891-467d89bd0b5b/audio" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><em>bonus NotebookLM podcast of my data sources</em><i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a><em>.</em></p>



<p id="ember918">Generative AI is poised to revolutionise the way we work, and last week&#8217;s news from Google about the expansion of Gemini for Google Workspace only reinforces this notion. The announcement that <a href="https://workspaceupdates.googleblog.com/2025/01/expanding-google-ai-to-more-of-google-workspace.html" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><strong>The best of Google AI is now included in Workspace Business and Enterprise plans</strong><i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> signals a major step towards making these powerful tools accessible to a wider audience. This innovative technology has the potential to transform enterprises, enabling employees to collaborate with AI in unprecedented ways. Imagine drafting marketing campaigns with AI assistance, brainstorming ideas in dynamic conversations, and witnessing real-time generation of compelling copy and visuals. This is the reality that generative AI tools like Gemini are bringing to the workplace.</p>



<p id="ember919">One striking example of generative AI&#8217;s potential impact on the future of work is illustrated by <a href="https://www.linkedin.com/in/benlcollins/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Ben Collins<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>&#8216; experiment with AI Studio&#8217;s experimental tool. In a YouTube video, <a href="https://www.youtube.com/watch?v=4ocypQw-4Vo" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Ben demonstrates in real-time how Gemini within AI Studio can assist users in creating pivot tables in Google Sheets<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>, a task many find daunting. While the AI doesn&#8217;t yet have full control over the spreadsheet, its ability to provide step-by-step guidance and correct user errors highlights its potential as a powerful learning and productivity tool. As Collins noted, it&#8217;s only a matter of time before AI can seamlessly execute such tasks in real time.</p>



<p id="ember921">But this future isn&#8217;t without its challenges. As AI takes on more tasks and provides ready-made solutions, a critical question emerges: how do we ensure that human critical thinking skills remain sharp?</p>



<h2 class="wp-block-heading" id="ember922">The Impact of AI on Critical Thinking</h2>



<p id="ember923">The rapid evolution of generative AI presents exciting opportunities but also raises important considerations, particularly regarding its impact on critical thinking. As AI increasingly automates tasks and provides ready-made solutions, it&#8217;s crucial to ensure that human critical thinking skills are not inadvertently eroded. Research suggests that this concern is not unfounded. A <a href="https://doi.org/10.3390/soc15010006" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">recent study published in<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> <a href="https://doi.org/10.3390/soc15010006" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><em>Societies</em><i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>, focusing on AI tools in society, found a <strong>&#8220;significant negative correlation between frequent AI tool usage and critical thinking abilities&#8221;</strong>. The study&#8217;s author, Michael Gerlich, argues that while AI can enhance efficiency and convenience, <strong>&#8220;excessive reliance on these tools can lead to cognitive offloading&#8221;</strong> and a decline in the deep, reflective thinking that is essential for critical thinking.</p>



<p id="ember924">It&#8217;s important to note that Gerlich also highlights that critical thinking is also one of the key skills needed to use generative AI effectively. The ability to assess AI-generated responses and decide on the next steps, such as further prompts to validate or correct the output, is crucial for harnessing the full potential of these tools.</p>



<p id="ember925">Echoing this sentiment, <a href="https://journals.aom.org/doi/10.5465/amle.2024.0338" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">the Academy of Management editorial on Critical Thinking in the Age of Generative AI<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> emphasises the importance of critical thinking as a response to both the opportunities and risks posed by GenAI. They highlight the potential for GenAI to enhance, but also acknowledge the risk of users accepting AI-generated information uncritically.&nbsp; Specifically, the authors point out that GenAI&#8217;s authoritative tone and tendency to present information as objective can lead users to overlook biases and potential inaccuracies, hindering both individual and social critical thinking.</p>



<h2 class="wp-block-heading" id="ember926">Integrating AI into the Enterprise: A Multifaceted Approach</h2>



<p id="ember927">So to successfully integrate generative AI into the enterprise, I believe organisations need a multifaceted approach. This includes investing in training, fostering internal &#8220;champions,&#8221; strategically identifying pain points for improvement, measuring success, and thoughtfully disseminating new ways of working. A critical part of this multifaceted approach involves ensuring that AI augments, rather than replaces, human critical thinking.</p>



<p id="ember928">So as businesses prepare for an era of work powered by Gemini for Workspace here are some areas where businesses might want to adapt to respond to this changing landscape and foster critical thinking in an AI-driven world:</p>



<ul class="wp-block-list">
<li><strong>Prioritise critical thinking skills in recruitment:</strong> Businesses should actively seek candidates who possess strong critical thinking abilities. When hiring, evaluate a candidate&#8217;s ability to analyse information, solve problems, and think critically.</li>



<li><strong>Re-evaluate job profiles:</strong> Update job descriptions to highlight the importance of critical thinking skills, even in positions involving AI tools.</li>



<li><strong>Invest in training and development:</strong> Training programs can equip employees with the skills to leverage AI as a tool to augment their critical thinking, rather than replace it. Workshops and online courses can encourage employees to engage in deep thinking and analytical reasoning.</li>



<li><strong>Promote a culture of critical inquiry:</strong> Foster a workplace culture that values and rewards critical thinking. Create opportunities for employees to share ideas, challenge assumptions, and engage in constructive debate.</li>



<li><strong>Balance AI with human oversight:</strong> Ensure a balance between AI automation and human oversight. Encourage employees to use AI as a tool to support, not supplant, their decision-making processes. This fosters a healthy level of scepticism and critical evaluation of AI outputs, ensuring that AI is used responsibly and ethically.</li>
</ul>



<p id="ember930">By embracing these strategies, businesses can harness the transformational power of generative AI while building a future of work that is both innovative, productive whilst using generative AI in a responsible way.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hawksey.info/blog/2025/01/gemini-for-google-workspace-empowering-enterprise-productivity-while-preserving-critical-thinking/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The Transformative Power of Generative AI: Reimagining the Enterprise with Gemini for Google Workspace</title>
		<link>https://hawksey.info/blog/2024/11/the-transformative-power-of-generative-ai-reimagining-the-enterprise-with-gemini-for-google-workspace/</link>
					<comments>https://hawksey.info/blog/2024/11/the-transformative-power-of-generative-ai-reimagining-the-enterprise-with-gemini-for-google-workspace/?noamp=mobile#comments</comments>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Mon, 25 Nov 2024 21:01:47 +0000</pubDate>
				<category><![CDATA[Google]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21023</guid>

					<description><![CDATA[Sharing some thoughts I've had exploring the transformative potential of Generative AI tools like Gemini for Google Workspace. As part of this (with the help of Gemini as a co-author), I've tried to capture some of my learnings and observations from the last 12 months supporting our customers with their GenAI journeys. 

Some key takeaways talked about include:

* The importance of change management in adopting GenAI.
* Mastering the art of prompting and interaction.
* The need for continuous learning in a rapidly evolving landscape.
* The future of human-AI collaboration.]]></description>
										<content:encoded><![CDATA[
<p id="ember884">This article was co-authored with Gemini for Google Workspace. You can <a href="https://docs.google.com/document/d/1Dix5Mcv1SSq1JoOMcwDcdb31YA14bMMZRzaC5lsICx4/edit?usp=sharing" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">read the full transcript of our conversation<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>.</p>



<h2 class="wp-block-heading" id="ember885">Introduction</h2>



<p id="ember886">Imagine collaborating with an AI to draft a compelling marketing campaign, brainstorming ideas in a fluid conversation, and watching as it generates compelling copy and visuals in real-time. This is the power of generative AI tools like Gemini for Google Workspace, and it&#8217;s transforming how enterprises work.</p>



<p id="ember887">My own journey with generative AI began in late 2023 when I had the opportunity to be part of Google Cloud&#8217;s trusted tester program. Working with early models in MakerSuite, Bard, and Duet AI gave me a glimpse of this transformative power. I was immediately struck by the shift to a conversational paradigm. We&#8217;re no longer just issuing commands to machines; we&#8217;re engaging in dynamic dialogues to create and innovate.</p>



<p id="ember888">Having now supported several businesses with Gemini for Workspace &#8216;proof of value&#8217; pilots, I&#8217;ve come to realize that simply introducing these powerful tools isn&#8217;t enough. To truly unlock the potential of generative AI like Gemini, organizations need a multifaceted approach. This includes investing in training, fostering internal &#8220;champions,&#8221; strategically identifying pain points for improvement, measuring success, and thoughtfully disseminating new ways of working. This is the key to successfully integrating this revolutionary technology into the enterprise.</p>



<h2 class="wp-block-heading" id="ember889">The Promise of GenAI for Enterprise Productivity</h2>



<p id="ember890">McKinsey&#8217;s research paints a compelling picture of generative AI&#8217;s potential to revolutionize productivity. They estimate that <a href="https://www.mckinsey.com/capabilities/mckinsey-digital/our-insights/the-economic-potential-of-generative-ai-the-next-productivity-frontier#introduction" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">generative AI could add the equivalent of $2.6 trillion to $4.4 trillion annually across the 63 use cases they analysed<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>. This staggering figure underscores the transformative impact this technology could have on businesses across various sectors, from automating mundane tasks to unlocking entirely new levels of creativity and efficiency.</p>



<p id="ember891">But the true promise of GenAI extends far beyond simply saving time. Tools like Gemini empower employees to:</p>



<ul class="wp-block-list">
<li><strong>Improve quality:</strong> By providing intelligent suggestions, generating alternative approaches, and catching errors, GenAI helps elevate the overall quality of work.</li>



<li><strong>Upskill and learn:</strong> Gemini not only provides answers but often explains the &#8220;why&#8221; and &#8220;how&#8221; behind them, offering valuable learning opportunities and fostering deeper understanding.</li>



<li><strong>Conduct advanced analysis:</strong> With the ability to analyse vast amounts of data, GenAI unlocks new levels of insight and understanding that were previously impossible.</li>
</ul>



<p id="ember893">Just this week, I was working with a pilot participant from a company&#8217;s People team. They needed to analyse an employee satisfaction survey with hundreds of free-text responses. Imagine the task: categorizing those responses by theme, extracting key quotes, and generating a comprehensive report with recommendations. Gemini was able to analyse all the responses and create a draft report in minutes – a task that would normally take a full day. While the person still needed to check the data and refine the report, having this head start, complete with accurate thematic categorization and relevant quotes, significantly enhanced their efficiency and allowed them to focus on higher-level analysis and recommendations.</p>



<p id="ember894">These benefits highlight the transformative potential of GenAI to not just speed up work, but to fundamentally enhance the way we work and the value we create.</p>



<h2 class="wp-block-heading" id="ember895">The Importance of Change Management</h2>



<p id="ember896">Introducing a powerful tool like Gemini into an organization is more than just adding a new piece of software; it requires a fundamental shift in how people work and think about their roles. This is where change management becomes crucial. The ADKAR model, which focuses on Awareness, Desire, Knowledge, Ability, and Reinforcement, provides a useful framework for navigating this transition.</p>



<ul class="wp-block-list">
<li><strong>Awareness:</strong> First, employees need to be aware of what Gemini is, its capabilities, and how it can impact their work. This goes beyond simply showcasing features; it&#8217;s about communicating the &#8216;why&#8217; behind the change and painting a clear picture of how Gemini can benefit them individually and the organization as a whole.</li>



<li><strong>Desire:</strong> Next, we need to foster a desire to use Gemini. This involves addressing concerns, highlighting the advantages, and creating a sense of excitement about the possibilities. One of the biggest hurdles is overcoming the mindset of &#8216;I need to do this myself.&#8217; Many employees have never had the experience of having an assistant, so it&#8217;s about encouraging them to embrace Gemini as a valuable partner that can augment their capabilities and free them to focus on higher-value tasks. In one of my pilot programs, an employee was hesitant to use Gemini in Gmail because it felt like &#8216;cheating&#8217; to spend less time writing emails. To address this, I explained that Gemini wasn&#8217;t about cutting corners; it was about freeing up time for more valuable activities. By using Gemini to generate a first draft, the employee could then dedicate more time to refining the message, adding personal touches, and ensuring the communication was truly impactful. This reframing helped the employee see the value of GenAI not as a replacement for their skills, but as a tool to enhance them.</li>



<li><strong>Knowledge:</strong> Once the desire is there, employees need the knowledge to use Gemini effectively. This involves providing comprehensive training on the tool&#8217;s functionalities, best practices for prompting, and strategies for integrating it into their workflows. It&#8217;s about equipping them with the skills and understanding to truly leverage Gemini&#8217;s potential.</li>



<li><strong>Ability:</strong> Knowledge is not enough; employees need the ability to apply what they&#8217;ve learned. This requires hands-on practice, opportunities for experimentation, and ongoing support. It&#8217;s about creating a safe environment where people can explore, make mistakes, and learn by doing.</li>



<li><strong>Reinforcement:</strong> Finally, to ensure lasting adoption, reinforcement is key. This involves recognizing and rewarding successful use of Gemini, providing ongoing support and resources, and continuously communicating the benefits and impact of the tool. It&#8217;s about creating a culture where GenAI is seamlessly integrated into the way work gets done.</li>
</ul>



<h3 class="wp-block-heading" id="ember898">Addressing the &#8220;Assistant Mindset&#8221;</h3>



<p id="ember899">A key element of this change management process is helping employees embrace the &#8220;assistant mindset.&#8221; This means moving away from the idea that they need to do everything themselves and towards a collaborative approach where they leverage Gemini as a powerful ally. It&#8217;s about reframing their roles, recognizing that delegating tasks to Gemini can free them to focus on more strategic, creative, and fulfilling aspects of their work.</p>



<h2 class="wp-block-heading" id="ember900">Mastering the Art of Prompting and Interaction</h2>



<p id="ember901">While generative AI tools like Gemini are incredibly powerful, their effectiveness hinges on our ability to communicate our needs and intentions clearly. This goes beyond simply typing in a text prompt; it&#8217;s about mastering the art of interaction and understanding the full range of ways to make the most of Gemini&#8217;s capabilities within Google Workspace.</p>



<h3 class="wp-block-heading" id="ember902">Prompt Engineering: The Basics</h3>



<p id="ember903">Effective prompting is essential for getting the most out of Gemini. Here are a few key principles to keep in mind:</p>



<ul class="wp-block-list">
<li><strong>Be clear and specific:</strong> The more specific your instructions, the better the results. Instead of asking &#8220;write a training plan,&#8221; try &#8220;create a training plan for a new sales onboarding program, including modules on product knowledge, sales techniques, and company values. The plan should be structured for a 3-day program with a mix of presentations, role-playing activities, and online assessments.&#8221;</li>



<li><strong>Provide context:</strong> Give Gemini the information it needs to understand your request. If you want it to summarize a document, provide the document or a link to it.</li>



<li><strong>Experiment and iterate:</strong> Don&#8217;t be afraid to try different prompts and refine your approach based on the results. Prompt engineering is an iterative process.</li>
</ul>



<h3 class="wp-block-heading" id="ember905">Beyond Text Prompts: Unlocking Advanced Capabilities</h3>



<p id="ember906">But mastering Gemini goes beyond just text prompts. It&#8217;s about understanding how to fully utilize its potential within the Workspace environment. Here&#8217;s where things get really interesting:</p>



<ul class="wp-block-list">
<li><strong>The Gemini Side Panel:</strong> This powerful tool allows you to interact with Gemini in more sophisticated ways. You can drag and drop files, incorporate information from multiple sources, and apply Gemini&#8217;s analytical capabilities to generate insights and create new content. For example, I recently worked with a client who was impressed with Google Meet&#8217;s &#8220;take notes for me&#8221; and transcript features but found themselves spending significant time reformatting these into structured meeting minutes. I showed them how to use the Gemini Side Panel to combine three files – the meeting agenda, the Google Meet transcript, and an example of minutes from a previous meeting – and then use a prompt to generate new minutes from the transcript, formatted in the same way as the previous minutes. This saved them a huge amount of time and effort.</li>



<li><strong>Contextual Awareness:</strong> Gemini is designed to understand the context of your work within Workspace. This means it can access and process information from your emails, documents, and other files, allowing for more intelligent and relevant responses.</li>



<li><strong>Multimodal Interaction:</strong> Gemini is not just about text. It can also process images and potentially other forms of media in the future, opening up even more possibilities for creative expression and problem-solving.</li>
</ul>



<p id="ember908">By mastering these advanced interaction techniques, you can unlock the true power of Gemini and transform the way you work.</p>



<h2 class="wp-block-heading" id="ember909">Looking Ahead: The Future of Work with GenAI</h2>



<p id="ember910">As we&#8217;ve seen, generative AI tools like Gemini have the potential to revolutionize the way we work. But the journey has just begun. One of the defining characteristics of this technology is its rapid pace of evolution. New features, capabilities, and ways of interacting with Gemini are emerging constantly. This presents both exciting opportunities and unique challenges for enterprises.</p>



<h3 class="wp-block-heading" id="ember911">The Need for Continuous Learning</h3>



<p id="ember912">In this dynamic environment, continuous learning is no longer a luxury; it&#8217;s a necessity. Employees need to be equipped with the skills and mindset to adapt to new features and functionalities as they become available. Organizations need to foster a culture of continuous learning and provide ongoing support and resources to help their teams stay ahead of the curve.</p>



<p id="ember913">This rapid evolution was evident in one of our recent pilot programs. At the start of the pilot, Gemini&#8217;s ability to analyse quantitative data in the Side Panel within Google Sheets was limited. However, just a few weeks in, Google pushed an update that significantly enhanced these capabilities. This step change opened up a whole new range of possibilities for our pilot participants, but it also highlighted the need for ongoing awareness and education around new features and functionalities.</p>



<h3 class="wp-block-heading" id="ember914">Human-AI Collaboration: A New Era of Work</h3>



<p id="ember915">The future of work with GenAI is not about humans being replaced by machines; it&#8217;s about humans and AI collaborating to achieve more than ever before. This requires a shift in mindset, where we view AI as a partner that can augment our capabilities and free us to focus on higher-value tasks.</p>



<p id="ember916">Imagine a future where:</p>



<ul class="wp-block-list">
<li>Marketing teams use GenAI to brainstorm creative campaigns and generate compelling content.</li>



<li>Sales teams use GenAI to analyse customer data and personalize their outreach.</li>



<li>HR teams use GenAI to streamline recruitment processes and enhance employee engagement.</li>



<li>Engineering teams use GenAI to write and debug code, accelerating development cycles.</li>
</ul>



<p id="ember918">This collaborative future requires us to develop new skills, embrace new ways of working, and cultivate a mindset of continuous learning.</p>



<h3 class="wp-block-heading" id="ember919">Responsible AI: Ethical Considerations</h3>



<p id="ember920">As we integrate GenAI into our workflows, it&#8217;s essential to consider the ethical implications and ensure responsible use of this powerful technology. This includes:</p>



<ul class="wp-block-list">
<li><strong>Data privacy and security:</strong> Protecting sensitive information and ensuring compliance with data protection regulations.</li>



<li><strong>Bias mitigation:</strong> Being aware of potential biases in AI models and taking steps to mitigate their impact.</li>



<li><strong>Transparency and explainability:</strong> Understanding how AI models arrive at their conclusions and ensuring transparency in their use.</li>
</ul>



<p id="ember922">This also extends to establishing clear guidelines and policies around the use of GenAI within the organization. In our pilot programs, we&#8217;ve been actively helping businesses explore these questions. For instance, in one organization, we facilitated a discussion around the feasibility of having a policy where any content or analysis generated with the assistance of Gemini was clearly noted in the document, presentation, or other output. This type of proactive policy-making can foster transparency, build trust, and ensure that GenAI is used ethically and responsibly.</p>



<p id="ember923">By embracing these principles, we can harness the transformative power of GenAI while building a future of work that is both innovative and ethical.</p>



<h2 class="wp-block-heading" id="ember924">Conclusion</h2>



<p id="ember925">The era of generative AI has arrived, and tools like Gemini for Google Workspace are poised to revolutionize the enterprise. But technology alone is not enough. To truly unlock the transformative potential of GenAI, organizations need to invest in change management, foster a culture of continuous learning, and embrace a collaborative approach to human-AI interaction. By doing so, they can empower their employees, enhance productivity, and shape a future of work that is both innovative and ethical.</p>



<p id="ember926">The journey may be challenging, but the rewards are immense. Let&#8217;s embrace this new era of work with open minds, a willingness to learn, and a commitment to responsible AI practices. The future is collaborative, and it&#8217;s powered by generative AI.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hawksey.info/blog/2024/11/the-transformative-power-of-generative-ai-reimagining-the-enterprise-with-gemini-for-google-workspace/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Google Workspace Developer Summit, Berlin 2024 Highlights</title>
		<link>https://hawksey.info/blog/2024/09/google-workspace-developer-summit-berlin-2024-highlights/</link>
					<comments>https://hawksey.info/blog/2024/09/google-workspace-developer-summit-berlin-2024-highlights/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Wed, 18 Sep 2024 20:04:07 +0000</pubDate>
				<category><![CDATA[AppSheet]]></category>
		<category><![CDATA[GDE]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21018</guid>

					<description><![CDATA[A recap of the Google Workspace Developer Summit in Berlin, highlighting key sessions on AppSheet, Apps Script, and AI integrations, with insights on monetization and community engagement. ]]></description>
										<content:encoded><![CDATA[
<p>I recently had the privilege of presenting at the Google Workspace Developer Summit in Berlin. It was my first time representing the new company name Qodea, and I was thrilled to see the brand recognition already established. The summit was a great blend of Google-led sessions and community contributions, showcasing the vibrant energy within the Workspace developer ecosystem.</p>



<h2 class="wp-block-heading">Key Session Highlights</h2>



<p>I was particularly impressed by the following talks:</p>



<ul class="wp-block-list">
<li><strong>Transforming Feedback into Action: Leveraging AppSheet, Forms, and AI for Enhanced Business Insights</strong> by Aurélien Sabaly (CEO, Idun Group): Aurélien demonstrated how to harness the power of AppSheet, Forms, and AI (including the Gemini API) to turn feedback into actionable business insights. This talk was an inspiring example of how Google Workspace tools, AppSheet and a little AI can be used to enhance data-driven decision-making.</li>



<li><strong>Small Steps, Big Impact: Start Simple and Scale Up with Apps Script</strong> by Jay Rost (Lead Engineer, Google Business at Seibert Media GmbH): Jay&#8217;s session offered practical guidance on using Apps Script to boost productivity and streamline workflows within Google Workspace. From custom functions to automation and GCP integration, Jay&#8217;s insights were a goldmine for anyone looking to optimize their Workspace experience.</li>
</ul>



<h2 class="wp-block-heading">Demo Magic</h2>



<p>My Totally Unscripted co-hosts, Kara Ireland and Charles Maxon, delivered an amazing, demo-packed session on the Gemini API and Google Workspace solutions. A standout moment was their Apps Script web app that could generate Card Service code from a hand-drawn wireframe UI – truly impressive!</p>



<h2 class="wp-block-heading">Other Notable Sessions</h2>



<ul class="wp-block-list">
<li>Mike Rhemtulla (Product Manager, Google Chat Platform) shared best practices for designing and building Google Chat apps in his &#8220;Chat Apps 101&#8221; session.</li>



<li>Christian Schalk (AppSheet Product Manager) explored AppSheet AI strategies with Gemini, offering a glimpse into the future of AI-powered Workspace applications.</li>
</ul>



<p><strong>Monetization Tips from the Pros</strong></p>



<p>The summit concluded with a panel discussion featuring Google Workspace Marketplace entrepreneurs Romain Vialard and John McGown. They shared invaluable tips on monetizing add-ons, including strategies for EDU domain installs and navigating the add-on review process.</p>



<h2 class="wp-block-heading">Community Connections</h2>



<p>It was fantastic to connect with so many people at the summit! Thank you to everyone who came by to say hello and mentioned Apps Script Pulse and the GeminiApp Apps Script library. It gets lonely sometimes and people’s support and enthusiasm are really appreciated. Recording might be published at a later date, but in the meantime you can check out&nbsp;<a href="https://docs.google.com/presentation/d/1pcP6X2rJcFijP-zMbacfPfm4xZKr3blvQCv5V4uZAJ0/edit" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">my slides here<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://hawksey.info/blog/2024/09/google-workspace-developer-summit-berlin-2024-highlights/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Automate Google Drive test data creation with Google Apps Script</title>
		<link>https://hawksey.info/blog/2024/07/automate-google-drive-test-data-creation-with-google-apps-script/</link>
					<comments>https://hawksey.info/blog/2024/07/automate-google-drive-test-data-creation-with-google-apps-script/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Wed, 17 Jul 2024 22:04:43 +0000</pubDate>
				<category><![CDATA[GDE]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Drive]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21008</guid>

					<description><![CDATA[This post describes a Google Apps Script function to create a dummy folder structure in Google Drive, including nested folders and files (Documents, Sheets, Slides). 

It highlights some useful features beginners might find useful such as recursion, randomness, and the use of Google Apps Script services for Drive interactions. 

The post also discusses specific challenges encountered, like using Drive.Files.create for file creation and ensuring compatibility with Shared Drives.]]></description>
										<content:encoded><![CDATA[
<p>Working with Google Workspace Enterprise customers we recommend using a DEV/Test Google Workspace domain. If you purchase your Workspace licences through a Google Partner you should be able to get a free test domain, which admins can use to test features like Data Loss Prevention, Context Aware-Access without fear of breaking things for your live domain.</p>



<p>Unfortunately there are no convenient settings or data duplication so configuring your test environment can be a challenge. To help create some dummy data with a little help from Gemini I was able to create the following&nbsp; <code>createDummyFoldersWithNesting()</code> function: &nbsp;</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: gas; title: ; notranslate">
function createDummyFoldersWithNesting() {
  // Get the starting point for the dummy folder structure
  // Replace with your desired folder ID or use &#039;root&#039; to start in the root of your My Drive
  const rootFolder = DriveApp.getFolderById(&quot;YOUR_FOLDER_ID&quot;); 

  // Configuration for the dummy structure
  const maxNestingLevel = 3;        // How many levels deep the structure will go
  const maxFoldersPerLevel = 5;     // Maximum number of folders to create in each level
  const maxFilesPerFolder = 5;      // Maximum number of files to create in each folder
  const fileFolderPrefix = &#039;Dummy&#039;  // Text added to the start of all folders/files

  // ---------------------------- //

  // Array of file types we want to create (Documents, Sheets, Slides)
  const fileTypes = &#x5B;&quot;document&quot;, &quot;spreadsheet&quot;, &quot;presentation&quot;];
  
  // Function to randomly pick a file type from the array
  const randomFileType = () =&gt; fileTypes&#x5B;Math.floor(Math.random() * fileTypes.length)];

  // Recursive function to create nested folders and files
  const createNestedFolders = (parentFolder, currentLevel) =&gt; {
    // Decide how many folders to create in this level
    const numFolders = Math.floor(Math.random() * maxFoldersPerLevel) + 1; // Randomly create 1-5 folders
    console.log(`Creating ${numFolders} folders in ${parentFolder.getName()} (level ${currentLevel})`);

    // Create folders and files within them
    for (let i = 0; i &lt; numFolders; i++) {
      const levelName = `${currentLevel}.${i + 1}`;    // Name for the folder (e.g., &quot;1.2&quot; for 2nd folder in level 1)
      const folder = parentFolder.createFolder(`${fileFolderPrefix} Folder ${levelName}`); // Create the new folder

      // Create files within the new folder
      Array.from({ length: maxFilesPerFolder }, (_, index) =&gt; {   // Create up to 5 files
        const fileType = randomFileType();                     // Pick a random file type
        const fileMetadata = {                                // Prepare information about the new file
          name: `${fileFolderPrefix} ${fileType&#x5B;0].toUpperCase() + fileType.slice(1)} ${levelName}.${index + 1}`,  // File name (e.g., &quot;Dummy Document 1.2.3&quot;)
          mimeType: `application/vnd.google-apps.${fileType}`, // Google Apps Script file type (document, spreadsheet, or presentation)
          parents: &#x5B;folder.getId()]                           // Place the file in the newly created folder
        };
        Drive.Files.create(fileMetadata, undefined, { supportsAllDrives: true }); // Create the file in Google Drive
        console.log(`  Created ${fileType} in folder ID: ${folder.getId()}`);
      });

      // Recursive call: If haven&#039;t reached max nesting level, create more folders in this one
      if (currentLevel &lt; maxNestingLevel) {
        createNestedFolders(folder, currentLevel + 1);
      }
    }
  };

  // Start the process
  console.log(&quot;Starting dummy folder creation...&quot;);
  createNestedFolders(rootFolder, 1);
  console.log(&quot;Finished creating dummy folders!&quot;);
}
</pre></div>


<p>To use the script</p>



<ol class="wp-block-list">
<li>Copy into the Apps Script Editor</li>



<li>Enable the Google Drive Advanced Service</li>



<li>Configure the settings inside the function for the root folder and the number of files/folders to generate</li>
</ol>



<p>Gemini suggested I highlighted the following key points:</p>



<ul class="wp-block-list">
<li>Recursion: The createNestedFolders function calls itself to create folders within folders.</li>



<li>Randomness: The script randomly determines the number of folders and files to create, and the types of files.</li>



<li>Google Apps Script Services: It uses DriveApp and Drive.Files to interact with Google Drive.</li>



<li>File Metadata: When creating files, it uses the mimeType property to specify the Google Apps Script file type.</li>
</ul>



<p>Whilst Gemini wrote a lot of the code for me (with a little guidance), there were a couple of gotchas I’ll highlight.</p>



<p><strong>Drive.Files.create instead of DriveApp.createFile(name, content, mimeType)</strong> &#8211; the current documentation would suggest that you can use the .createFile() method and include a MimeType like GOOGLE_SHEETS, but as <a href="https://stackoverflow.com/q/59959088/1027723" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">explained in this Stackoverflow post<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> Google have said <em>“After extensive consideration, we have determined that DriveApp.createFile() should not be used to create MimeType.GOOGLE_* files.”&nbsp;</em></p>



<p>I could have asked Gemini to rewrite this to use <code>DocumentApp</code>, <code>SpreadsheetApp </code>or <code>SlidesApp .create()</code> methods e.g. <code>SpreadsheetApp.create()</code> but then I would have to move into a folder, use extra scopes, which all felt a bit messy so instead opted for <code>Drive.Files.create</code>.</p>



<p><strong>Drive.Files.create supporting Shared Drives without a blob</strong> &#8211; when using Advanced Services there is a bit of cross referencing required between the auto-complete in the script editor and the associated API documentation. For my script I wanted to support creating files in Shared Drive. To do this requires adding the <code><a href="https://developers.google.com/drive/api/reference/rest/v3/files/create#:~:text=639%2D1%20code).-,supportsAllDrives,-boolean" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">supportsAllDrives<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> </code>as <code>optionalArgs </code>in the <code>Drive.Files.create(resource, mediaData, optionalArgs)</code> method. As I only wanted blank Docs, Sheets and Slides I was scratching my head as to what to include for the <code>mediaData </code>blob. Fortunately this issue was <a href="https://groups.google.com/g/google-apps-script-community/c/VpvWOjTjI7k/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">discussed in the Google Apps Script Community &#8211; Google Group<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> and it was clear I could use null or undefined.&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hawksey.info/blog/2024/07/automate-google-drive-test-data-creation-with-google-apps-script/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Upload and download files from Google Cloud Storage with Google Apps Script without using a service account</title>
		<link>https://hawksey.info/blog/2024/02/upload-and-download-files-from-google-cloud-storage-with-google-apps-script-without-using-a-service-account/</link>
		
		<dc:creator><![CDATA[Martin Hawksey]]></dc:creator>
		<pubDate>Thu, 15 Feb 2024 08:29:00 +0000</pubDate>
				<category><![CDATA[GDE]]></category>
		<category><![CDATA[Google Apps Script]]></category>
		<guid isPermaLink="false">https://hawksey.info/?p=21063</guid>

					<description><![CDATA[A key feature of Google Apps Script is its integration into Google Cloud. The default behaviour when any Apps Script project is created is that an associated Google Cloud project is created and configured. This default project is not accessible to the user and for most scripts, the user doesn’t need to worry about any [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>A key feature of Google Apps Script is its integration into Google Cloud. The default behaviour when any Apps Script project is created is that an associated Google Cloud project is created and configured. This <a href="https://developers.google.com/apps-script/guides/cloud-platform-projects" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">default project<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> is not accessible to the user and for most scripts, the user doesn’t need to worry about any of the configurations such as enabling APIs and configuring authentication settings.</p>



<p>Other key aspects are identity and authentication. The default behaviour for scripts is usually to run as the account executing the script, Apps Script automatically determining what authorisation is required for different Google services based on an automatic scan of your code or from what <a href="https://developers.google.com/apps-script/concepts/scopes#setting_explicit_scopes" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">scopes have been set explicitly<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> in the Apps Script manifest file.</p>



<p>The last piece in the puzzle is the <a href="https://developers.google.com/apps-script/reference/script/script-app#getOAuthToken()" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><code>.getOAuthToken()</code><i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> method which is part of the ScriptApp Service:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Gets the OAuth 2.0 access token for the effective user. … The token returned by this method only includes scopes that the script currently needs. Scopes that were previously authorized but are no longer used by the script are not included in the returned token. If additional OAuth scopes are needed beyond what the script itself requires, they can be specified in the script’s manifest file.</p>
</blockquote>



<p>What this means is in script projects we can borrow an access token to use other services that the effective user has access to and have been declared in the script project scopes. For example, if my Google account <a href="mailto:martin@example.com">martin@example.com</a> has been added to another Google Cloud project with the Google Cloud Storage service enabled, I can use Apps Script to generate a token to use the Cloud Storage service in that project.</p>



<p>To help illustrate this, here are two examples for interacting with Google Cloud Storage buckets to upload and download files to Google Drive.</p>



<h2 class="wp-block-heading"><strong>Download Google Cloud Storage Bucket resources to Google Drive</strong></h2>



<p>Assuming you have already set up a Cloud Storage Bucket, the first step is to grant permission to the account you will be running your Google Apps Script code. In the steps below we are adding a principal to a bucket-level policy with read-only access. Other <a href="https://cloud.google.com/storage/docs/access-control/iam" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Identity and Access Management Configurations<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> are possible.</p>



<ol class="wp-block-list">
<li>In the Google Cloud console, go to the Cloud Storage <strong>Buckets</strong> page.<br><a href="https://console.cloud.google.com/storage/browser" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Go to Buckets<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a></li>



<li>In the list of buckets, click the name of the bucket for which you want to grant a principal a role.</li>



<li>Select the <strong>Permissions</strong> tab near the top of the page.</li>



<li>Click the <strong>Grant access</strong> button.<br>The <em>Add principals</em> dialog box appears.</li>



<li>In the <strong>New principals</strong> field, enter one or more identities that need access to your bucket.</li>



<li>Select a role (or roles) from the <strong>Select a role</strong> drop-down menu select the <strong>Storage Object Viewer</strong> role</li>



<li>Click <strong>Save</strong>.</li>
</ol>



<p>To be able to access the Cloud Storage Bucket we need to declare the required scope in the Apps Script project by following these steps (or <a href="https://script.google.com/home/projects/17PDAtgUpz4eNAOqjtE_nADny83vzf6_RAYG9PhNOpJ98tCCooVZGUvZO" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Make a Copy of this script project<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>):</p>



<ol class="wp-block-list">
<li>Create a <a href="https://script.new/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">new Script Project<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a></li>



<li>Open the script project in the Apps Script editor.</li>



<li>Click <strong>Project Settings</strong>.</li>



<li>Select the <strong>Show “appsscript.json” manifest file in editor</strong> checkbox.</li>
</ol>



<p>The manifest file appears as a project file named <code>appsscript.json</code>. Open this file in the Script Editor and add the <code>oauthScopes</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: gas; title: ; notranslate">
&quot;https://www.googleapis.com/auth/script.external_request&quot;,
&quot;https://www.googleapis.com/auth/devstorage.read_only&quot;,
&quot;https://www.googleapis.com/auth/drive&quot;
</pre></div>


<p>An example <code>appsscript.json</code> with these scopes is included below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: gas; title: ; notranslate">
{
  &quot;timeZone&quot;: &quot;Europe/London&quot;,
  &quot;dependencies&quot;: {},
  &quot;exceptionLogging&quot;: &quot;STACKDRIVER&quot;,
  &quot;runtimeVersion&quot;: &quot;V8&quot;,
  &quot;oauthScopes&quot;: &#x5B;
    &quot;https://www.googleapis.com/auth/script.external_request&quot;,
    &quot;https://www.googleapis.com/auth/devstorage.read_only&quot;,
    &quot;https://www.googleapis.com/auth/drive&quot;
  ]
}
</pre></div>


<p>In your <code>Code.gs</code> file add the following code:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: gas; title: ; notranslate">
// Example usage
function getFile() {
  const bucketName = &#039;my-bucket&#039;;
  const fileName = &#039;path/to/my/file.txt&#039;;

  const blob = getBucketFile_(bucketName, fileName);

  if (blob) {
    const file = DriveApp.createFile(blob);
    console.log(file.getUrl());
  }
}


/**
 * Retrieves a file from a Google Cloud Storage bucket as a Blob.
 *
 * @param {string} BUCKET_NAME - The name of the bucket containing the file.
 * @param {string} OBJECT_NAME - The name of the file to retrieve.
 * @return {Blob} The retrieved file as a Blob object.
 *
 * @example
 * const fileBlob = getBucketFile_(&#039;my-bucket&#039;, &#039;path/to/my/file.txt&#039;);
 */
function getBucketFile_(BUCKET_NAME, OBJECT_NAME) {
  // Base URL for Cloud Storage API
  const url = `https://storage.googleapis.com/storage/v1/b/${BUCKET_NAME}/o/${encodeURIComponent(OBJECT_NAME)}?alt=media`;
  try {
    const response = UrlFetchApp.fetch(url, {
      method: &#039;GET&#039;,
      headers: {
        &quot;Authorization&quot;: &quot;Bearer &quot; + ScriptApp.getOAuthToken()
      }
    });
    return response.getBlob();
  } catch (error) {
    console.error(&#039;Error getting file:&#039;, error);
  }
}
</pre></div>


<ol class="wp-block-list">
<li>In the Script Editor replace the <code>bucketName</code> and <code>fileName</code> with the bucket and object details that you want to access.</li>



<li>Click <strong>Save</strong>.</li>



<li>Run the <code>getFile()</code> function</li>
</ol>



<p>When the script is run the execution log will reference the Google File file link:</p>



<p>Press enter or click to view image in full size</p>



<p><img decoding="async" alt="" src="blob:https://hawksey.info/6d952cde-5856-47c9-b063-5286cc72bb6c"><br>Example execution log</p>



<h2 class="wp-block-heading"><strong>Upload a Google Drive file to a Google Cloud Storage Bucket</strong></h2>



<p>Again assuming you have already set up a Cloud Storage Bucket, the first step is to grant permission to the account you will be running your Google Apps Script code to write to the bucket. In the steps below we are adding a principal to a bucket-level policy with write-only access. Other <a href="https://cloud.google.com/storage/docs/access-control/iam" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Identity and Access Management Configurations<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a> are possible.</p>



<ol class="wp-block-list">
<li>In the Google Cloud console, go to the Cloud Storage <strong>Buckets</strong> page.<br><a href="https://console.cloud.google.com/storage/browser" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Go to Buckets<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a></li>



<li>In the list of buckets, click the name of the bucket for which you want to grant a principal a role.</li>



<li>Select the <strong>Permissions</strong> tab near the top of the page.</li>



<li>Click the <strong>Grant access</strong> button.<br>The <em>Add principals</em> dialog box appears.</li>



<li>In the <strong>New principals</strong> field, enter one or more identities that need access to your bucket.</li>



<li>Select a role (or roles) from the <strong>Select a role</strong> drop-down menu select the <strong>Storage Object Creator</strong> role (this allows users to create objects, but does not give permission to view, delete, or replace objects).</li>



<li>Click <strong>Save</strong>.</li>
</ol>



<p>To be able to access the Cloud Storage Bucket we need to declare the required scope in the Apps Script project by following these steps (or <a href="https://script.google.com/home/projects/1F-XiJDVIvjh_6PU-l68PiHfVkB7tUtYJWabxGRbdApGfAGnNc1bbKRUM" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Make a Copy of this script project<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>):</p>



<ol class="wp-block-list">
<li>Create a <a href="https://script.new/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">new Script Project<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a></li>



<li>Open the script project in the Apps Script editor.</li>



<li>Click <strong>Project Settings</strong>.</li>



<li>Select the <strong>Show “appsscript.json” manifest file in editor</strong> checkbox.</li>
</ol>



<p>The manifest file appears as a project file named <code>appsscript.json</code>. Open this file in the Script Editor and add the <code>oauthScopes</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: gas; title: ; notranslate">
&quot;https://www.googleapis.com/auth/script.external_request&quot;,
&quot;https://www.googleapis.com/auth/devstorage.read_write&quot;,
&quot;https://www.googleapis.com/auth/drive.readonly&quot;
</pre></div>


<p>An example <code>appsscript.json</code> with these scopes is included below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: gas; title: ; notranslate">
{
  &quot;timeZone&quot;: &quot;Europe/London&quot;,
  &quot;dependencies&quot;: {},
  &quot;exceptionLogging&quot;: &quot;STACKDRIVER&quot;,
  &quot;runtimeVersion&quot;: &quot;V8&quot;,
  &quot;oauthScopes&quot;: &#x5B;
    &quot;https://www.googleapis.com/auth/script.external_request&quot;,
    &quot;https://www.googleapis.com/auth/devstorage.read_write&quot;,
    &quot;https://www.googleapis.com/auth/drive.readonly&quot;
  ]
}
</pre></div>


<p>In your <code>Code.gs</code> file add the following code:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: gas; title: ; notranslate">
function addFile() {
  const bucketName = &#039;my-bucket&#039;;
  const fileName = &#039;path/to/my/file.txt&#039;;
 
  const driveBlob = DriveApp.getFileById(&#039;YOUR_DRIVE_FILE_ID&#039;).getBlob();

  const resource = addBucketFile_(driveBlob, bucketName, fileName);

  if (resource) {
    console.log(resource);
  }
}

/**
 * Adds a Blob to a Google Cloud Storage bucket.
 *
 * @param {Blob} BLOB - The Blob of the file to add to the bucket.
 * @param {string} BUCKET_NAME - The name of the bucket containing to add the file to.
 * @param {string} OBJECT_NAME - The name/path of the file to add.
 * @return {Object} objects#resource
 *
 * @example
 * const fileBlob = addBucketFile_(driveBlob, &#039;my-bucket&#039;, &#039;path/to/my/file.txt&#039;);
 */
function addBucketFile_(BLOB, BUCKET_NAME, OBJECT_NAME) {
  const bytes = BLOB.getBytes();
 
  // Base URL for Cloud Storage API
  const url = `https://www.googleapis.com/upload/storage/v1/b/${BUCKET_NAME}/o?uploadType=media&amp;name=${encodeURIComponent(OBJECT_NAME)}`;
  try {
    const response = UrlFetchApp.fetch(url, {
      method: &#039;POST&#039;,
      contentLength: bytes.length,
      contentType: BLOB.getContentType(),
      payload: bytes,
      headers: {
        &quot;Authorization&quot;: &quot;Bearer &quot; + ScriptApp.getOAuthToken()
      }
    });
    return JSON.parse(response.getContentText());
  } catch (error) {
    console.error(&#039;Error getting file:&#039;, error);
  }
}
</pre></div>


<ol class="wp-block-list">
<li>In the Script Editor replace the <code>bucketName</code>, <code>fileName</code> and <code>YOUR_DRIVE_FILE_ID</code> with the bucket, object filename and path and the Drive file ID you want to upload.</li>



<li>Click <strong>Save</strong>.</li>



<li>Run the <code>addFile()</code> function</li>
</ol>



<p><strong>Note:</strong> The above sample only deals with single Google Drive files. If you are looking for a solution to upload an entire Google Drive folder, which also handles conversion of Google document formats into Microsoft equivalents, here is a related post from Stéphane Giron on <a href="https://medium.com/@stephane.giron/automatically-backup-google-drive-folders-to-cloud-storage-469a47e0f5dc" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Automatically backup Google Drive folders to Cloud Storage<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>.</p>



<h2 class="wp-block-heading"><strong>Summary</strong></h2>



<p>The strategy of using Apps Script access tokens is great for internal process solutions, allowing the use of a specific account for data read/write operations. In addition, this method is not exclusive to Google Cloud Storage but extends to other Google APIs manageable through Google Cloud IAM permissions. To help in identifying the appropriate scopes to include in the Apps Script manifest file, refer to the provided link for <a href="https://developers.google.com/identity/protocols/oauth2/scopes" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">OAuth 2.0 Scopes for Google APIs<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>.</p>



<p>For other situations, for example Google Workspace Marketplace Add-ons, where the identity of the account can’t be granted access to your storage bucket, creating and using a service account is required. If this is your situation Amit Agarwal has shared this post on <a href="https://www.labnol.org/code/20074-upload-files-to-google-cloud-storage" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Upload Files from Google Drive to Google Cloud Storage with Google Apps Script<i class="wpel-icon dashicons-before dashicons-external" aria-hidden="true"></i></a>, which uses a service account.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
