Google Workspace
Drive, Docs, Sheets, Calendar, Gmail in Tools verwenden.
Die Google-Dienste sind die häufigsten Integrationen. Einmal verbunden, decken sie einen Großteil der „Office-Automatisierung" ab.
Verbinden
/manage/o-auth-connections → Provider Google → verbinden. Beim ersten Mal vergibst du die Scopes, die du brauchst:
| Scope | Für |
|---|---|
drive.file |
Dateien verwalten, die die App erstellt hat |
drive.readonly |
Alle Dateien lesen |
drive |
Voller Drive-Zugriff |
documents |
Google Docs lesen/schreiben |
spreadsheets |
Google Sheets lesen/schreiben |
calendar |
Kalender-Events |
gmail.readonly |
E-Mails lesen |
gmail.send |
E-Mails versenden |
Faustregel: so wenig Scopes wie möglich. Wenn dein Use-Case „Reports ablegen" ist, reicht drive.file — die App sieht nur Dateien, die sie selbst erstellt hat.
Beispiel: Datei in Drive ablegen
API in apis.php:
'google_drive' => [
'base_url' => 'https://www.googleapis.com/drive/v3/',
'headers' => ['Accept' => 'application/json'],
],
Tool:
'tools' => [
'uploadReportToDrive' => [
'description' => 'Report als Google Doc in Ordner "Reports" ablegen.',
'parameters' => [
'type' => 'object',
'properties' => [
'title' => ['type' => 'string'],
'content' => ['type' => 'string'],
],
'required' => ['title', 'content'],
],
'handler' => function (array $results, array $args, array $ctx): array {
$file = $ctx->http->post('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', [
'headers' => ['Content-Type' => 'multipart/related'],
'body' => buildMultipartBody($args['title'], $args['content']),
], ['api' => 'google_drive']);
return [
'id' => $file['id'],
'url' => "https://docs.google.com/document/d/{$file['id']}",
];
},
],
];
Sheets als „Datenbank"
Google Sheets ist ein beliebter Kompromiss zwischen „richtige Datenbank" und „Excel-Datei in Drive".
'tools' => [
'appendToSheet' => [
'description' => 'Eine Zeile zu einem Google Sheet hinzufügen.',
'parameters' => [
'type' => 'object',
'properties' => [
'sheetId' => ['type' => 'string'],
'row' => ['type' => 'array', 'items' => ['type' => 'string']],
],
'required' => ['sheetId', 'row'],
],
'api' => 'google_sheets',
'method' => 'POST',
'path' => '/{sheetId}/values/A1:append?valueInputOption=USER_ENTERED',
'body' => ['values' => '{row}'],
],
];
Gmail-Read
'tools' => [
'listRecentMails' => [
'description' => 'Letzte 10 E-Mails im Posteingang auflisten.',
'parameters' => ['type' => 'object', 'properties' => []],
'api' => 'gmail',
'method' => 'GET',
'path' => '/users/me/messages?maxResults=10',
],
'getMail' => [
'description' => 'Inhalt einer E-Mail per ID holen.',
'parameters' => [
'type' => 'object',
'properties' => ['id' => ['type' => 'string']],
'required' => ['id'],
],
'api' => 'gmail',
'method' => 'GET',
'path' => '/users/me/messages/{id}',
],
];
Daraus kannst du dann einen Assistant „Posteingang-Assistent" bauen, der jeden Morgen neue Mails triagiert.
Calendar
Calendar-APIs haben große Response-Bodies — Mapping einsetzen, um nur relevante Felder rauszuziehen:
'listEvents' => [
// ...
'api' => 'google_calendar',
'method' => 'GET',
'path' => '/calendars/primary/events?timeMin={from}&timeMax={to}',
'mapping' => [
'items' => [
'id' => 'id',
'title' => 'summary',
'start' => 'start.dateTime',
'end' => 'end.dateTime',
'attendees' => 'attendees[].email',
],
],
];
Rate-Limits
Google hat pro-User-Limits (100 req/100s typisch). Bei Scheduled Tasks, die viele Calls machen:
- Request-Batching nutzen, wo Google es anbietet
intervalauf10minoder länger setzen- Bei Fehlern
429in deinem Handler mit Backoff behandeln
Debug
tm logs # volle API-Responses bei Problemen
tm test-tool listRecentMails # direkte Reproduktion
Wenn Google plötzlich 401 zurückgibt, obwohl die Verbindung gestern noch lief: der Benutzer hat wahrscheinlich das App-Passwort widerrufen oder Scopes geändert. /manage/o-auth-connections → neu verbinden.