协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
lindy-sdk-patterns【开发与工程】Lindy integration patterns for webhook handling, HTTP actions, and Run Code. Use when building integrations, calling Lindy agents from code, or implementing the Run Code action with Python/JavaScript. Trigger with phrases like "lindy integration patterns", "lindy best practices", "lindy webhook patterns", "lindy Run Code", "lindy HTTP Request".
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: lindy-sdk-patterns description: 'Lindy integration patterns for webhook handling, HTTP actions, and Run Code.
Use when building integrations, calling Lindy agents from code,
or implementing the Run Code action with Python/JavaScript.
Trigger with phrases like "lindy integration patterns", "lindy best practices",
"lindy webhook patterns", "lindy Run Code", "lindy HTTP Request".
' allowed-tools: Read, Write, Edit version: 1.20.0 license: MIT author: Jeremy Longshore jeremy@intentsolutions.io tags:
Use Lindy's documented integration primitives: Webhook Received for inbound calls, HTTP Request for outbound calls, Run Code for bounded transformations, and Send POST Request to Callback for the documented callback workflow. This is not an SDK guide: Lindy's current public documentation does not provide the package, client, agent CRUD, streaming, API key, or general API-host surface that older copies of this skill claimed.
public.lindy.ai webhook URL.callbackUrl and Send POST Request to
Callback, but does not document a Lindy callback signature. Treat callback content
as untrusted unless the receiving application establishes its own authenticated
boundary; never invent or claim a Lindy signing header.text output.This is a small application wrapper around the documented webhook, not a Lindy SDK:
type Intake = { event: 'document.ready'; documentRef: string };
async function triggerLindyWebhook(input: {
webhookUrl: string;
webhookSecret: string;
payload: Intake;
}): Promise<number> {
const url = new URL(input.webhookUrl);
if (
url.protocol !== 'https:' ||
url.hostname !== 'public.lindy.ai' ||
!url.pathname.startsWith('/api/v1/webhooks/') ||
url.username ||
url.password
) {
throw new Error('Refusing an unrecognized Lindy webhook URL');
}
if (!input.webhookSecret.trim()) throw new Error('Webhook secret is empty');
if (!/^doc_[a-z0-9_-]{1,64}$/i.test(input.payload.documentRef)) {
throw new Error('Invalid document reference');
}
const response = await fetch(url, {
method: 'POST',
redirect: 'error',
headers: {
Authorization: `Bearer ${input.webhookSecret}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(input.payload),
});
if (!response.ok) throw new Error(`Webhook rejected with status ${response.status}`);
return response.status;
}
Do not blindly retry an ambiguous response: the public webhook documentation does not promise an idempotency key. Check Tasks and the application's operation record before a controlled retry.
Lindy documents Python/JavaScript variables as strings and exposes result, text,
and stderr to later steps. Parse, validate, bound, and return only the minimum data:
import json
data = json.loads(raw_items)
if not isinstance(data, list) or len(data) > 100:
raise ValueError("raw_items must be a list with at most 100 entries")
allowed = []
for item in data:
if not isinstance(item, dict) or set(item) != {"reference", "score"}:
raise ValueError("unexpected item schema")
reference = item["reference"]
score = item["score"]
if not isinstance(reference, str) or len(reference) > 64:
raise ValueError("invalid reference")
if not isinstance(score, (int, float)) or not 0 <= score <= 1:
raise ValueError("invalid score")
if score >= 0.5:
allowed.append({"reference": reference, "score": score})
return {"count": len(allowed), "items": allowed}
Avoid printing input data: printed content becomes text. Prefer HTTP Request for
network calls so URL, authentication, response status, and error branches remain
visible in the workflow. Do not rely on an undocumented runtime, sandbox vendor,
startup time, timeout value, or library version; check the current Run Code page.
Include a fixed application-owned callbackUrl only when two-way processing is
needed, then add Send POST Request to Callback as documented. The receiver should
accept a minimal result schema and stage the result for validation/approval. A
callback alone must not authorize payments, deletion, access changes, or external
communications.
Verify one valid call and negative cases for a missing/wrong bearer secret, wrong host, extra/oversized input, outbound 4xx/5xx response, malformed Run Code input, and untrusted callback content. The Test Panel executes real actions, so use synthetic data, test integrations, and confirmation for side effects.
| Failure | Fail-closed response |
|---|---|
| Webhook returns 401 | Stop; confirm the Lindy-generated secret without printing it |
| Webhook outcome is ambiguous | Inspect Tasks/operation record before a manual retry |
| Outbound URL is dynamic or non-HTTPS | Refuse and replace it with an allowlisted endpoint |
| HTTP response is rejected or malformed | Route to an error branch; do not consume partial data |
| Run Code input violates schema | Raise an error and inspect only metadata in Tasks |
| Callback is unauthenticated/untrusted | Quarantine for validation; perform no side effect |
Return an integration contract containing:
For a document workflow, the application sends only
{"event":"document.ready","documentRef":"doc_sample_001"} to the exact generated
webhook URL with its generated bearer secret. Lindy transforms the reference, calls a
fixed application endpoint with that endpoint's separate credential, and returns a
minimal status callback. Raw document text, user identity, and either secret never
enter the payload, prompt, task title, Run Code output, or logs.
Use lindy-security-basics to review the resulting credential, connection, approval,
data, and monitoring boundaries before activating the workflow.