Join our Discord community — connect, share, and grow with us! Join Now

Workflows

Workflows ermöglichen es Nutzerinnen und Nutzern, eigene Automationen innerhalb ihrer Workspaces zu erstellen.
"Workflows" bestehen aus "Nodes", die man als serverlose Funktionen verstehen kann, die miteinander verbunden werden können.

Trigger

Manuell (Button klicken)

Dies ist die Standardoption. Sie bedeutet, dass der Workflow nur ausgelöst wird, wenn du in der Workflow-UI manuell auf "execute" klickst.

Cron (AWS cron)

Cron ermöglicht es dir, die Ausführung deines Workflows sehr präzise zu planen (minutengenau). Wir verwenden das AWS-Cron-Format, um ein zuverlässiges Scheduling-Erlebnis sicherzustellen.

Webhook (URL + Payload)

OrbitType erzeugt eine Webhook-URL, die als Einstiegspunkt dient. Wenn eine Drittanbieter-App oder dein Bot aus einem anderen Client eine POST-Anfrage mit einem JSON-Body an diesen Endpoint sendet, wird dieser JSON-Body als Input-JSON für die erste Node verwendet. Dieser Input wird außerdem als Beispiel in deinem Workspace gespeichert, um Tests zu vereinfachen. Du kannst ihn im Code-Editor der ersten Node mit "Load Input" laden.

Datenbank (Tabellen-Events und OrbitType-API-Trigger)

Da OrbitType eine integrierte Umgebung ist, kannst du auf Trigger aus Datenbanktabellen lauschen. Wir unterstützen Events für Erstellung, Updates und Löschungen. Die SQL-Anfrage, die den Workflow auslöst, muss über die OrbitType-API ausgeführt werden und einen definierten Return-Value enthalten. Für Tests wird der Input gespeichert, sodass er später wieder abgerufen werden kann.
Wenn eine Zeile aktualisiert wird, erhältst du als Input ein Array mit zwei Objekten: eines mit der alten Zeile und eines mit der neuen Zeile. Du kannst dann JavaScript innerhalb der Node verwenden, um präzise zu prüfen, ob die Änderungen den Flow auslösen sollen oder ob du frühzeitig zurückkehren möchtest.

Versionen/Wiederherstellen

Jeder Workflow ist versioniert. Bei jedem Speichern einer Node wird der komplette Workflow gespeichert. Über den Button "Versions" kannst du auf frühere Versionen zurückspringen und diese wiederherstellen. Es werden 50 Versionen als Backups aufbewahrt.

Node-Typen

Code-Nodes

Dies ist die Standard-Node. In dieser Node kannst du Code schreiben und Config-Werte setzen, die du innerhalb des Codes verwendest.

Dekorative Nodes

Das sind visuelle Elemente, die dir helfen, den Workflow-Plan zu dokumentieren und visuell zu strukturieren. Sie können außerdem nützlichen Kontext für Orbitype Intelligence liefern.

Node-Einstellungen

Entry-Node

Jeder Workflow hat genau eine Entry-Node. Das ist entweder per Konvention die erste Node auf dem Canvas oder die Node, die du in den Node-Einstellungen manuell als Entry festlegst.

Hard Limit

Nodes können bis zu 60 Minuten laufen. Da du Nodes aneinanderketten kannst, können dadurch sehr lang laufende Tasks entstehen. Um zu verhindern, dass Nodes in Situationen zu lange laufen, in denen sie klarerweise nur wenige Minuten dauern sollten, kannst du ein Hard Limit setzen, das die Laufzeit hart abbricht. Das ist kein sanfter Prozess, das heißt: Wenn die Node in ein Timeout läuft, erhältst du kein Output.
Das ist besonders hilfreich beim Experimentieren mit AI-Agents und Prompts, die noch nicht optimiert sind, weil diese sonst zu langen Läufen und verschwendeten Credits führen können, wenn kein Hard Limit gesetzt ist.

Benennung

Eine saubere Benennung von Nodes hilft dir, deinen Kolleginnen und Kollegen und Orbitpye Intelligence dabei, den Zweck jeder Node besser zu verstehen. Es ist wichtig, jede Node klar anhand ihrer Funktion zu benennen.

Node-Funktionsstruktur und Logging

Orbitype-Nodes müssen die folgende Syntax verwenden, wobei nur eine Funktion erlaubt ist. Innerhalb dieser Funktion kannst du normales Node.js verwenden. Bitte beachte, dass dies eine serverlose Umgebung ist, daher funktionieren einige OS-nahe Funktionen nicht.
In Orbitype-Funktionen musst du niemals etwas require oder importieren. Stattdessen kannst du die erlaubten Libraries und API-Produkte per Dependency Injection in die Funktion geben und dann nutzen.

async ({input}) => {
  return {output: input}
}


Wenn du Informationen loggen möchtest, empfiehlt es sich, ein debug-Array zu erstellen und Nachrichten hinein zu pushen. Am Ende kannst du es zusammen mit anderen Dingen zurückgeben. So kann die nächste Node Fehler analysieren oder du kannst sie weiterverarbeiten.

Node-Output und Next-Parameter

Output einer Node

Wenn du in der Funktion einfach etwas zurückgibst, wird das als Output gesetzt.
Wenn du mehr Kontrolle möchtest und außerdem Features wie next nutzen willst, musst du ein Objekt mit dem Key output zurückgeben. Dann legst du den Output dort ab und er wird als sauberer, nicht „boxed“ Input an die nächste Node weitergegeben.

async () => {
  const output = Math.random() 
  return {output, 
next: output > 0.5 ? "idOfTheNextNode" : "idOfTheOtherNextNode"}
}

Next-Attribut

Das next-Attribut erlaubt es dir, die nächste Node dynamisch zu bestimmen. Das funktioniert nur, wenn zwei oder mehr Nodes über den Output-Handle der Node verbunden sind.

async () => {
  const output = Math.random() 
  return {output, next: output > 0.5 ? "idOfTheNextNode" : "idOfTheOtherNextNode"}
}

Flow-Typen

Linear

Das ist ein einfacher Workflow, der von a -> b -> c läuft. Das ist der einfachste und häufigste Weg.

Branching

Wenn dein Workflow-Pfad an einem Punkt entscheiden muss, ob er mit Pfad a.a oder Pfad a.b weitergeht, kannst du den next-Parameter setzen, um das zu steuern.

Multi Input

Jeder Workflow hat nur eine Entry-Node, aber du kannst auch eine weitere Node hinzufügen und sie an die zweite Node anschließen, wenn das beim Testen eines Input-Payloads hilft. Später im Flow kann es auch passieren, dass du mehrere Inputs hast. Denk daran, dass das Payload je nach Input variieren kann, weil zwei oder mehr verschiedene Nodes es befüllen können. Wenn du in den vorherigen Nodes nicht mit demselben Format arbeitest, kann das in der Node mit mehreren Inputs zu Fehlern führen.

Looping

Das ist super, um Bedingungen innerhalb eines Workflows abzubilden, aber falsche Bedingungen können zu Endlosschleifen führen, die wiederum Tokens verbrennen. Nutze Looping nur in sehr kontrollierten Settings mit klaren Exit-Regeln.

Sub-Workflow-Architektur

Wenn ein Workflow aus klar trennbaren Sub-Workflows besteht, ergibt es meist Sinn, diese als eigene Workflows zu bauen und per Webhooks zu triggern. So bekommst du eine deutlich modularere Workspace-Struktur und kannst Sub-Teile isoliert nutzen und testen.

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 }
}

Deprecated: credentials-Injection

Die direkte credentials-Injection ist deprecated. Verwende stattdessen orbi.project.credentials, damit Workflows konsistent und zukunftssicher bleiben.

// deprecated
async ({ credentials }) => {
  const apiKey = credentials.myApiKey
  return { apiKey }
}

Hinweis: Secrets nicht als Output zurückgeben. Verwende sie nur intern für authentifizierte Calls.

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 apollo existiert im Projekt

  • Der 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:

  1. Apollo verbinden

  2. Personen suchen (raw oder normalisiert)

  3. 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

  • object raw Apollo Response (enthaelt typischerweise total_entries und people)


apollo.searchLeads(params)

Beschreibung
Normalisierte Suchantwort mit stabilen Lead-Feldern.

Parameter

  • params (object, optional)
    Gleiche Query-Form wie bei search()

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

  • object raw Enrichment-Response (typischerweise mit person und request_id)


apollo.enrichById(personId, options)

Beschreibung
Reichert eine Person ueber die Apollo Person-ID an.

Parameter

  • personId (string, required)
    Apollo Person-ID

  • options (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 URL

  • options (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): Suchbegriff

    • page (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
  }
}

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, inklusive der erwarteten Parameter, Rückgaben und eines vollständigen Beispiel-Workflows, der jede Action einmal verwendet.

Die Integration steht über das Objekt linkedin in der Orbitype Code-Umgebung zur Verfügung.


Voraussetzungen

  • Ein Credential mit dem Namen linkedin existiert im Projekt

  • Der Code läuft in einer Orbitype Funktion oder einem Agent

  • Vor jeder Aktion muss das LinkedIn Konto verbunden werden


Verbindungsaufbau

linkedin.connect(accountId)

Beschreibung
Verbindet dein LinkedIn Konto und initialisiert die Session.
Diese Methode muss immer zuerst aufgerufen werden.

Parameter

  • accountId (string, required)
    Wert aus orbi.project.credentials für das Credential linkedin

Rückgabe

{
  account_id: string,
  provider_id: string
}

Profile & Suche

linkedin.getProfile(identifier)

Beschreibung
Lädt ein LinkedIn Profil anhand des Profil-Identifiers.

Parameter

  • identifier (string, required)
    LinkedIn Handle aus der Profil-URL, z.B. julian-vorraro

Rückgabe (relevante Felder)

{
  first_name: string,
  last_name: string,
  provider_id: string
}

linkedin.search(params)

Beschreibung
Sucht nach LinkedIn Profilen mit frei definierbaren Suchparametern.

Parameter

  • params (object, required)
    Suchkriterien, z.B.:

    • keywords (string)

Rückgabe

  • Array<object> Liste von Suchtreffern


Einladungen

linkedin.sendInvitation(providerId, message)

Beschreibung
Sendet eine Kontaktanfrage an ein Profil.

Parameter

  • providerId (string, required)
    Profil-ID aus getProfile() oder search()

  • message (string, required)
    Einladungstext


linkedin.getInvitations()

Beschreibung
Listet gesendete Kontaktanfragen.

Parameter

  • keine

Rückgabe

  • object mit Einladungseinträgen


linkedin.cancelInvitation(invitationId)

Beschreibung
Bricht eine gesendete Einladung ab.

Parameter

  • invitationId (string, required)
    ID aus getInvitations()


Chats & Nachrichten

linkedin.startChat(text, attendeesIds)

Beschreibung
Startet einen neuen Chat und setzt ihn als aktiv.

Parameter

  • text (string, required)
    Erste Nachricht

  • attendeesIds (string[], optional)
    Liste von providerIds


linkedin.resumeChat(chatId)

Beschreibung
Setzt einen bestehenden Chat als aktiv.

Parameter

  • chatId (string, required)


linkedin.getChats()

Beschreibung
Listet bestehende Chats.

Parameter

  • keine


linkedin.getMessages()

Beschreibung
Lädt Nachrichten aus dem aktuell aktiven Chat.

Voraussetzung

  • Ein aktiver Chat ist gesetzt


linkedin.sendMessage(text)

Beschreibung
Sendet eine Nachricht im aktiven Chat.

Parameter

  • text (string, required)


Posts & Kommentare

linkedin.createPost(text)

Beschreibung
Erstellt einen LinkedIn Beitrag.

Parameter

  • text (string, required)


linkedin.getPosts(identifier)

Beschreibung
Lädt Beiträge eines Profils.

Parameter

  • identifier (string, required)
    Meist die eigene provider_id


linkedin.sendComment(postId, text)

Beschreibung
Kommentiert einen Beitrag.

Parameter

  • postId (string, required)

  • text (string, required)


Vollständiges Beispiel: Alle LinkedIn Actions in einem Flow

Dieses Beispiel verwendet jede verfügbare LinkedIn Action genau einmal in einem realistischen Ablauf.

async ({ orbi, linkedin }) => {
  // 1) LinkedIn verbinden
  const accountId = orbi.project.credentials.find(x => x.name === "linkedin").value
  const self = await linkedin.connect(accountId)

  // 2) Personen suchen
  const searchResults = await linkedin.search({
    keywords: "Webentertainer GmbH"
  })

  // 3) Profil laden
  const profile = await linkedin.getProfile("julian-vorraro")

  // 4) Einladung senden
  await linkedin.sendInvitation(
    profile.provider_id,
    "Hallo Julian, kurze Vernetzung?"
  )

  // 5) Gesendete Einladungen abrufen
  const invitations = await linkedin.getInvitations()

  // 6) Einladung optional abbrechen
  if (invitations.items?.length) {
    await linkedin.cancelInvitation(invitations.items[0].invitation_id)
  }

  // 7) Chat starten
  await linkedin.startChat(
    "Danke fürs Vernetzen 👋",
    [profile.provider_id]
  )

  // 8) Nachricht senden
  await linkedin.sendMessage("Kurzer Austausch zu Automatisierung?")

  // 9) Chats abrufen
  const chats = await linkedin.getChats()

  // 10) Bestehenden Chat fortsetzen
  if (chats.items?.length) {
    await linkedin.resumeChat(chats.items[0].id)
  }

  // 11) Nachrichten abrufen
  const messages = await linkedin.getMessages()
  console.log(messages.items?.map(m => m.text))

  // 12) Beitrag erstellen
  await linkedin.createPost("Automatisierung direkt aus Orbitype 🚀")

  // 13) Eigene Beiträge abrufen
  const posts = await linkedin.getPosts(self.provider_id)

  // 14) Beitrag kommentieren
  if (posts.items?.length) {
    await linkedin.sendComment(
      posts.items[0].id,
      "Danke fürs Lesen"
    )
  }
}

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.read parst den Input in eine Workbook-Struktur.

  • XLSX.utils.sheet_to_json wandelt 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.

Detaillierte Preisgestaltung

Orbitype nutzt ein einfaches Credit-Modell. 1 USD entspricht 100 Credits. Jeder Workspace hat einen Sponsor-User, der alle Seats und die gesamte Nutzung bezahlt. Credits können prepaid gekauft und flexibel für Seats und Usage genutzt werden.