Runtime-Umgebung
Orbitype verfügt über eine gemeinsame Runtime-Umgebung, auf die Agenten über ihre Tools zugreifen können, Workflows über ihre Nodes, Artefakte über ihre Server Actions sowie Orbitype Intelligence im interaktiven Ausführungsmodus.
TABLE_OF_CONTENTS
Orbitype Environment Injections
Orbi-Objekt
Workflow-Funktionen haben Zugriff auf ein injiziertes orbi-Objekt. Es repräsentiert den aktuellen Projekt-Kontext und ermöglicht dir einen konsistenten Zugriff auf Projekt-Metadaten, Connectors und konfigurierte Credentials.
async ({ orbi }) => {
const { id, name } = orbi.project
return { projectId: id, projectName: name }
}Connectors
orbi.project.connectors listet alle Connectors im aktuellen Projekt (z.B. SQL, S3). Das ist hilfreich, um verfügbare Integrationen zu entdecken und Connector-IDs bei Bedarf zu referenzieren.
async ({ orbi }) => {
const connectors = orbi.project.connectors.map(c => ({
id: c.id,
name: c.name,
implementation: c.implementation
}))
return { connectors }
}Credentials
orbi.project.credentials enthält konfigurierte Credential-Einträge für das aktuelle Projekt. Das ist der empfohlene Weg, um Credential-Values zu beziehen.
async ({ orbi, linkedin }) => {
const accountId = orbi.project.credentials
.find(x => x.name === 'linkedin')?.value
if (!accountId) {
throw new Error('Missing credential: linkedin')
}
const self = await linkedin.connect(accountId)
return { providerId: self.provider_id }
}API Keys
orbi.project.apiKeys enthält API-Key-Metadaten für das aktuelle Projekt. API-Keys sind Secrets: nicht loggen und in produktiven Workflows nicht als Output zurückgeben.
async ({ orbi }) => {
const keys = orbi.project.apiKeys.map(k => ({
name: k.name,
connectorId: k.connectorId
}))
return { apiKeys: keys }
}Leads-Datenbank
Nutze die Leads-Datenbank, um passende Personen zu finden und sie bei Bedarf mit Kontaktdaten anzureichern. Das Verhalten ist in Assistant-Tools und im Workflow-Code identisch.
Was möglich ist
- Suchmodus: liefert Profil-/Firmen-/Kontextfelder (ohne direkte Kontaktfreigabe).
- Enrich-Modus: liefert ausgewählte Kontaktfelder für bestimmte Leads.
- Paginierung: unterstützt page/perPage und cursor-basierte Paginierung.
- Idempotenz: unterstützt
excludeIds, um bereits verarbeitete Leads zu überspringen. - Credit-bewusst: Kosten hängen vom Modus und den gewählten Enrich-Feldern ab.
Eingabemodell
Gemeinsame Eingaben:
{
mode?: "search" | "enrich", // Standard: "search"
confirmed?: boolean, // true nach expliziter Freigabe bei hohem Enrich-Preis
page?: number, // Standard: 1
perPage?: number, // max: 100
cursor?: string, // Keyset-Paginierungs-Cursor
ids?: string[], // meist für Enrich-Modus
excludeIds?: string[], // bereits verarbeitete Leads auslassen
fields?: string[] // nur für Enrich
}Typische Filter (alle optional):
{
query?: string | string[],
keywords?: string[],
excludeKeywords?: string[],
industries?: string[],
jobTitles?: string[],
companyNames?: string[],
locations?: string[],
locationCountries?: string[],
skills?: string[],
interests?: string[],
countries?: string[],
minYearsExperience?: number,
maxYearsExperience?: number,
minLinkedinConnections?: number,
hasCompanyWebsite?: boolean,
hasLinkedinUrl?: boolean
}Query-Verhalten
query: "revops"trifft auf Datensätze zu, bei denen ein durchsuchbares Feld den Begriff enthält.query: ["revops", "berlin"]nutzt AND zwischen den Begriffen; jeder Begriff wird über mehrere Felder gematcht.
Antworten in Search vs. Enrich
Search-Ausgabe (Beispiel):
{
data: [
{
id, fullName, firstName, lastName,
industry, jobTitle, subRole,
companyName, companyIndustry, companyWebsite, companySize,
location, locationCountry,
yearsExperience, linkedinConnections,
skills, countries, interests
}
],
hasMore, nextPage, cursor, nextCursor,
enrichment: {
count,
fields,
selectedFieldCostCredits,
estimatedCostCredits,
pricing,
filters
}
}Enrich-Ausgabe (Beispiel):
{
data: [
{
id,
email,
emailAddresses,
mobileNumbers,
phoneNumbers,
linkedinUrl,
facebookUrl,
twitterUrl,
githubUrl
}
],
rows,
fields,
selectedFieldCostCredits,
costCredits,
hasMore,
nextPage,
cursor,
nextCursor
}Verwendung im Workflow-Wrapper
async ({ leads }) => {
const page1 = await leads.search({
mode: "search",
query: ["revops", "outbound"],
locations: ["Berlin"],
perPage: 50,
excludeIds: ["already-processed-id"]
})
return {
rows: page1.data,
nextCursor: page1.nextCursor,
credits: leads.getCredits()
}
}async ({ leads }) => {
const enriched = await leads.search({
mode: "enrich",
confirmed: true,
ids: ["lead-id-1", "lead-id-2"],
fields: ["email", "linkedinUrl"]
})
return {
rows: enriched.data,
cost: enriched.costCredits,
credits: leads.getCredits()
}
}async ({ leads }) => {
const batch = await leads.searchMany(
{
mode: "search",
query: "b2b saas",
excludeIds: ["already-processed-id"]
},
{ maxRows: 150 }
)
return {
count: batch.count,
rows: batch.data,
limited: batch.limited,
cost: batch.costCredits
}
}Empfohlener Ablauf
- Mit engen Filtern und kleinem
perPagestarten (10-25). - Relevanz anhand der Ergebnisse prüfen.
perPageerst erhöhen, wenn die Trefferqualität passt.- Enrich nur für den wirklich benötigten Teil verwenden.
- Verarbeitete IDs speichern und bei Retries immer über
excludeIdsübergeben. - Wenn eine Kostenbestätigung nötig ist: erst Freigabe einholen, dann mit
confirmed: trueerneut ausführen.
Apollo Integration
Apollo Integration in Orbitype
Diese Dokumentation beschreibt alle verfuegbaren Apollo Actions in Orbitype.
Sie erklaert was jede Action macht, welche Parameter erwartet werden, und enthaelt ein vollstaendiges Beispiel, das jede Apollo Action in einem logischen Ablauf verwendet.
Alle Apollo Funktionen sind ueber das Objekt apollo in der Orbitype Code-Umgebung verfuegbar.
Voraussetzungen
Ein Credential mit dem Namen
apolloexistiert im ProjektDer Code laeuft in einer Orbitype Funktion oder einem Agent
Vor jeder weiteren Action muss Apollo verbunden werden
Grundmuster
Jeder Apollo Workflow folgt in der Regel dieser Reihenfolge:
Apollo verbinden
Personen suchen (raw oder normalisiert)
Leads anreichern und Credits pruefen
Minimaler Setup:
async ({ orbi, apollo }) => {
const credential = orbi.project.credentials.find(x => x.name === "apollo")
if (!credential?.value) throw new Error("missing [apollo] credential")
apollo.connect(credential.value)
}
Ohne connect() schlagen alle Request-Methoden fehl.
Verbindung
apollo.connect(accessToken)
Beschreibung
Verbindet Apollo mit einem Bearer Access Token.
Diese Methode muss immer zuerst aufgerufen werden.
Parameter
accessToken(string, required)
Apollo Access Token aus dem Credential-Wert
Rueckgabe
{
connected: true
}
Suche
apollo.search(params)
Beschreibung
Raw Personensuche ueber den Apollo mixed_people API Endpoint.
Parameter
params(object, optional)
Raw Apollo Query-Parameter (z.B.q_keywords,page,per_page)
Rueckgabe
objectraw Apollo Response (enthaelt typischerweisetotal_entriesundpeople)
apollo.searchLeads(params)
Beschreibung
Normalisierte Suchantwort mit stabilen Lead-Feldern.
Parameter
params(object, optional)
Gleiche Query-Form wie beisearch()
Rueckgabe
{
totalEntries: number,
leads: [
{
id: string,
fullName: string,
title: string,
linkedinUrl: string,
hasEmail: boolean,
companyName: string
}
]
}
Enrichment
apollo.enrichPerson(params)
Beschreibung
Raw Enrichment-Call auf den Apollo people/match Endpoint.
Parameter
params(object, optional)
Apollo Enrichment-Parameter (z.B.id,linkedin_url,reveal_personal_emails)
Rueckgabe
objectraw Enrichment-Response (typischerweise mitpersonundrequest_id)
apollo.enrichById(personId, options)
Beschreibung
Reichert eine Person ueber die Apollo Person-ID an.
Parameter
personId(string, required)
Apollo Person-IDoptions(object, optional)
Zusaetzliche Enrichment-Parameter
Rueckgabe
{
person: object | undefined,
request_id: number | undefined
}
apollo.enrichByLinkedinUrl(linkedinUrl, options)
Beschreibung
Reichert eine Person ueber die LinkedIn URL an.
Parameter
linkedinUrl(string, required)
Vollstaendige LinkedIn URLoptions(object, optional)
Zusaetzliche Enrichment-Parameter
Rueckgabe
{
person: object | undefined,
request_id: number | undefined
}
Kombinierter Workflow-Helper
apollo.searchAndEnrich(input)
Beschreibung
Sucht Leads per Keywords und reichert einen Teil der Ergebnisse per ID an.
Parameter
input(object, required)query(string, required): Suchbegriffpage(number, optional, default 1)perPage(number, optional, default 10)maxEnrich(number, optional, default 3, clamped to 0..25)
Rueckgabe
{
search: {
totalEntries: number,
leads: ApolloLead[]
},
enriched: ApolloPerson[],
errors: [
{
personId: string,
message: string
}
]
}
Credits
apollo.getCredits()
Beschreibung
Gibt die in dieser Apollo Integration Instanz verbrauchten Credit-Einheiten zurueck.
Parameter
keine
Rueckgabe
number
Vollstaendiges Beispiel mit allen Apollo Actions
Dieses Beispiel verwendet jede verfuegbare Apollo Action genau einmal in einem realistischen Ablauf.
async ({ orbi, apollo }) => {
// 1) Apollo verbinden
const credential = orbi.project.credentials.find(x => x.name === "apollo")
if (!credential?.value) throw new Error("missing [apollo] credential")
apollo.connect(credential.value)
// 2) Raw Suche
const rawSearch = await apollo.search({
q_keywords: "founder saas zurich",
page: 1,
per_page: 5
})
// 3) Normalisierte Suche
const normalized = await apollo.searchLeads({
q_keywords: "founder saas zurich",
page: 1,
per_page: 5
})
// 4) Raw Enrichment (aus raw Suche)
const firstRawPerson = rawSearch?.people?.[0]
let rawEnrichment = null
if (firstRawPerson?.linkedin_url) {
rawEnrichment = await apollo.enrichPerson({
linkedin_url: firstRawPerson.linkedin_url,
reveal_personal_emails: true
})
}
// 5) Enrichment per Apollo ID
const firstLead = normalized.leads[0]
let enrichById = null
if (firstLead?.id) {
enrichById = await apollo.enrichById(firstLead.id, {
reveal_personal_emails: true
})
}
// 6) Enrichment per LinkedIn URL
let enrichByLinkedin = null
if (firstLead?.linkedinUrl) {
enrichByLinkedin = await apollo.enrichByLinkedinUrl(firstLead.linkedinUrl, {
reveal_personal_emails: true
})
}
// 7) Kombinierter Helper
const searchAndEnrich = await apollo.searchAndEnrich({
query: "founder saas zurich",
page: 1,
perPage: 10,
maxEnrich: 2
})
// 8) Credits
const credits = apollo.getCredits()
return {
totals: {
rawTotalEntries: rawSearch?.total_entries ?? 0,
normalizedTotalEntries: normalized.totalEntries
},
firstLead,
rawEnrichment,
enrichById,
enrichByLinkedin,
searchAndEnrich,
credits
}
}
Agency
In orbitype-Workflow-Funktionen wird agency automatisch injiziert. Damit kannst du über den Slug auf deine konfigurierten Agenten zugreifen.
Verwende agency.get(slug), um einen Agenten auszuwählen, und run(prompt), um ihn auszuführen.
agency.get(slug)wählt den gewünschten Agenten ausagent.run(prompt)führt den Agenten aus und gibt das Ergebnis zurück
Beispiel:
async ({ agency }) => {
const agent = agency.get("immo_research_agent")
if (!agent) {
return { error: "Agent nicht gefunden: immo_research_agent" }
}
try {
const run = await agent.run("start prompt for my Agent")
return { run }
} catch (e) {
return { error: String(e) }
}
}Agent
orbitype workflow functions haben Zugriff auf ein injiziertes agent-Objekt. Es ist ein vorkonfigurierter Wrapper um langchain mit zwei Methoden: addTool() registriert ein Tool, run() führt den Agent aus und gibt die finale Message zurück
Beispiel:
const func = async ({agent, zod}) => {
const { z } = zod
agent.addTool(
(id) => {
const url = `https://jsonplaceholder.typicode.com/todos/${id}`
return fetch(url).then((x) => x.json())
},
{
name: "fetch_todo",
description: "Fetches a todo by ID from JSONPlaceholder",
schema: z.string()
},
)
agent.addTool(
(text) => text.trim().split(/\s+/).length,
{
name: "count_words",
description: "Counts the number of words in a given string",
schema: z.string(),
returnDirect: true,
},
)
const data = await agent.run("number of words in todo with id 3")
return data
}SERP
orbitype workflow functions haben Zugriff auf ein injiziertes serp-Objekt. Dessen search-Methode führt eine Suchmaschinenabfrage aus und gibt ein Array von Ergebnis-URLs zurück (nach Relevanz sortiert).
Beispiel:
async ({serp}) => {
return {output: await serp.search('orbitype')}
}Output:
[
"https://www.orbitype.com/",
"https://uk.finance.yahoo.com/news/orbitype-com-launches-orbitype-intelligence-150000017.html",
"https://www.orbitype.com/de",
"https://app.orbitype.com/guest/register",
"https://www.orbitype.com/posts",
"https://www.globenewswire.com/news-release/2026/01/06/3213801/0/en/Orbitype-com-Launches-Orbitype-Intelligence-a-Chat-Based-Control-Layer-for-AI-Agent-Environments.html",
"https://www.orbitype.com/vs",
"https://www.crunchbase.com/organization/orbitype",
"https://www.orbitype.com/vs/marketing-automation",
"https://webcatalog.io/en/apps/orbitype"
]Browser
orbitype workflow functions haben Zugriff auf ein injiziertes browser-Objekt. Dessen run-Methode führt Puppeteer-Code remote auf einem anderen Server aus. Die Funktion, die als erster Parameter übergeben wird, wird stringifiziert und via HTTP gesendet. Der zweite Parameter wird als JSON serialisiert und erlaubt es, Variablen von außen zu injizieren. Am Ende wird das Resultat zurückgegeben.
Beispiel:
async ({browser}) => {
const url = "https://vuejs.org/guide/introduction.html"
const clicks = 3
const html = await browser.run(
// puppeteer code
async ({page, data}) => {
await page.goto(data.url)
const button = page.locator(".demo > button")
for (let i = 0; i < data.clicks; i++)
await button.click()
return button.map((x) => x.textContent).wait()
},
// injected variables
{url, clicks}
)
return html
}KI
Nutze KI-Features ganz einfach in deinen Nodes:
async ({ai}) => {
const text = await ai.chat("This is a test")
// -> "this is an answer..."
const json = await ai.chat("JSON for red rgb color", true)
// -> {r: 255, g: 0, b: 0}
return {text , json}
}
async ({ai}) => {
return await ai.image("a red apple")
// -> { base64: "iVBORw..." }
}
async ({ai}) => {
return await ai.embedding("lorem ipsum")
// -> [-0.0014445713,-0.021729672, ... ]
}OCR
orbitype workflow functions haben Zugriff auf ein injiziertes ocr-Objekt. fileToText() gibt den reinen Text einer Datei zurück. fileToTable() gibt tabellarische Daten zurück, die aus der Datei extrahiert wurden. fileToForm() gibt Felder aus einem PDF-Formular zurück
Beispiele:
async ({ocr}) => {
const url = "https://cdn.orbitype.com/sXbDwXihqsp0/pdfs/sample.pdf"
const resp = await fetch(url)
const blob = await resp.blob()
const file = new File([blob], "dummmy.pdf", {type: "application/pdf"})
const text = ocr.fileToText(file)
return text
}
async ({ocr}) => {
const url = "https://cdn.orbitype.com/sXbDwXihqsp0/pdfs/table.png"
const resp = await fetch(url)
const blob = await resp.blob()
const file = new File([blob], "table.png", {type: "image/png"})
const table = ocr.fileToTable(file)
return table
}
async ({ocr}) => {
const url = "https://cdn.orbitype.com/sXbDwXihqsp0/pdfs/table.png"
const resp = await fetch(url)
const blob = await resp.blob()
const file = new File([blob], "table.png", {type: "image/png"})
const table = ocr.fileToForm(file)
return table
}
// tabular data is returned as a 2d array, e.g.
[
["name", "hex", "temperature"],
["red", "#FF0000", "warm"],
["blue", "#0000FF", "cold"],
["yellow", "#FFFF00", "warm"],
["cyan", "#00FFFF", "cold"]
]LinkedIn (erweitert)
LinkedIn Integration in Orbitype
Diese Dokumentation beschreibt alle verfügbaren LinkedIn Aktionen in Orbitype.
Sie erklärt, was jede Aktion macht, welche Parameter benötigt werden, welche Rückgaben zu erwarten sind, und enthält vollständige Beispiele.
Alle LinkedIn Funktionen stehen über das Objekt linkedin in der Orbitype Code-Umgebung zur Verfügung.
Voraussetzungen
Ein Credential mit dem Namen
linkedinexistiert im ProjektDer Code läuft in einer Orbitype Funktion oder einem Agent
Das LinkedIn Konto wird vor allen weiteren Aktionen verbunden
Grundmuster
LinkedIn Konto verbinden
Optional Daten abrufen (Profile, Suche, Chats, Posts)
Aktionen ausführen (Einladungen, Nachrichten, Posts, Kommentare, Reaktionen, Analysen)
Minimales Setup:
async ({ orbi, linkedin }) => {
const accountId = orbi.project.credentials.find(x => x.name === 'linkedin')?.value
if (!accountId) throw new Error('Missing linkedin credential')
await linkedin.connect(accountId)
}
Ohne connect() funktionieren keine weiteren Methoden.
Verbindung
linkedin.connect(accountId)
Beschreibung
Verbindet das LinkedIn Konto und initialisiert die Session.
Parameter
accountId(string, required)
Credential-Wert ausorbi.project.credentialsfür den Namenlinkedin
Rückgabe
{
account_id: string,
provider_id: string
}
provider_id identifiziert das eigene Profil und wird für Profil-/Post-Aktionen verwendet.
Profile und Suche
linkedin.getProfile(identifier, options?)
Beschreibung
Lädt ein LinkedIn Profil über den Identifier (Profil-Handle).
Parameter
identifier(string, required)
Handle aus der LinkedIn URL, z.B.julian-vorrarooptions(object, optional)
Optionale provider-spezifische Optionen
Rückgabe (relevante Felder)
{
first_name: string,
last_name: string,
provider_id: string
}
linkedin.search(params, limit?)
Beschreibung
Sucht auf LinkedIn mit flexiblen Kriterien und Pagination.
Parameter
params(object, required)
Suchkriterien, z.B.{ keywords: 'Webentertainer GmbH' }limit(number, optional, default10)
Maximale Anzahl an Treffern
Standardverhalten
Wenn nicht in
paramsgesetzt:category = 'people'undapi = 'classic'
Rückgabe
Array<object>Liste mit Suchtreffern
Einladungen
linkedin.sendInvitation(providerId, message)
Beschreibung
Sendet eine Kontaktanfrage an ein Profil.
Parameter
providerId(string, required)
Profil-ID ausgetProfile()odersearch()message(string, required)
Einladungstext
linkedin.getInvitations()
Beschreibung
Liefert gesendete Kontaktanfragen.
Parameter
keine
Rückgabe
objectmit Einladungseinträgen
linkedin.cancelInvitation(invitationId)
Beschreibung
Bricht eine gesendete Einladung ab.
Parameter
invitationId(string, required)
ID ausgetInvitations()
Chats und Nachrichten
linkedin.startChat(text, attendeesIds?)
Beschreibung
Startet einen neuen Chat und setzt ihn als aktiven Chat.
Parameter
text(string, required)
Erste NachrichtattendeesIds(string[], optional)
Liste von Teilnehmer-Profil-IDs
Verhalten
Das eigene Profil wird automatisch hinzugefügt
Doppelte Teilnehmer werden automatisch entfernt
linkedin.resumeChat(chatId)
Beschreibung
Setzt einen bestehenden Chat als aktiv.
Parameter
chatId(string, required)
linkedin.getChats()
Beschreibung
Listet bestehende Chats.
Parameter
keine
Verhalten
Verwendet intern ein festes Limit von 20 Chats pro Aufruf
linkedin.getMessages()
Beschreibung
Lädt Nachrichten aus dem aktiven Chat.
Voraussetzung
Ein aktiver Chat muss gesetzt sein (
startChatoderresumeChat)
linkedin.sendMessage(text)
Beschreibung
Sendet eine Nachricht im aktiven Chat.
Parameter
text(string, required)
Posts und Kommentare
linkedin.createPost(text, attachments?)
Beschreibung
Erstellt einen LinkedIn Beitrag. Unterstützt Text-Beiträge, Bild-Beiträge (einzeln oder Karussell), Video-Beiträge (ein Video) und Dokument-Beiträge (PDF, DOC/DOCX, PPT/PPTX).
Parameter
text(string, required)
Beitragstext. Für reine Medien-Beiträge''verwenden.attachments(optional)
Ein Anhang oder ein Array von Anhängen. Jeder Anhang kann sein:URL String — z.B.
'https://.../photo.jpg'{ url, filename? }— URL mit optionalem Dateinamen{ buffer, filename? }— Binärdaten mit optionalem Dateinamen (empfohlen){ base64, filename? }— Base64-Inhalt (plain base64 oderdata:<mime>;base64,...) mit optionalem Dateinamen (empfohlen)
Unterstützte Endungen
Bilder:
jpg,jpeg,png,gif,webpVideos:
mp4,mov,webmDokumente:
pdf,doc,docx,ppt,pptx
Einschränkungen und Hinweise
Bilder und Video nicht im selben Beitrag kombinieren.
Dokument-Beiträge sollten genau ein Dokument enthalten und nicht mit anderen Medien kombiniert werden.
Für Bild-Karussells nur Bild-Anhänge übergeben.
Bei Binär-/Base64-Uploads möglichst immer Dateinamen mitgeben.
Beispiele
// nur Text
await linkedin.createPost('hello from orbitype')
// einzelnes Bild per URL
await linkedin.createPost(
'new product launch',
'https://cdn.example.com/launch.jpg'
)
// Bild-Karussell
await linkedin.createPost('event recap', [
'https://cdn.example.com/1.jpg',
'https://cdn.example.com/2.jpg',
'https://cdn.example.com/3.jpg'
])
// einzelnes Video
await linkedin.createPost('short demo', {
url: 'https://cdn.example.com/demo.mp4',
filename: 'demo.mp4'
})
// einzelnes PDF
await linkedin.createPost('our latest whitepaper', {
url: 'https://cdn.example.com/whitepaper.pdf',
filename: 'Orbitype Whitepaper 2026.pdf'
})
// PDF aus vorherigem Schritt
await linkedin.createPost('monthly report', {
buffer: input.pdfBuffer,
filename: 'report-2026-04.pdf'
})
// Bild aus base64
await linkedin.createPost('ai-generated cover', {
base64: input.coverBase64,
filename: 'cover.png'
})
linkedin.getPosts(identifier)
Beschreibung
Lädt Beiträge eines LinkedIn Profils.
Parameter
identifier(string, required)
Typischerweise die eigeneprovider_idausconnect()
linkedin.sendComment(postId, text)
Beschreibung
Kommentiert einen LinkedIn Beitrag.
Parameter
postId(string, required)text(string, required)
Reaktionen
linkedin.reactToPost(postId, reaction?)
Beschreibung
Sendet eine Reaktion auf einen Beitrag.
Parameter
postId(string, required)reaction(string, optional, default'LIKE')
linkedin.likePost(postId)
Beschreibung
Komfortmethode für reactToPost(postId, 'LIKE').
Parameter
postId(string, required)
Posting-Identitäten
linkedin.getPostingIdentities()
Beschreibung
Liefert verfügbare Posting-Identitäten des verbundenen Kontos (Member + ggf. Organization/Page).
Rückgabe
[
{
id: string,
type: 'member' | 'organization' | 'page' | 'unknown',
name: string | null,
provider: 'linkedin',
mailbox_id?: string | null,
raw: unknown
}
]
linkedin.createPostAs(identityId, text, attachments?)
Beschreibung
Erstellt einen Beitrag als bestimmte Identität.
Parameter
identityId(string, required)
ID ausgetPostingIdentities()text(string, required)attachments(optional)
Gleiches Format wie beicreatePost()
Rückgabe
Post-Payload inklusive Identity-Metadaten (
posting_identity_id,posting_identity_field)
linkedin.createOrganizationPost(organizationId, text, attachments?)
Beschreibung
Alias für Organization/Page-Posting.
Entspricht
await linkedin.createPostAs(organizationId, text, attachments)
Post-Engagement-Analysen
linkedin.getPostComments(postId, options?)
Beschreibung
Lädt eine paginierte Kommentar-Seite für einen Beitrag.
Parameter
postId(string, required)options(object, optional)cursor(string, optional)limit(number, optional, begrenzt auf 1..100)sort_by(string, optional):'MOST_RECENT'oder'MOST_RELEVANT'comment_id(string, optional)
Rückgabe
{
items: any[],
cursor: string | null,
raw: any
}
linkedin.getAllPostComments(postId, options?)
Beschreibung
Paginierung automatisch bis zum Ende oder bis zum gesetzten Limit.
Parameter
postId(string, required)options(object, optional)limitPerPage(number, optional)maxItems(number, optional)sort_by(string, optional)comment_id(string, optional)
Rückgabe
any[]flache Kommentar-Liste
linkedin.getPostReactions(postId, options?)
Beschreibung
Lädt eine paginierte Reaktions-Seite für einen Beitrag.
Parameter
postId(string, required)options(object, optional)cursor(string, optional)limit(number, optional, begrenzt auf 1..100)comment_id(string, optional)
Rückgabe
{
items: any[],
cursor: string | null,
raw: any
}
linkedin.getAllPostReactions(postId, options?)
Beschreibung
Paginierung automatisch bis zum Ende oder bis zum gesetzten Limit.
Parameter
postId(string, required)options(object, optional)limitPerPage(number, optional)maxItems(number, optional)comment_id(string, optional)
Rückgabe
any[]flache Reaktions-Liste
linkedin.getPostEngagedPersons(postId, options?)
Beschreibung
Kombiniert Kommentar- und Reaktions-Akteure zu einer deduplizierten Engagement-Ansicht.
Parameter
postId(string, required)options(object, optional)includeComments(boolean, optional, defaulttrue)includeReactions(boolean, optional, defaulttrue)commentSort(string, optional)limitPerPage(number, optional)maxComments(number, optional)maxReactions(number, optional)
Rückgabe
{
people: [
{
id: string | null,
provider_id: string | null,
name: string | null,
headline: string | null,
profile_url: string | null,
sources: Array<'comment' | 'reaction'>,
comments_count: number,
reactions_count: number,
raw_examples: any[]
}
],
comments: any[],
reactions: any[]
}
linkedin.getCompanyActiveEngagers(companyIdentifier, options?)
Beschreibung
Lädt Company-Posts und aggregiert aktive Engager über mehrere Beiträge.
Parameter
companyIdentifier(string, required)options(object, optional)postsLimit(number, optional, default20)includeComments(boolean, optional)includeReactions(boolean, optional)commentSort(string, optional)limitPerPage(number, optional)maxCommentsPerPost(number, optional)maxReactionsPerPost(number, optional)
Rückgabe
{
company_identifier: string,
posts_scanned: Array<{ id: string, raw: any }>,
engagers: Array<{
id: string | null,
provider_id: string | null,
name: string | null,
headline: string | null,
profile_url: string | null,
posts_count: number,
comments_count: number,
reactions_count: number,
engagement_types: Array<'comment' | 'reaction'>,
post_ids: string[],
comment_texts: string[],
reaction_types: string[],
raw_examples: any[]
}>,
errors: Array<{ scope: 'company' | 'post', message: string, post_id?: string }>
}
Credits
linkedin.getCredits()
Beschreibung
Liefert gerundete verbrauchte Credits für die aktuelle LinkedIn Session innerhalb der aktuellen Ausführung.
Vollständiges Beispiel
async ({ orbi, linkedin }) => {
// 1) verbinden
const accountId = orbi.project.credentials.find(x => x.name === 'linkedin')?.value
if (!accountId) throw new Error('Missing linkedin credential')
const self = await linkedin.connect(accountId)
// 2) suche + profil
const searchResults = await linkedin.search({ keywords: 'Webentertainer GmbH' }, 10)
const profile = await linkedin.getProfile('julian-vorraro')
// 3) einladungen
await linkedin.sendInvitation(profile.provider_id, 'Hallo Julian, kurze Vernetzung?')
const invitations = await linkedin.getInvitations()
if (invitations.items?.length) {
await linkedin.cancelInvitation(invitations.items[0].invitation_id)
}
// 4) chat + nachrichten
await linkedin.startChat('Danke fürs Vernetzen 👋', [profile.provider_id])
await linkedin.sendMessage('Kurzer Austausch zu Automatisierung?')
const chats = await linkedin.getChats()
if (chats.items?.length) await linkedin.resumeChat(chats.items[0].id)
const messages = await linkedin.getMessages()
// 5) beitrag erstellen
const createdPost = await linkedin.createPost('Automatisierung direkt aus Orbitype 🚀', {
url: 'https://cdn.example.com/post-cover.jpg',
filename: 'cover.jpg'
})
// 6) identitäten + als organization/page posten
const identities = await linkedin.getPostingIdentities()
const orgIdentity = identities.find(x => x.type === 'organization' || x.type === 'page')
if (orgIdentity) {
await linkedin.createPostAs(orgIdentity.id, 'Posted as organization via createPostAs')
await linkedin.createOrganizationPost(orgIdentity.id, 'Posted as organization via alias')
}
// 7) posts + kommentar + reaktion
const posts = await linkedin.getPosts(self.provider_id)
const firstPostId = posts.items?.[0]?.id || posts.items?.[0]?.post_id || createdPost?.id || createdPost?.post_id
if (firstPostId) {
await linkedin.sendComment(firstPostId, 'Danke fürs Lesen')
await linkedin.reactToPost(firstPostId, 'LIKE')
await linkedin.likePost(firstPostId)
// 8) engagement-analysen
const commentsPage = await linkedin.getPostComments(firstPostId, {
limit: 20,
sort_by: 'MOST_RECENT'
})
const allComments = await linkedin.getAllPostComments(firstPostId, {
maxItems: 100,
sort_by: 'MOST_RECENT'
})
const reactionsPage = await linkedin.getPostReactions(firstPostId, {
limit: 20
})
const allReactions = await linkedin.getAllPostReactions(firstPostId, {
maxItems: 100
})
const engaged = await linkedin.getPostEngagedPersons(firstPostId, {
includeComments: true,
includeReactions: true,
commentSort: 'MOST_RECENT',
maxComments: 200,
maxReactions: 200
})
console.log('comments page:', commentsPage.items?.length)
console.log('all comments:', allComments.length)
console.log('reactions page:', reactionsPage.items?.length)
console.log('all reactions:', allReactions.length)
console.log('engaged persons:', engaged.people?.map(x => x.name))
}
// 9) company-level aktive engagers
const companyEngagers = await linkedin.getCompanyActiveEngagers('webentertainer', {
postsLimit: 10,
includeComments: true,
includeReactions: true,
commentSort: 'MOST_RECENT',
maxCommentsPerPost: 150,
maxReactionsPerPost: 150
})
// 10) credits
const credits = linkedin.getCredits()
return {
self,
searchResultsCount: searchResults.length,
messagesCount: messages.items?.length ?? 0,
identitiesCount: identities.length,
companyEngagersCount: companyEngagers.engagers.length,
credits
}
}
Fehlerbehebung
Not connected Fehler: Sicherstellen, dass
linkedin.connect(accountId)zuerst läuft.Keine Nachrichten: Sicherstellen, dass ein aktiver Chat gesetzt wurde.
Upload-Fehler bei Posts: Dateiendung, Typ, Größe und Dateiname prüfen.
Wenig/keine Analytics Daten: Engagement kann gering sein oder durch Sichtbarkeit begrenzt sein.
Fehler bei Company-Engagers: Gültigen Company-Identifier nutzen und Zugriffsrechte prüfen.
Bibliotheken
orbitype workflow functions haben Zugriff auf einige injizierte npm-Bibliotheken.
cheerio
imapflow
lodash
nodemailer
pdf-lib (verfügbar als PDFLib)
pdfkit (verfügbar als PDFDocument)
unpdf
swissqrbill
zod
zusätzliches manuelles Importieren/Requiren weiterer Libraries wird NICHT unterstützt
Beispiele:
const func = async ({lodash}) => {
await new Promise((res) => setTimeout(res, 100))
const output = lodash.random(0,9)
return {output}
}
const func = async ({config, input, nodemailer}) => {
const transporter = nodemailer.createTransport({
host: "smtp.ethereal.email",
port: 587,
auth: {
user: config.user,
pass: config.pass,
},
})
const mail = {
from: config.user,
to: input.email,
subject: config.subject,
text: config.text,
}
await transporter.sendMail(mail)
return mail
}
const func = async ({ImapFlow}) => {
const client = new ImapFlow({
host: 'smtp.ethereal.email',
port: 993,
secure: true,
auth: {
user: "nathanial.oreilly@ethereal.email",
pass: "BnK2wAJtg4P1Efu5zp",
}
})
await client.connect()
await client.mailboxOpen('INBOX')
const message = await client.fetchOne('*', { source: true })
await client.logout()
return message.source.toString()
}
const func = async ({unpdf}) => {
const url = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
const res = await fetch(url)
const buffer = await res.arrayBuffer()
const pdf = await unpdf.getDocumentProxy(new Uint8Array(buffer))
const { text } = await unpdf.extractText(pdf, { mergePages: true })
return text
}
const func = async ({PDFLib}) => {
const pdfDoc = await PDFLib.PDFDocument.create()
const page = pdfDoc.addPage()
page.drawText('lorem ipsum')
const base64 = await pdfDoc.saveAsBase64({ dataUri: true })
return base64
}
const func = async ({SwissQRBill, PDFDocument}) => {
return new Promise((resolve, reject) => {
const doc = new PDFDocument({ size: 'A4' });
const chunks = [];
doc.on('data', (chunk) => chunks.push(chunk));
doc.on('end', () => resolve(Buffer.concat(chunks).toString('base64')));
doc.on('error', reject);
doc.fontSize(20).text('Invoice #12345', 50, 50);
doc.fontSize(12).text('Lorem ipsum...', 50, 100);
const data = {
amount: 1994.75,
creditor: {
account: "CH44 3199 9123 0008 8901 2",
address: "Musterstrasse",
buildingNumber: 7,
city: "Musterstadt",
country: "CH",
name: "SwissQRBill",
zip: 1234
},
currency: "CHF",
debtor: {
address: "Musterstrasse",
buildingNumber: 1,
city: "Musterstadt",
country: "CH",
name: "Peter Muster",
zip: 1234
},
reference: "21 00000 00003 13947 14300 09017"
};
const qrBill = new SwissQRBill(data);
qrBill.attachTo(doc);
doc.end();
});
}SheetJS (XLSX): Tabellenverarbeitung
XLSX ist SheetJS, eine leistungsstarke Library zur Tabellenverarbeitung, die in Orbitype-Workflows per Dependency Injection verfügbar ist. Damit kannst du Spreadsheets und tabellarische Daten in vielen Formaten lesen, erstellen, bearbeiten und exportieren. Das ist ideal für Imports, Exports, Reporting und Daten-Transformationen.
Was SheetJS alles kann
Lesen von Spreadsheets und tabellarischen Daten (zum Beispiel: XLSX, XLS, CSV und mehr) aus Strings, ArrayBuffers und anderen unterstützten Inputs.
Erstellen und bearbeiten von Workbooks und Worksheets per Code.
Konvertieren zwischen Formaten (zum Beispiel: CSV zu XLSX, XLSX zu CSV).
Transformieren von Datenstrukturen: Sheet zu JSON, JSON zu Sheet, Arrays zu Sheet und mehr.
Schreiben/Exportieren von Dateien (zum Beispiel: XLSX/CSV Output generieren für Downloads, E-Mails oder Storage).
Arbeiten mit Zellen: Werte setzen, Zahlenformate, Datumswerte, Formeln und grundlegende Worksheet-Metadaten.
Utility-Helper für Ranges, Header, Spalten-Mappings und typische Spreadsheet-Operationen.
Beispiel:
async ({ XLSX }) => {
const csv =
`name, age, city, email
John Doe, 30, New York, john@example.com
Jane Smith, 25, Los Angeles, jane@example.com
Bob Johnson, 35, Chicago, bob@example.com`;
const workbook = XLSX.read(csv, { type: "string" });
const sheet = workbook.Sheets['Sheet1'];
const json = XLSX.utils.sheet_to_json(sheet);
return json;
};Hinweise:
Die Header-Zeile des CSV wird zu den Objekt-Keys im resultierenden JSON-Array.
XLSX.readparst den Input in eine Workbook-Struktur.XLSX.utils.sheet_to_jsonwandelt Worksheet-Zeilen in JSON-Objekte um.
Learn more
Konto kündigen
Wir möchten sicherstellen, dass du Orbitype problemlos nutzen kannst. Falls du Fragen hast oder auf Schwierigkeiten stößt, zögere nicht, uns zu kontaktieren. Wir sind für dich da – schreib uns einfach eine Nachricht an support@orbitype.com, und wir helfen dir gerne weiter.
