On this page

How to Integrate OpenClaw with Google Workspace (Drive, Docs, Sheets, Slides)

Google Workspace is where your work lives — Docs with meeting notes, Sheets with data, Slides for pitches, Drive folders organizing everything. OpenClaw + Workspace lets your AI agent create, read, and update all of these, turning meeting transcripts into formatted docs, raw data into analyzed sheets, and strategy briefs into presentation decks.

This guide covers Drive, Docs, Sheets, and Slides integration. By the end you’ll have three high-value workflows running: meeting notes → Doc, CSV → Sheet analysis, and strategy brief → Slides presentation.

Why Workspace Integration Matters

Knowledge workers spend 2–3 hours/day on document work — creating docs from templates, copying data between sheets, formatting presentations, hunting for files in Drive. At ~750 hours/year and $50/hr that’s $37,500 in document overhead. What OpenClaw can do once connected:

  • “Summarize this transcript and create a Doc” — formatted meeting notes in seconds
  • “Analyze this CSV and create a sheet with insights” — data cleaned, analyzed, visualized
  • “Turn this strategy brief into a 10-slide deck” — presentation ready to review
  • “Find all docs mentioning Project Phoenix” — instant search across Drive
  • “Share this folder with [email protected]” — permissions managed

Service Account vs OAuth: The Big Decision

OAuth (user authorization)

The user grants your app permission to access their Google account, and the app acts on behalf of that user. Simple for single-user apps, user controls permissions, no admin required — but each user must authorize individually, tokens expire and need refresh, and you can’t access files the user doesn’t own. Best for personal OpenClaw installs.

Service Account (server-to-server)

Create a “robot” account that’s not a human user, grant it access to files/folders, and your app authenticates as that account. No user authorization flow, credentials don’t expire, and it can access anything shared with it. Requires more setup, and for Workspace domains needs domain-wide delegation (admin approval). Best for multi-user deployments and team/company use.

? Note:For this guide we’ll use OAuth (simpler for most users). Service account setup is covered at the end for Workspace admins.

Step 1: Enable Google Workspace APIs

Visit console.cloud.google.com and use the same project as Calendar (if you followed that guide). Enable all four APIs from APIs & Services → Library:

  • Google Drive API — file management
  • Google Docs API — create/edit documents
  • Google Sheets API — spreadsheets
  • Google Slides API — presentations

Create OAuth credentials

  1. 1.APIs & Services → Credentials → Create Credentials → OAuth client ID
  2. 2.Application type: Desktop app
  3. 3.Name: OpenClaw Workspace Client
  4. 4.Click Create and copy Client ID and Client Secret

Required OAuth scopes (auto-requested when generating the auth URL):

https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/documents
https://www.googleapis.com/auth/spreadsheets
https://www.googleapis.com/auth/presentations

Step 2: Configure OpenClaw

Add credentials to .env:

# Google Workspace Configuration
GOOGLE_WORKSPACE_ENABLED=true
GOOGLE_CLIENT_ID=abc123...apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xyz789...
GOOGLE_REDIRECT_URI=http://localhost:3000/auth/google/workspace/callback

Install the official client: npm install googleapis. Then create skills/google-workspace.js:

const { google } = require('googleapis');
const fs = require('fs');
const path = require('path');

class GoogleWorkspaceSkill {
  constructor(config) {
    this.config = config;
    this.oauth2Client = null;
    this.drive = null;
    this.docs = null;
    this.sheets = null;
    this.slides = null;
  }

  async initialize() {
    this.oauth2Client = new google.auth.OAuth2(
      this.config.clientId,
      this.config.clientSecret,
      this.config.redirectUri
    );
    const tokenPath = path.join(__dirname, '../.workspace-tokens.json');
    if (fs.existsSync(tokenPath)) {
      const tokens = JSON.parse(fs.readFileSync(tokenPath, 'utf8'));
      this.oauth2Client.setCredentials(tokens);
    }
    this.drive = google.drive({ version: 'v3', auth: this.oauth2Client });
    this.docs = google.docs({ version: 'v1', auth: this.oauth2Client });
    this.sheets = google.sheets({ version: 'v4', auth: this.oauth2Client });
    this.slides = google.slides({ version: 'v1', auth: this.oauth2Client });
  }

  getAuthUrl() {
    return this.oauth2Client.generateAuthUrl({
      access_type: 'offline',
      scope: [
        'https://www.googleapis.com/auth/drive',
        'https://www.googleapis.com/auth/documents',
        'https://www.googleapis.com/auth/spreadsheets',
        'https://www.googleapis.com/auth/presentations',
      ],
    });
  }

  async getTokensFromCode(code) {
    const { tokens } = await this.oauth2Client.getToken(code);
    this.oauth2Client.setCredentials(tokens);
    fs.writeFileSync(
      path.join(__dirname, '../.workspace-tokens.json'),
      JSON.stringify(tokens)
    );
    return tokens;
  }

  async searchFiles(query, type = null) {
    let q = `name contains '${query}'`;
    if (type) {
      const mimeTypes = {
        doc: 'application/vnd.google-apps.document',
        sheet: 'application/vnd.google-apps.spreadsheet',
        slide: 'application/vnd.google-apps.presentation',
        folder: 'application/vnd.google-apps.folder',
      };
      q += ` and mimeType='${mimeTypes[type]}'`;
    }
    const response = await this.drive.files.list({
      q,
      fields: 'files(id, name, mimeType, webViewLink)',
      pageSize: 10,
    });
    return response.data.files;
  }

  async createDoc(title, content) {
    const doc = await this.docs.documents.create({ requestBody: { title } });
    if (content) {
      await this.docs.documents.batchUpdate({
        documentId: doc.data.documentId,
        requestBody: {
          requests: [{ insertText: { text: content, location: { index: 1 } } }],
        },
      });
    }
    return doc.data;
  }

  async createSheet(title, data = []) {
    const sheet = await this.sheets.spreadsheets.create({
      requestBody: { properties: { title }, sheets: [{ properties: { title: 'Sheet1' } }] },
    });
    if (data.length > 0) {
      await this.sheets.spreadsheets.values.update({
        spreadsheetId: sheet.data.spreadsheetId,
        range: 'Sheet1!A1',
        valueInputOption: 'RAW',
        requestBody: { values: data },
      });
    }
    return sheet.data;
  }

  async createPresentation(title) {
    const p = await this.slides.presentations.create({ requestBody: { title } });
    return p.data;
  }

  async shareFile(fileId, email, role = 'reader') {
    await this.drive.permissions.create({
      fileId,
      requestBody: { type: 'user', role, emailAddress: email },
    });
  }
}

module.exports = GoogleWorkspaceSkill;

Step 3: First-Time Authorization

Run the authorization flow (same as Calendar if you’ve done it before):

node -e "
const WorkspaceSkill = require('./skills/google-workspace');
const skill = new WorkspaceSkill({
  clientId: process.env.GOOGLE_CLIENT_ID,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET,
  redirectUri: process.env.GOOGLE_REDIRECT_URI,
});
skill.initialize().then(() => {
  console.log('Visit this URL:');
  console.log(skill.getAuthUrl());
});
"

Visit the URL, authorize, paste the code back into the CLI, and tokens land in .workspace-tokens.json.

Workflow 1: Meeting Notes → Google Doc

Automatically convert meeting transcripts into formatted documents:

  1. 1.Meeting ends (via calendar integration)
  2. 2.Get the meeting transcript (from recording or real-time transcription)
  3. 3.Summarize key points with OpenClaw
  4. 4.Format as professional meeting notes
  5. 5.Create a Google Doc and share with attendees
class MeetingNotesWorkflow {
  constructor(workspace, calendar) {
    this.workspace = workspace;
    this.calendar = calendar;
  }

  async processMeeting(meetingId) {
    const meeting = await this.calendar.getEvent(meetingId);
    const transcript = await this.getTranscript(meeting.hangoutLink);
    const summary = await this.summarizeTranscript(transcript);
    const notes = this.formatMeetingNotes(meeting, summary);

    const doc = await this.workspace.createDoc(
      `Meeting Notes: ${meeting.summary}`,
      notes
    );

    for (const attendee of meeting.attendees) {
      await this.workspace.shareFile(doc.documentId, attendee.email, 'writer');
    }
    return doc;
  }

  formatMeetingNotes(meeting, summary) {
    const date = new Date(meeting.start.dateTime);
    return `Meeting Notes: ${meeting.summary}

Date: ${date.toLocaleDateString()}
Attendees: ${meeting.attendees.map(a => a.email).join(', ')}

Key Discussion Points:
${summary.keyPoints.map(p => '• ' + p).join('n')}

Decisions Made:
${summary.decisions.map(d => '• ' + d).join('n')}

Action Items:
${summary.actionItems.map(i => '• ' + i.task + ' (Owner: ' + i.owner + ', Due: ' + i.due + ')').join('n')}

---
Generated by OpenClaw`;
  }
}

Workflow 2: CSV → Analyzed Google Sheet

Transform raw CSV data into cleaned, analyzed spreadsheets — parse, dedupe, normalize, then add a Summary & Insights tab with AI-generated patterns and recommendations.

class CSVAnalysisWorkflow {
  constructor(workspace) { this.workspace = workspace; }

  async processCSV(csvPath) {
    const data = await this.parseCSV(csvPath);
    const cleaned = await this.cleanData(data);
    const analysis = await this.analyzeData(cleaned);
    return await this.createAnalysisSheet(cleaned, analysis);
  }

  async cleanData(data) {
    const unique = [...new Map(data.map(r => [JSON.stringify(r), r])).values()];
    return unique.map(row => {
      Object.keys(row).forEach(k => {
        if (typeof row[k] === 'string') row[k] = row[k].trim();
        if (!isNaN(row[k]) && row[k] !== '') row[k] = parseFloat(row[k]);
      });
      return row;
    });
  }

  async createAnalysisSheet(data, analysis) {
    const headers = Object.keys(data[0]);
    const rows = data.map(r => headers.map(h => r[h]));
    const sheet = await this.workspace.createSheet(
      `Analysis: ${new Date().toLocaleDateString()}`,
      [headers, ...rows]
    );
    await this.addSummarySheet(sheet.spreadsheetId, this.createSummary(data, analysis));
    return sheet;
  }

  createSummary(data, analysis) {
    return [
      ['Dataset Summary'], [],
      ['Total Rows:', data.length],
      ['Columns:', Object.keys(data[0]).length], [],
      ['Key Insights:'],
      ...analysis.insights.map(i => [i]), [],
      ['Recommendations:'],
      ...analysis.recommendations.map(r => [r]),
    ];
  }
}

Workflow 3: Strategy Brief → Google Slides

Convert text strategy briefs into presentation decks. Parse the brief into sections (problem, solution, market…), let OpenClaw generate a 10-slide structure with title + 3–5 bullets per slide, then create the deck:

class BriefToSlidesWorkflow {
  constructor(workspace) { this.workspace = workspace; }

  async processBrief(briefText) {
    const sections = await this.parseBrief(briefText);
    const structure = await this.generateSlides(sections);
    return await this.createPresentation(structure);
  }

  async parseBrief(text) {
    const sections = {};
    let current = null;
    for (const line of text.split('n')) {
      if (line.startsWith('##')) {
        current = line.replace('##', '').trim();
        sections[current] = [];
      } else if (current && line.trim()) {
        sections[current].push(line);
      }
    }
    return sections;
  }

  async createPresentation(structure) {
    const presentation = await this.workspace.createPresentation(structure.title);
    const presentationId = presentation.presentationId;

    for (let i = 0; i < structure.slides.length; i++) {
      const slide = structure.slides[i];
      await this.workspace.slides.presentations.batchUpdate({
        presentationId,
        requestBody: {
          requests: [
            { createSlide: { objectId: `slide_${i}`, slideLayoutReference: { predefinedLayout: 'TITLE_AND_BODY' } } },
            { insertText: { objectId: `slide_${i}_title`, text: slide.title } },
            { insertText: { objectId: `slide_${i}_body`, text: slide.points.join('n') } },
          ],
        },
      });
    }
    return presentation;
  }
}

Domain-Wide Delegation (For Workspace Admins)

If you’re a Workspace admin and want OpenClaw to access all users’ files (team calendar automation, company-wide doc search, automated reporting, HR/IT automation), use domain-wide delegation.

  1. 1.Cloud Console → IAM & Admin → Service Accounts → Create Service Account → download JSON key
  2. 2.On the service account, enable G Suite Domain-wide Delegation and note the Client ID
  3. 3.admin.google.com → Security → API Controls → Domain-wide Delegation → Add new with that Client ID and the required scopes
  4. 4.Use the service account in code with subject impersonation
const { google } = require('googleapis');

const auth = new google.auth.GoogleAuth({
  keyFile: 'path/to/service-account-key.json',
  scopes: ['https://www.googleapis.com/auth/drive'],
  subject: '[email protected]', // user to impersonate
});

const drive = google.drive({ version: 'v3', auth });
? Note:Service accounts with domain-wide delegation are powerful — protect the key file.

Common Workspace Integration Issues

“Insufficient permissions” error

Missing OAuth scope. Add the scope to your auth URL and re-authorize.

“File not found” error

Service account doesn’t have access. Share the file with the service account email, or use OAuth so it acts as the user.

Token expired errors

Access token expired and refresh isn’t kicking in. googleapis handles this automatically when an offline refresh token is stored — make sure you requested access_type: 'offline'.

Rate limit errors

Too many API calls. Implement exponential backoff:

async function retryWithBackoff(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try { return await fn(); }
    catch (e) {
      if (e.code === 429 && i < maxRetries - 1) {
        await sleep(Math.pow(2, i) * 1000);
      } else { throw e; }
    }
  }
}

The PaioClaw Alternative

Setup time so far: 90–120 minutes (OAuth, three workflows, testing) — plus ongoing maintenance for API changes, workflow refinement, and error handling edge cases.

PaioClaw includes full Workspace integration: one-click OAuth via the UI, pre-built workflows (meeting notes, CSV analysis, brief→slides), natural language file operations, and cross-app automation (calendar→drive→docs→sheets). Total time: ~5 minutes. Starts FREE, Smart $15/month, Genius $25/month.

  • DIY when you need custom document logic, highly specific workflows, or want to learn Google APIs
  • PaioClaw when you want standard workflows working immediately, especially for multi-user or team deployments

The Bottom Line

Workspace integration turns OpenClaw into a document automation powerhouse. Meeting notes write themselves, CSV data self-analyzes, and strategy briefs become presentations. The three workflows here (notes→Doc, CSV→Sheet, brief→Slides) save hours per week for knowledge workers.

OAuth setup is straightforward, service accounts add power for admin use cases, and the APIs are well-documented and stable. DIY gives you full control. PaioClaw gives you the same workflows with zero setup.

Join Our Community

Connect with other PaioClaw users, share tips, and stay up to date.