Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🎙️ Meet → Linear Automation

A Google Apps Script add-on that automatically transforms Google Meet transcripts (generated by Gemini) into Linear issues, with a manager approval step before any issue is created.


How it works

Google Meet ends
      ↓
Gemini generates meeting notes → saved to Google Drive
      ↓
Apps Script finds the transcript
      ↓
Gemini (via Requesty) extracts action items as structured JSON
      ↓
Manager receives an approval email with one button per issue
      ↓
Manager approves individual issues (or all at once)
      ↓
Issues are created in Linear via GraphQL API

Features

  • Automatic trigger — polls Google Calendar every 5 minutes to detect ended Meet sessions
  • Smart transcript detection — searches Drive for Gemini-generated notes matching today's date and meeting title, with up to 3 retries (covers overruns and Google's processing delay)
  • Selective activation — only processes meetings where a specific email address is present among the participants
  • AI extraction — uses Gemini via Requesty to extract title, description, assignee, priority, and due date for each action item
  • Granular approval — the manager can approve issues one by one, approve all at once, or cancel everything
  • Automatic assignee resolution — cross-references Calendar participants with Linear workspace members by email, then passes the mapping to Gemini so each action item gets assigned to the correct Linear user ID automatically. Matching works by full name, first name, or email address

Project structure

├── Config.gs         # API keys and global constants
├── Trigger.gs        # Calendar polling, transcript search, retry logic
├── AIProcessor.gs    # Gemini prompt and JSON extraction via Requesty
├── Approval.gs       # Approval email with per-issue buttons
├── LinearAPI.gs      # Linear GraphQL mutation and doGet web app handler
└── appsscript.json   # Manifest with scopes and add-on config

Prerequisites

  • A Google Workspace account
  • A Requesty account and API key
  • A Linear account with API access
  • Google Meet with Gemini notes enabled (notes must be saved to Drive)

Setup

1. Create the Apps Script project

  1. Go to script.google.com and create a new project
  2. Create the following files: Config.gs, Trigger.gs, AIProcessor.gs, Approval.gs, LinearAPI.gs
  3. Copy the code from this repository into each file

2. Configure the manifest

In the Apps Script editor, go to Project Settings (⚙️) → Show appsscript.json, then replace its content with:

{
  "timeZone": "Europe/Rome",
  "dependencies": {
    "enabledAdvancedServices": [
      { "userSymbol": "Drive", "version": "v3", "serviceId": "drive" },
      { "userSymbol": "Gmail", "version": "v1", "serviceId": "gmail" },
      { "userSymbol": "Calendar", "version": "v3", "serviceId": "calendar" }
    ]
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/drive.readonly",
    "https://www.googleapis.com/auth/gmail.send",
    "https://www.googleapis.com/auth/calendar.readonly",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/script.scriptapp"
  ],
  "addOns": {
    "common": {
      "name": "Meet → Linear Automation",
      "logoUrl": "https://www.gstatic.com/images/branding/product/1x/apps_script_48dp.png"
    }
  },
  "webapp": {
    "executeAs": "USER_DEPLOYING",
    "access": "DOMAIN"
  }
}

3. Add script properties

Go to Project Settings (⚙️) → Script properties and add the following keys:

Key Description
REQUESTY_API_KEY Your Requesty API key
REQUESTY_MODEL Model to use via Requesty (e.g. google/gemini-2.0-flash). Falls back to google/gemini-2.0-flash if not set
LINEAR_API_KEY Your Linear personal API key (lin_api_...)
TEAM_ID Your Linear team ID (see below)
MANAGER_EMAIL Email address that will receive approval requests
TRIGGER_EMAIL The meeting participant whose presence activates the flow

How to get your Linear Team ID

Run this query against the Linear API (e.g. with curl or any GraphQL client):

curl -X POST https://api.linear.app/graphql \
  -H "Authorization: YOUR_LINEAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"{ teams { nodes { id name } } }"}'

Copy the id of your team and save it as TEAM_ID.

4. Deploy as a Web App

The approval email links rely on a web app endpoint (doGet):

  1. Click Deploy → New Deployment
  2. Select type: Web App
  3. Execute as: Me
  4. Who has access: Anyone with a Google Account (or limit to your domain)
  5. Click Deploy and copy the web app URL

⚠️ Every time you modify the code, you must create a new version under Deploy → Manage Deployments for changes to take effect.

5. Activate the trigger

Run setupTrigger() once from the Apps Script editor. This installs a time-based trigger that polls Calendar every 5 minutes. You can verify it is active under Triggers (⏰) in the left sidebar.


Usage

Once set up, the flow runs automatically:

  1. A Google Meet ends with TRIGGER_EMAIL among the participants
  2. Gemini generates the meeting notes and saves them to Drive
  3. After ~10 minutes (to allow for overruns and processing delay), the script finds the transcript
  4. An approval email is sent to MANAGER_EMAIL
  5. The manager clicks Approve next to each issue they want to create, or Approve all
  6. Issues appear in Linear instantly

Testing

You can test the full flow manually without waiting for a meeting to end:

function testFullFlow() {
  const today = Utilities.formatDate(new Date(), "Europe/Rome", "yyyy/MM/dd");
  const files = DriveApp.searchFiles('title contains "Gemini"');

  while (files.hasNext()) {
    const file = files.next();
    const name = file.getName();

    if (name.includes(today)) {
      const url = "https://www.googleapis.com/drive/v3/files/" + file.getId() + "/export?mimeType=text/plain";
      const res = UrlFetchApp.fetch(url, {
        headers: { "Authorization": "Bearer " + ScriptApp.getOAuthToken() }
      });
      const transcript = res.getContentText();
      console.log("✅ Transcript found:", name);

      const items = extractActionItems(transcript);
      console.log("📋 Extracted items:", JSON.stringify(items, null, 2));

      sendApprovalEmail(items, MANAGER_EMAIL, name);
      console.log("📧 Email sent to:", MANAGER_EMAIL);
      return;
    }
  }
  console.log("❌ No Gemini notes found for today");
}

Priority mapping

Gemini output Linear priority
urgent 1 — Urgent
high 2 — High
medium 3 — Medium
low 4 — Low

Limitations

  • Approval links expire after 1 hour (configurable via CacheService TTL)
  • The script retries transcript detection up to 3 times (10 min + 5 min + 5 min = up to 20 minutes after meeting end)
  • Gemini notes must be saved to the same Google Drive account running the script
  • The trigger activates only for events where TRIGGER_EMAIL is among the participants — no Meet link check is performed since Google Calendar does not always populate the location field
  • Assignee matching uses three keys per user: full name, first name, and email — so Gemini can resolve mentions to the same Linear user ID

License

MIT

About

Google Apps Script add-on that turns Google Meet transcripts (Gemini notes) into Linear issues — with AI-powered action item extraction via Requesty, automatic assignee resolution from calendar participants, and a per-issue manager approval flow over email.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages