$npx -y skills add opendatahub-io/ai-helpers --skill email-meeting-summaryUse when the user wants to summarize a Google Meet meeting and send the summary by email. Reviews a Google Meet transcript for a specific meeting topic, then composes a Gmail draft summarizing decisions and action items for that topic. Prompts for meeting selection if not specifi
| 1 | # Email Meeting Summary |
| 2 | |
| 3 | Read a Google Meet transcript, identify discussion topics, summarize decisions |
| 4 | and action items for the chosen topic, and compose a Gmail draft for review. |
| 5 | |
| 6 | ## Prerequisites |
| 7 | |
| 8 | - `gws` binary must be on `$PATH` |
| 9 | - Authenticated: run `gws auth login` if not already logged in. The `--readonly` flag is sufficient for reading calendar/docs/drive, but draft creation requires the `gmail.compose` scope which is included in the default (non-readonly) login. |
| 10 | |
| 11 | If `gws` is not installed or authentication fails, tell the user to follow the |
| 12 | setup instructions in the `google-workspace` skill. |
| 13 | |
| 14 | Helper scripts are located in `${CLAUDE_SKILL_DIR}` and require Python 3.10+. |
| 15 | |
| 16 | --- |
| 17 | |
| 18 | ## Step 1: Identify the Meeting |
| 19 | |
| 20 | Run the search once and save the result to a temp file: |
| 21 | |
| 22 | ```bash |
| 23 | EVENT_FILE=$(mktemp /tmp/meeting_event.XXXXXX) |
| 24 | |
| 25 | # With a keyword (argument provided): |
| 26 | python3 "${CLAUDE_SKILL_DIR}/scripts/find_meeting.py" --days 7 "<keyword>" > "$EVENT_FILE" |
| 27 | |
| 28 | # With keyword + specific date (recurring meeting): |
| 29 | python3 "${CLAUDE_SKILL_DIR}/scripts/find_meeting.py" --days 7 --date "<YYYY-MM-DD>" "<keyword>" > "$EVENT_FILE" |
| 30 | |
| 31 | # No argument — list all recent events: |
| 32 | python3 "${CLAUDE_SKILL_DIR}/scripts/find_meeting.py" --days 7 > "$EVENT_FILE" |
| 33 | ``` |
| 34 | |
| 35 | The script always outputs JSON. Read `EVENT_FILE` and display the result(s) to |
| 36 | the user as a human-readable list. |
| 37 | |
| 38 | The script searches the past 7 days (up to now). When a keyword matches |
| 39 | multiple occurrences of a recurring meeting, it automatically picks the best |
| 40 | one: the occurrence on `--date` if given, otherwise today's, otherwise the most |
| 41 | recent past one. |
| 42 | |
| 43 | **Always confirm with the user** before proceeding, regardless of how many |
| 44 | results were found. Use `AskUserQuestion`: |
| 45 | |
| 46 | > "I found: **<title>** on <date> at <time>. Is this the meeting you want to |
| 47 | > summarize? (yes / no — if no, describe the meeting you meant)" |
| 48 | |
| 49 | If the user says no, ask for clarification and re-run `find_meeting.py` with a |
| 50 | corrected keyword or `--date`, overwriting `EVENT_FILE`. If multiple events were |
| 51 | returned, list them and ask the user to pick one by number, then re-run with |
| 52 | `--date` to narrow to that occurrence. |
| 53 | |
| 54 | --- |
| 55 | |
| 56 | ## Step 2: Find the Transcript in Google Drive |
| 57 | |
| 58 | Pass the event JSON to `find_transcript.py` on stdin: |
| 59 | |
| 60 | ```bash |
| 61 | python3 "${CLAUDE_SKILL_DIR}/scripts/find_transcript.py" < "$EVENT_FILE" |
| 62 | ``` |
| 63 | |
| 64 | The script returns JSON with a `source` field: |
| 65 | |
| 66 | | `source` | Meaning | What to use | |
| 67 | |---|---|---| |
| 68 | | `"attachment"` | Found in event attachments | `fileId` field | |
| 69 | | `"drive"` | Found via Drive search | pick from `files` array | |
| 70 | | `"none"` | Not found anywhere | inform user and stop | |
| 71 | |
| 72 | **If `source` is `"none"`**: tell the user the transcript is not yet available |
| 73 | (Gemini may take several minutes after the meeting ends) and stop. |
| 74 | |
| 75 | **If `source` is `"drive"` and `files` has more than one entry**: present a |
| 76 | numbered list (name, created date, link) and use `AskUserQuestion` to ask which |
| 77 | file to use. |
| 78 | |
| 79 | **If exactly one result**: proceed automatically. |
| 80 | |
| 81 | Store the chosen document ID as `DOC_ID`. |
| 82 | |
| 83 | --- |
| 84 | |
| 85 | ## Step 3: Read the Transcript |
| 86 | |
| 87 | ```bash |
| 88 | python3 "${CLAUDE_SKILL_DIR}/scripts/read_doc.py" "<DOC_ID>" |
| 89 | ``` |
| 90 | |
| 91 | The script outputs the document as plain text. Store this as `TRANSCRIPT`. If |
| 92 | the script exits with an error or the output is empty, inform the user and stop. |
| 93 | |
| 94 | --- |
| 95 | |
| 96 | ## Step 4: Identify Topics and Let the User Choose |
| 97 | |
| 98 | Analyze `TRANSCRIPT` to identify 3–8 distinct discussion topics or agenda |
| 99 | items. For each topic, write a one-sentence description of what was discussed. |
| 100 | |
| 101 | Present the topics as a numbered list, for example: |
| 102 | |
| 103 | ```text |
| 104 | 1. Sprint planning — The team aligned on story point allocations for the |
| 105 | upcoming two-week sprint. |
| 106 | 2. CI pipeline failures — Discussed root cause of the nightly test failures |
| 107 | and assigned investigation owners. |
| 108 | 3. Q3 roadmap review — Reviewed progress against Q3 milestones and flagged |
| 109 | three items at risk. |
| 110 | ``` |
| 111 | |
| 112 | Use `AskUserQuestion`: |
| 113 | |
| 114 | > "Which topic would you like to summarize for the team email? Enter the number." |
| 115 | |
| 116 | --- |
| 117 | |
| 118 | ## Step 5: Generate the Summary and Present for Review |
| 119 | |
| 120 | For the selected topic, extract from `TRANSCRIPT`: |
| 121 | |
| 122 | **Key decisions** — concrete choices or conclusions reached (bullet list). |
| 123 | **Action items** — tasks assigned, including owner name and due date where |
| 124 | mentioned (bullet list; format each as `[Own |