Eigene REST-API anbinden
Wie du Dienste einbindest, die kein OAuth brauchen — klassische API-Keys.
Nicht jeder Dienst, an den du andocken willst, hat OAuth. Viele APIs identifizieren sich einfach per API-Key, Bearer-Token oder Basic Auth im Header.
In apis.php eintragen
<?php
return [
'apis' => [
'shop_api' => [
'base_url' => 'https://shop.example.com/api/v2/',
'headers' => [
'Authorization' => 'Bearer sk_live_abc123…',
'Accept' => 'application/json',
],
],
'weather' => [
'base_url' => 'https://api.openweathermap.org/data/2.5/',
'_auth' => 'appid=abc123…',
],
],
];
Zwei typische Muster:
headers: Auth als HTTP-Header (Bearer-Token, Basic Auth, Custom Header)_auth: Auth als Query-String — wird automatisch an jede URL angehängt
Credentials behandeln
API-Keys stehen direkt in apis.php:
'Authorization' => 'Bearer sk_live_abc123',
apis.phpist sensitiv. Sie enthält Secrets, die deinen Workspace mit echten Diensten verbinden. Halte die Datei aus öffentlichen Repos heraus. Nutze ein privates Git-Repo für deinen Workspace, oder schließeapis.phpper.gitignoreaus, wenn das Repo öffentlich ist.Bei Key-Rotation: Wert in
apis.phpersetzen,tm sync, fertig.
Tool definieren
'tools' => [
'getRecentOrders' => [
'description' => 'Letzte 5 Bestellungen aus dem Shop laden.',
'parameters' => [
'type' => 'object',
'properties' => [
'since' => [
'type' => 'string',
'description' => 'Datum YYYY-MM-DD oder "today"',
],
],
'required' => ['since'],
],
'api' => 'shop_api',
'method' => 'GET',
'path' => 'orders?limit=5&since={since}',
'mapping' => [
'orders' => [
'id' => 'id',
'customer' => 'customer.name',
'total' => 'total',
'status' => 'status',
],
],
],
];
POST-Requests mit Body
'createOrder' => [
'description' => 'Neue Bestellung anlegen.',
'parameters' => [
'type' => 'object',
'properties' => [
'customerId' => ['type' => 'integer'],
'items' => [
'type' => 'array',
'items' => [
'type' => 'object',
'properties' => [
'sku' => ['type' => 'string'],
'qty' => ['type' => 'integer'],
],
],
],
],
'required' => ['customerId', 'items'],
],
'api' => 'shop_api',
'method' => 'POST',
'path' => 'orders',
'body' => [
'customer_id' => '{customerId}',
'line_items' => '{items}',
],
'mapping' => [
'id' => 'id',
'orderNumber' => 'number',
'url' => 'admin_url',
],
];
Basic Auth
'old_api' => [
'base_url' => 'https://old.example.com/api/',
'headers' => [
'Authorization' => 'Basic ' . base64_encode('user:passwort'),
],
],
Custom Header
Manche APIs wollen eigene Header — typisch für B2B-Systeme:
'internal_crm' => [
'base_url' => 'https://crm.firma.intern/api/',
'headers' => [
'x-app-id' => 'TaskMonkey',
'x-app-version' => '1.0',
'x-api-key' => 'abc123…',
],
],
Response-Mapping
APIs geben oft deutlich mehr zurück, als du brauchst. mapping pickt die interessanten Felder raus:
'mapping' => [
'total' => 'amounts.gross_total',
'customerName' => 'billing.first_name',
'line' => 'line_items[0].name', // erstes Array-Element
'items' => 'line_items', // ganzes Array behalten
],
Ohne mapping bekommt das Modell den kompletten Response-JSON. Bei großen Responses frisst das Tokens und bringt selten Mehrwert.
Pre-/Postprocess für Spezialfälle
Wenn du den Request vor dem Absenden anpassen musst (z. B. Signatur berechnen, Datum formatieren):
'preprocess' => function (array $args, array $ctx): array {
$args['date'] = (new \DateTime($args['date']))->format('Y-m-d');
return $args;
},
Debug
# Request + Response live ansehen
tm test-tool getRecentOrders since=today
# Logs mit vollem HTTP-Dump
tm logs --lines 200
Wenn ein externer Dienst 500 zurückgibt, liegt es meistens nicht an TaskMonkey, sondern am Dienst. tm logs zeigt die rohe Response — das kannst du in der Regel direkt an den Betreiber dieses Dienstes weiterreichen.