# @kentcdodds/google ## Intent Account-aware Google product helpers for Kent's Kody workflows. Centralizes explicit account selection (`personal`, `business`, `youtube-brand`, `youtube-plus`), OAuth integration routing, shared API error handling, and dry-run guards for Gmail, Calendar, Drive, People, YouTube, and YouTube Analytics. Use `cal-com` for Cal.com booking pages and lifecycle—not this package. ## What it does - Read or mutate Gmail, Google Calendar, Drive, and People with the correct Google account - Reply to Gmail with `createReplyDraft` (quotes original + threading headers) - Call YouTube Data / Analytics on Kent's `main` (`youtube-brand`) or `plus` (`youtube-plus`) channel, including `uploadVideo` / `updateVideo` - Resolve which account alias to use when a task mentions personal Gmail, Workspace calendar, or a specific YouTube channel - `listEventsAcrossCalendars` returns within a 20 second budget (60 second cap) and sets `truncated` when it stops early, instead of paging every calendar until the caller times out ## Prerequisites / setup Connect OAuth integrations at `/connect/oauth` (tokens are managed by Kody—not raw access-token secrets): | Account alias | OAuth integration | Typical use | |---------------|-------------------|-------------| | `personal` | `google` | Personal Gmail, Drive, default YouTube reads | | `business` | `google-business` | Workspace Calendar and Gmail (`me@kentcdodds.com`) | | `youtube-brand` | `google-youtube-brand` | Main Kent C. Dodds YouTube channel | | `youtube-plus` | `google-youtube-plus` | kentcdodds-plus / BEPE channel | Every API call requires an explicit `account` param. Use `dryRun: true` before Gmail sends or Calendar mutations. Agents: see `AGENTS.md` for import paths and smoke checks. ## Gmail self-send trap (read this) Replying to a message **you already sent** is the common footgun. Gmail's From is you; a naive "Reply-To else From" default puts **To: you**, and Kent emails himself. `createReplyDraft` detects own-outbound mail (From is this mailbox) and defaults `To` to the original recipient(s) instead. Omit `to` unless you truly need an override. Composed `createDraft` / `sendMessage` **refuse** when `to` is only the mailbox unless you pass `allowSelfSend: true`. `createReplyDraft` closes the quoting gap that raw `createDraft` leaves open: pass the message id being replied to plus the reply text, and it derives the recipient, subject, `In-Reply-To`, `References`, `threadId`, and the quoted original from the fetched message. Replies go out as `multipart/related` wrapping `multipart/alternative` (same shape mail clients produce). Pass `cc` / `bcc` when needed — they are not inferred. Pass `dryRun: true` to preview the assembled MIME without creating anything. Do not set `to` to Kent's own address on a reply to his outbound mail — that is the self-send trap. Kent publishes to two YouTube channels: **`main`** (`youtube-brand`, Better with Kent) and **`plus`** (`youtube-plus`, BEPE / legacy Chats with Kent). Resolve the channel before upload or analytics work. ## Gmail draft Unicode / BCC (agents: read AGENTS.md) Do **not** add Bcc (or rewrite a draft) by `atob` → edit → `btoa` on Gmail `message.raw`. Bare `atob` is Latin-1-per-byte and corrupts UTF-8 en-dashes from clients like Mimestream. Use `updateDraftHeaders` from `kody:@kentcdodds/google/gmail` for header-only changes, or the UTF-8-safe Base64 helpers (`decodeUtf8Base64` / `encodeUtf8Base64`) when the body must change. Details and snippets: `AGENTS.md`. ## Done when - Needed OAuth integrations are connected at `/connect/oauth` - An explicit `account` is passed on every call - Gmail / Calendar mutations are previewed with `dryRun: true` before live use - Replies to Kent's own outbound mail do not To-only-self without `allowSelfSend: true`