snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 3s

This commit is contained in:
upstream-mirror
2026-09-17 23:28:13 +05:00
commit e7da97194a
32688 changed files with 4208681 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
---
title: Automatische Antwort auf eingehende E-Mails
description: Erstellen Sie einen Workflow, der KI nutzt, um eingehende E-Mails zu sichten und automatisch Antworten im Thread zu senden.
---
Antworten Sie auf eingehende E-Mails in Sekunden — nicht in Stunden. Dieser Workflow verwendet einen AI Agenten, um Rauschen (Newsletter, Spam, Auto-Antworten) zu filtern und eine personalisierte Antwort auf echte Nachrichten zu entwerfen. Dann sendet die KI sie als Thread-Antwort innerhalb der ursprünglichen Konversation.
## Wie E-Mail-Threading funktioniert
Jede E-Mail enthält einen verborgenen `Message-ID`-Header — einen eindeutigen Fingerabdruck, der vom Mailserver des Absenders zugewiesen wird. Wenn Sie auf eine E-Mail antworten, setzt Ihr E-Mail-Client einen `In-Reply-To`-Header, der auf diesen Fingerabdruck verweist. So gruppieren Gmail, Outlook und alle anderen Clients Nachrichten in Threads.
In Twenty wird dieser Fingerabdruck als `headerMessageId` am Message-Objekt gespeichert. Ihr Workflow greift ihn auf und übergibt ihn an das Feld In-Reply-To der Aktion Send Email.
## Den Workflow erstellen
### Schritt 1: Neuen Workflow erstellen
Gehen Sie zu **Settings -> Workflows** und klicken Sie auf **+ New Workflow**.
### Schritt 2: Bei eingehenden Nachrichten auslösen
Wählen Sie **When a Record is Created** und dann **Messages**.
Jedes Mal, wenn eine E-Mail in Twenty eingeht, wird dies ausgelöst.
<img src="/images/user-guide/workflows/auto-reply/workflow-overview.png" style={{width:'100%'}} />
### Schritt 3: Absender ermitteln
Fügen Sie eine **Datensätze suchen**-Aktion hinzu.
Die Absenderadresse befindet sich nicht in der Nachricht selbst — sie steht im zugehörigen Datensatz Message Participant.
| Feld | Wert |
| ---------- | -------------------------------- |
| **Objekt** | Nachrichtenteilnehmer |
| **Filter** | Message **ist** `{{trigger.id}}` |
| **Filter** | Rolle **ist** From |
| **Limit** | 1 |
Dadurch erhalten Sie die E-Mail-Adresse des Absenders in `handle` und den Namen in `displayName`.
<img src="/images/user-guide/workflows/auto-reply/find-sender.png" style={{width:'100%'}} />
### Schritt 4: Triage und Entwurf einer Antwort mit der KI
Fügen Sie eine **AI Agent**-Aktion hinzu. Dieser einzelne Schritt erledigt zwei Dinge: Er entscheidet, ob die E-Mail eine Antwort verdient, und falls ja, verfasst er eine.
Verwenden Sie einen Prompt wie:
```
You are an email triage assistant for a sales team. Read the following
inbound email and decide if it deserves a reply.
Subject: {{trigger.subject}}
Body: {{trigger.text}}
From: {{Find Sender.first.displayName}} ({{Find Sender.first.handle}})
If this email is spam, a newsletter, an automated notification, or
otherwise does not need a human reply, respond with exactly: SKIP
Otherwise, write a short, professional reply (3-4 sentences max) that:
- Acknowledges their specific message
- Lets them know someone from the team will follow up shortly
- Is warm but not overly casual
Respond with only the reply text, no subject line or greeting prefix.
```
Der AI Agent gibt seine Antwort in einem Feld `response` aus, auf das sich die nächsten Schritte beziehen können.
<img src="/images/user-guide/workflows/auto-reply/ai-triage.png" style={{width:'100%'}} />
### Schritt 5: Verzweigen anhand der KI-Entscheidung
Fügen Sie eine **If/Else**-Aktion hinzu, um zu prüfen, ob die KI sich entschieden hat zu antworten oder zu überspringen.
| Feld | Wert |
| ------------- | -------------------------------------------- |
| **Bedingung** | AI Agent `response` **enthält nicht** `SKIP` |
| **Wenn wahr** | Mit Send Email fortfahren |
| **Sonst** | Nichts tun (Workflow endet) |
Spam, Newsletter und automatisch erzeugte Nachrichten werden verworfen. Alles andere geht zum nächsten Schritt über.
<img src="/images/user-guide/workflows/auto-reply/should-reply.png" style={{width:'100%'}} />
### Schritt 6: Eine Antwort im Thread senden
Fügen Sie im "Wenn wahr"-Zweig eine **Send Email**-Aktion hinzu. Klicken Sie auf **Advanced options**, dann **Add In-Reply-To**.
| Feld | Wert |
| --------------- | -------------------------------------- |
| **An** | `{{Find Sender.first.handle}}` |
| **Betreff** | `Re: {{trigger.subject}}` |
| **Body** | `{{AI Triage & Draft Reply.response}}` |
| **In-Reply-To** | `{{trigger.headerMessageId}}` |
Das Feld In-Reply-To sorgt dafür, dass dies eine Antwort und keine neue Unterhaltung ist. Der Empfänger sieht sie als Teil des Threads unter der ursprünglichen E-Mail in Gmail, Outlook oder jedem anderen Client.
<img src="/images/user-guide/workflows/auto-reply/send-email.png" style={{width:'100%'}} />
<Tip>
**In-Reply-To** erwartet eine `message.headerMessageId` aus dem Trigger — das ist der eindeutige Fingerabdruck der E-Mail, keine Empfängeradresse. Wenn Sie es leer lassen, wird die E-Mail trotzdem gesendet, nur als eigenständige Nachricht.
</Tip>
<Warning>
Gmail verwendet die Betreffzeile, um Nachrichten in Threads zu gruppieren. Der Betreff **muss** mit `Re:` beginnen (einschließlich Doppelpunkt und Leerzeichen), damit Gmail die Antwort im ursprünglichen Thread anzeigt. Ohne dies erscheint die Antwort als separate Unterhaltung — selbst wenn der In-Reply-To-Header korrekt gesetzt ist.
</Warning>
### Schritt 7: Testen und aktivieren
Klicken Sie auf **Test**, und prüfen Sie dann Ihren E-Mail-Client. Die Antwort sollte unter der ursprünglichen Nachricht verschachtelt erscheinen.
Aktivieren Sie ihn, wenn Sie zufrieden sind.
## Ideen zum Ausbau
* **Nur an VIPs antworten** — fügen Sie einen Zweig hinzu, der die Domain des Absenders prüft oder ob er in Twenty als Kontakt existiert
* **Nach Absicht routen** — verwenden Sie separate AI Agent-Prompts, um Vertriebsanfragen anders zu bearbeiten als Supportanfragen
* **Vor der Antwort anreichern** — fügen Sie einen Schritt Search Records hinzu, um das Unternehmen oder die Deal-Historie des Absenders in den AI-Prompt zu übernehmen, für persönlichere Antworten

View File

@@ -0,0 +1,179 @@
---
title: Closed-Won-Automatisierungen
description: Automatisieren Sie Post-Win-Aktivitäten, wenn Opportunities abgeschlossen werden.
---
Wenn ein Deal abgeschlossen wird, müssen mehrere Dinge geschehen: Unternehmensstatus aktualisieren, Teammitglieder benachrichtigen, Onboarding-Aufgaben erstellen. Automatisieren Sie all das mit einem einzigen Workflow.
## Das Problem
Wenn eine Opportunity zu "Closed Won" wechselt:
* Der Unternehmenstyp muss von "Prospect" zu "Customer" geändert werden
* Onboarding-Aufgaben müssen erstellt werden
* Das Customer-Success-Team muss benachrichtigt werden
* Der Vertriebsmitarbeiter benötigt eine Bestätigung
Dies manuell zu erledigen ist zeitaufwendig und fehleranfällig.
## Die Lösung
Erstellen Sie einen Workflow, der alle Post-Win-Aktivitäten automatisch erledigt.
## Vollständige Workflow-Einrichtung
### Schritt 1: Workflow erstellen
1. Gehen Sie zu **Einstellungen → Workflows**
2. Klicken Sie auf **+ Neuer Workflow**
3. Benennen Sie ihn "Deal Won - Post-Win Automation"
### Schritt 2: Trigger konfigurieren
1. Wählen Sie **Datensatz wird aktualisiert** aus
2. Wählen Sie **Opportunities**
3. Wählen Sie unter "Fields to monitor" **Stage** aus
### Schritt 3: Stage-Filter hinzufügen
1. Fügen Sie eine **Filter**-Aktion hinzu
2. Bedingung: `{{trigger.object.stage}}` ist gleich "Closed Won"
### Schritt 4: Unternehmenstyp aktualisieren
1. Fügen Sie die Aktion **Datensatz aktualisieren** hinzu
2. Konfigurieren:
| Feld | Wert |
| -------------------------- | ------------------------------- |
| **Objekt** | Unternehmen |
| **Datensatz** | `{{trigger.object.company.id}}` |
| **Typ** | Kunde |
| **Datum des ersten Deals** | `{{trigger.object.closedAt}}` |
| **Kontoinhaber** | `{{trigger.object.owner.id}}` |
### Schritt 5: Onboarding-Aufgabe erstellen
1. Fügen Sie die Aktion **Datensatz erstellen** hinzu
2. Konfigurieren:
| Feld | Wert |
| --------------------------- | ------------------------------------------------------------------------------------------------ |
| **Objekt** | Aufgaben |
| **Titel** | `Onboarding: {{trigger.object.name}}` |
| **Zuständiger** | Mitglied des Customer-Success-Teams |
| **Fälligkeitsdatum** | In 3 Tagen |
| **Priorität** | Hoch |
| **Zugehöriges Unternehmen** | `{{trigger.object.company.id}}` |
| **Zugehörige Opportunity** | `{{trigger.object.id}}` |
| **Beschreibung** | `Neukunden-Onboarding für {{trigger.object.company.name}}. Deal-Wert: {{trigger.object.amount}}` |
### Schritt 6: Customer Success benachrichtigen
1. Fügen Sie eine **E-Mail senden**-Aktion hinzu
2. Konfigurieren:
| Feld | Wert |
| ----------- | ------------------------------------------------- |
| **An** | customer-success@yourcompany.com |
| **Betreff** | `🎉 Neuer Kunde: {{trigger.object.company.name}}` |
| **Inhalt** | Siehe Beispiel unten |
**Beispiel für den E-Mail-Text**:
```
Hi CS Team,
We have a new customer!
Company: {{trigger.object.company.name}}
Deal: {{trigger.object.name}}
Value: {{trigger.object.amount}}
Sales Rep: {{trigger.object.owner.name}}
Close Date: {{trigger.object.closedAt}}
An onboarding task has been created automatically.
Let's give them a great start!
```
### Schritt 7: Bestätigung an Vertriebsmitarbeiter senden
1. Fügen Sie eine weitere **E-Mail senden**-Aktion hinzu
2. Konfigurieren:
| Feld | Wert |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| **An** | `{{trigger.object.owner.email}}` |
| **Betreff** | `✅ Deal abgeschlossen: {{trigger.object.name}}` |
| **Inhalt** | Herzlichen Glückwunsch! Ihr Deal wurde verarbeitet. Das Customer-Success-Team wurde benachrichtigt und das Onboarding hat begonnen. |
### Schritt 8: Testen und aktivieren
1. Testen Sie, indem Sie eine Test-Opportunity auf "Closed Won" verschieben
2. Verifizieren:
* Unternehmenstyp auf "Customer" geändert
* Onboarding-Aufgabe erstellt
* CS-Team hat E-Mail erhalten
* Vertriebsmitarbeiter hat Bestätigung erhalten
3. Aktivieren Sie, sobald alles bereit ist
## Closed Lost behandeln
Erstellen Sie einen ähnlichen Workflow für verlorene Deals:
### Auslöser
* Datensatz wird aktualisiert (Opportunities, Stage = "Closed Lost")
### Aktionen
1. **Datensatz erstellen**: Aufgabe für "Lost Deal Analysis"
2. **Datensatz aktualisieren**: Grund für verlorenen Deal zum Unternehmensdatensatz hinzufügen
3. **E-Mail senden**: Manager über verlorenen Deal benachrichtigen
## Erweitert: Mehrstufiges Onboarding
Für komplexes Onboarding mehrere Aufgaben erstellen:
```javascript
export const main = async (params) => {
const tasks = [
{ title: "Welcome call", daysFromNow: 1, assignee: "CS" },
{ title: "Send onboarding materials", daysFromNow: 2, assignee: "CS" },
{ title: "Technical setup", daysFromNow: 5, assignee: "Support" },
{ title: "30-day check-in", daysFromNow: 30, assignee: "CS" }
];
return { tasks };
};
```
Verwenden Sie **Iterator**, um jede Aufgabe aus dem Array zu erstellen.
## Ideen zur Anpassung
### Halten Sie Ihre anderen Tools auf dem neuesten Stand
* Kunden im Abrechnungssystem per **HTTP Request** erstellen
### Bedingte Aktionen
Verwenden Sie **Filter**-Aktionen, um:
* Unterschiedliches Onboarding für Enterprise vs. SMB
* Unterschiedliche Zuständige je nach Region
* Benachrichtigungen für kleine Deals überspringen
### Deal-Details einbeziehen
Verwenden Sie die **Code**-Aktion, um zu formatieren:
* Dokumente zur Deal-Zusammenfassung
* Übergabenotizen für das CS-Team
* Individuelle Onboarding-Checklisten
## Verwandt
* [Workflow-Aktionen](/l/de/user-guide/workflows/capabilities/workflow-actions)
* [E-Mails aus Workflows senden](/l/de/user-guide/workflows/capabilities/send-emails-from-workflows)

View File

@@ -0,0 +1,136 @@
---
title: Ruhende Gelegenheiten erkennen
description: Manager automatisch benachrichtigen, wenn Gelegenheiten nicht aktualisiert wurden.
---
Halten Sie Ihre Pipeline gesund, indem Sie Manager benachrichtigen, wenn Gelegenheiten ruhend werden. Dieser Workflow prüft Gelegenheiten, die seit einer festgelegten Anzahl von Tagen nicht aktualisiert wurden.
## Das Problem
Nicht aktualisierte Gelegenheiten führen zu:
* Erkaltende Deals
* Unzuverlässige Prognosen
* Entgangener Umsatz
## Die Lösung
Erstellen Sie einen geplanten Workflow, der ruhende Gelegenheiten findet und deren Manager per E-Mail benachrichtigt.
## Schritt-für-Schritt-Einrichtung
### Schritt 1: Workflow erstellen
1. Gehen Sie zu **Einstellungen → Workflows**
2. Klicken Sie auf **+ Neuer Workflow**
3. Benennen Sie ihn "Benachrichtigung für ruhende Gelegenheiten"
### Schritt 2: Trigger konfigurieren
1. Wählen Sie **Nach Zeitplan**
2. Auf täglich festlegen (z. B. jeden Tag um 8 Uhr)
### Schritt 3: Nach ruhenden Gelegenheiten suchen
1. Fügen Sie die Aktion **Datensätze suchen** hinzu
2. Konfigurieren:
| Feld | Wert |
| ---------- | ---------------------------------------------------- |
| **Objekt** | Opportunities |
| **Filter** | Aktualisiert am ist vor (heute - 7 Tage) |
| **Filter** | Phase ist nicht "Closed Won" UND nicht "Closed Lost" |
| **Limit** | 100 |
### Schritt 4: Prüfen, ob Einträge gefunden wurden
1. Fügen Sie eine **Filter**-Aktion hinzu
2. Bedingung: `{{searchRecords.length}}` ist größer als 0
3. Wenn keine ruhenden Gelegenheiten vorhanden sind, endet der Workflow hier
### Schritt 5: Benachrichtigung formatieren (Code-Aktion)
Fügen Sie eine **Code**-Aktion hinzu, um die E-Mail zu formatieren:
```javascript
export const main = async (params) => {
const opportunities = params.opportunities;
// Group opportunities by owner
const byOwner = {};
opportunities.forEach(opp => {
const ownerEmail = opp.owner?.email || 'unassigned';
if (!byOwner[ownerEmail]) {
byOwner[ownerEmail] = [];
}
byOwner[ownerEmail].push({
name: opp.name,
amount: opp.amount,
lastUpdated: opp.updatedAt,
stage: opp.stage
});
});
// Format summary for manager
let summary = "Stale Opportunities Report\n\n";
Object.entries(byOwner).forEach(([owner, opps]) => {
summary += `${owner}: ${opps.length} stale opportunities\n`;
opps.forEach(opp => {
summary += ` - ${opp.name} (${opp.stage})\n`;
});
summary += "\n";
});
return {
summary,
totalCount: opportunities.length
};
};
```
### Schritt 6: Benachrichtigungs-E-Mail senden
Fügen Sie eine **E-Mail senden**-Aktion hinzu:
| Feld | Wert |
| ----------- | ----------------------------------------------------------------------- |
| **An** | sales-manager@yourcompany.com |
| **Betreff** | `🚨 {{code.totalCount}} ruhende Gelegenheiten erfordern Aufmerksamkeit` |
| **Inhalt** | `{{code.summary}}` |
### Schritt 7: Testen und aktivieren
1. Klicken Sie auf **Test**, um den Workflow auszuführen
2. Überprüfen Sie, dass die E-Mail die richtigen Daten enthält
3. Aktivieren Sie, sobald alles bereit ist
## Anpassungsoptionen
### Schwellenwert für Inaktivität ändern
Passen Sie den Filter der Aktion Datensätze suchen an, um statt 7 Tagen Ihren bevorzugten Zeitraum zu verwenden:
* 3 Tage für schnelllebige Verkäufe
* 14 Tage für Enterprise-Deals
* 30 Tage für lange Verkaufszyklen
### Einzelne Vertriebsmitarbeiter benachrichtigen
Verwenden Sie statt einer einzelnen Manager-E-Mail den **Iterator**, um jedem Vertriebsmitarbeiter personalisierte E-Mails zu seinen eigenen ruhenden Deals zu senden.
### Eskalation hinzufügen
Erstellen Sie mehrere Workflows mit zunehmender Dringlichkeit:
1. Tag 7: E-Mail an den Vertriebsmitarbeiter
2. Tag 14: E-Mail an Vertriebsmitarbeiter + Manager
3. Tag 21: Aufgabe für den Manager erstellen, um einzugreifen
### In Slack einbinden
Verwenden Sie **HTTP Request**, um an einen Slack-Webhook zu posten, anstelle von oder zusätzlich zu E-Mail.
## Verwandt
* [Workflow-Aktionen](/l/de/user-guide/workflows/capabilities/workflow-actions)
* [E-Mails aus Workflows senden](/l/de/user-guide/workflows/capabilities/send-emails-from-workflows)

View File

@@ -0,0 +1,69 @@
---
title: Anzahl empfangener E-Mails anzeigen
description: Erstellen Sie einen Workflow, der automatisch die Anzahl der von jedem Kontakt empfangenen E-Mails zählt und anzeigt.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
<img src="/images/user-guide/workflows/workflow-number-of-emails-received.png" style={{width:'100%'}} />
## Übersicht
Dieser Workflow wird jedes Mal ausgelöst, wenn eine neue E-Mail eingeht, und aktualisiert ein benutzerdefiniertes Feld im Personendatensatz mit der Gesamtanzahl der E-Mails dieses Absenders.
## Voraussetzungen
Erstellen Sie vor der Einrichtung dieses Workflows ein benutzerdefiniertes Feld am Objekt **People**:
1. Gehen Sie zu **Einstellungen → Datenmodell → People**
2. Fügen Sie ein neues Feld vom Typ **Number** hinzu
3. Nennen Sie es etwa "Anzahl der von dieser Person empfangenen E-Mails"
## Schritt-für-Schritt-Einrichtung
<VimeoEmbed videoId="1148700336" title="Video-Demonstration" />
### Schritt 1: Trigger konfigurieren
1. Gehen Sie zu **Workflows** und erstellen Sie einen neuen Workflow
2. Wählen Sie **Record is Created** als Auslöser
3. Wählen Sie **Message Participants** (verfügbar unter Advanced objects)
<Note>
Ein Message Participant ist eine Kombination aus einer Nachrichten-ID und einer Personen-ID und erzeugt einen eindeutigen Datensatz pro Nachricht. Dies ist einfacher nachzuverfolgen als die Nachrichten direkt, da wir auf das Feld `handle` zugreifen können, das die E-Mail-Adresse des Absenders (oder Empfängers) enthält.
</Note>
### Schritt 2: Nach Rolle filtern
1. Fügen Sie eine **Filter**-Aktion hinzu
2. Legen Sie die Bedingung fest: **Role** ist gleich **FROM**
So stellen Sie sicher, dass Sie nur Nachrichten zählen, die von dieser Person gesendet wurden, nicht Nachrichten, die an sie gesendet wurden.
### Schritt 3: Alle Message Participants mit demselben Handle suchen
1. Fügen Sie eine **Datensätze suchen**-Aktion hinzu
2. Wählen Sie **Message Participants** als Objekt
3. Fügen Sie Filter hinzu: **Handle** entspricht dem Handle aus dem Trigger (der E-Mail-Adresse des Absenders) und **Role** ist gleich **FROM**
4. Erhöhen Sie das **Limit** von 1 auf **200** (das Maximum)
Dadurch werden alle Nachrichten von dieser E-Mail-Adresse gefunden, um die Gesamtanzahl zu erhalten.
<Note>
Die Aktion Datensätze suchen ist auf die Rückgabe von maximal 200 Datensätzen beschränkt. Da Sie jedoch nur den Wert `totalCount` verwenden (nicht die einzelnen Datensätze), liefert dieser Schritt die Gesamtanzahl der von dieser Person gesendeten E-Mails.
</Note>
### Schritt 4: Den Personendatensatz mit einer Create or Update Record-Aktion aktualisieren
1. Fügen Sie eine **Create or Update Record**-Aktion hinzu
2. Wählen Sie **People** als Objekt
3. Finden Sie die Person, indem Sie ihre E-Mail-Adresse mit dem `handle` des Message Participant abgleichen.
4. Setzen Sie Ihr benutzerdefiniertes Feld "Anzahl empfangener E-Mails" auf `{{searchRecords.totalCount}}`
Der Wert `totalCount` aus der Aktion Datensätze suchen steht für die Gesamtanzahl der von dieser Person empfangenen E-Mails.
## Verwandt
* [Workflow-Aktionen](/l/de/user-guide/workflows/capabilities/workflow-actions)
* [Benutzerdefinierte Felder erstellen](/l/de/user-guide/data-model/how-tos/customize-your-data-model)
* [Aktion Datensätze suchen](/l/de/user-guide/workflows/capabilities/workflow-actions#search-records)

View File

@@ -0,0 +1,170 @@
---
title: Daten verknüpfter Datensätze anzeigen
description: Zeigen Sie mithilfe von Workflows Daten aus verknüpften Datensätzen an (z. B. Unternehmensinformationen in Opportunities).
---
Zeigen Sie Daten aus verknüpften Datensätzen direkt in Ihren Datensätzen an — zum Beispiel die Mitarbeiterzahl eines Unternehmens in dessen Opportunities. Dieser Workflow-Workaround ist hilfreich, bis verschachtelte Felder nativ verfügbar sind.
## Häufige Anwendungsfälle
| Quelle | Ziel | Zu kopierende Felder |
| ----------- | ----------- | --------------------------------------------------- |
| Unternehmen | Opportunity | Branche, Unternehmensgröße, ARR |
| Person | Opportunity | E-Mail, Telefon, Position |
| Opportunity | Unternehmen | Betrag des letzten Deals, Datum des letzten Gewinns |
## Einfache Feldkopie
### Beispiel: Kontakt-E-Mail in die Opportunity kopieren
**Ziel**: Wenn bei einer Opportunity ein Ansprechpartner festgelegt wird, soll dessen E-Mail für den schnellen Zugriff in die Opportunity kopiert werden.
### Voraussetzung
Erstellen Sie die Zielfelder in **Settings → Data Model → Opportunities**, bevor Sie den Workflow erstellen:
* Kontakt-E-Mail (Typ: E-Mail)
* Kontakt-Telefon (Typ: Telefon)
### Einrichtung
1. **Auslöser**: Datensatz wird aktualisiert (Opportunities, Feld Ansprechpartner)
2. **Filter**: Prüfen, dass der Ansprechpartner nicht leer ist
3. **Datensätze durchsuchen**: Verknüpfte Person finden
* Objekt: People
* Filter: ID entspricht `{{trigger.object.pointOfContact.id}}`
4. **Datensatz aktualisieren**:
* Objekt: Opportunities
* Datensatz: `{{trigger.object.id}}`
* Kontakt-E-Mail: `{{searchRecords[0].email}}`
* Kontakt-Telefon: `{{searchRecords[0].phone}}`
## Mehrere Felder kopieren
### Beispiel: Unternehmensinformationen mit allen verknüpften Opportunities synchronisieren
**Ziel**: Wenn sich Unternehmensdetails ändern, alle verknüpften Opportunities aktualisieren.
### Einrichtung
1. **Auslöser**: Datensatz wird aktualisiert (Companies)
* Felder: Branche, Unternehmensgröße, Jahresumsatz
2. **Datensätze durchsuchen**: Alle Opportunities für dieses Unternehmen finden
* Objekt: Opportunities
* Filter: Unternehmens-ID entspricht `{{trigger.object.id}}`
3. **Iterator**: Jede Opportunity durchlaufen
4. **Datensatz aktualisieren** (innerhalb des Iterators):
* Objekt: Opportunities
* Datensatz: `{{iterator.currentItem.id}}`
* Unternehmensbranche: `{{trigger.object.industry}}`
* Unternehmensgröße: `{{trigger.object.companySize}}`
* Unternehmens-ARR: `{{trigger.object.annualRevenue}}`
## Kopieren bei der Datensatzerstellung
### Beispiel: Opportunity mit Unternehmensdaten vorbefüllen
**Ziel**: Beim Erstellen einer Opportunity, die mit einem Unternehmen verknüpft ist, werden wichtige Unternehmensinformationen automatisch kopiert.
### Voraussetzung
Erstellen Sie die Zielfelder in **Settings → Data Model → Opportunities**:
* Unternehmensbranche (Typ: Text)
* Unternehmensgröße (Typ: Zahl)
### Einrichtung
1. **Auslöser**: Datensatz wird erstellt (Opportunities)
* Filter: Unternehmen ist nicht leer
2. **Datensätze durchsuchen**: Details des verknüpften Unternehmens abrufen
* Objekt: Companies
* Filter: ID entspricht `{{trigger.object.company.id}}`
3. **Datensatz aktualisieren**:
* Objekt: Opportunities
* Datensatz: `{{trigger.object.id}}`
* Unternehmensbranche: `{{searchRecords[0].industry}}`
* Unternehmensgröße: `{{searchRecords[0].employees}}`
<Note>
**Einschränkung bei Aufgaben und Notizen**: Beziehungen bei Aufgaben und Notizen sind fest als Viele-zu-Viele implementiert und stehen in Workflow-Auslösern oder -Aktionen noch nicht zur Verfügung. Um auf diese Beziehungen zuzugreifen, verwenden Sie stattdessen die [API](/l/de/developers/extend/api).
</Note>
## Bidirektionale Synchronisierung
### Beispiel: Hauptansprechpartner synchron halten
**Ziel**: Wenn sich der Hauptansprechpartner eines Unternehmens ändert, den Kontakt aktualisieren. Wenn eine Person zum Hauptansprechpartner wird, das Unternehmen aktualisieren.
### Workflow 1: Unternehmen → Person
1. **Auslöser**: Datensatz wird aktualisiert (Companies, Feld Hauptansprechpartner)
2. **Datensatz aktualisieren**: Beim Kontakt "Is Primary Contact" auf true setzen
3. **Datensätze durchsuchen**: Vorherigen Hauptansprechpartner finden
4. **Datensatz aktualisieren**: Beim vorherigen Kontakt "Is Primary Contact" auf false setzen
### Workflow 2: Person → Unternehmen
1. **Auslöser**: Datensatz wird aktualisiert (People, Is Primary Contact = true)
2. **Datensatz aktualisieren**: Den Hauptansprechpartner des Unternehmens auf diese Person setzen
<Note>
Seien Sie bei bidirektionalen Synchronisierungen vorsichtig, um Endlosschleifen zu vermeiden. Verwenden Sie Filter, um vor dem Aktualisieren zu prüfen, ob sich der Wert tatsächlich geändert hat.
</Note>
## Code für komplexe Zuordnungen verwenden
### Beispiel: Daten beim Kopieren transformieren
**Ziel**: Telefonnummer von Person zur Opportunity kopieren und formatieren.
```javascript
export const main = async (params) => {
const { phone } = params;
if (!phone) return { formattedPhone: null };
// Remove non-numeric characters
const digits = phone.replace(/\D/g, '');
// Format as (XXX) XXX-XXXX
const formatted = digits.length === 10
? `(${digits.slice(0,3)}) ${digits.slice(3,6)}-${digits.slice(6)}`
: phone;
return { formattedPhone: formatted };
};
```
## Beste Praktiken
### Schleifen vermeiden
* Erstellen Sie keine Workflows, die sich gegenseitig endlos auslösen
* Spezifische Feldbedingungen verwenden
* Prüfungen hinzufügen, ob sich der Wert tatsächlich geändert hat
### Fehlende Daten behandeln
* Vor dem Kopieren stets prüfen, ob der Quelldatensatz existiert
* Standardwerte für optionale Felder bereitstellen
* Filter verwenden, um zu überspringen, wenn das Quellfeld leer ist
### Leistung
* Updates bündeln, wenn in viele Datensätze kopiert wird
* Geplante Workflows für Massensynchronisierungen verwenden
* Erwägen Sie die Verwendung von Iterator für mehrere Datensatzaktualisierungen
## Verwandt
* [Workflow-Aktionen](/l/de/user-guide/workflows/capabilities/workflow-actions)
* [Workflow-Trigger](/l/de/user-guide/workflows/capabilities/workflow-triggers)

View File

@@ -0,0 +1,202 @@
---
title: Formelfelder
description: Erstellen Sie Formelfelder mithilfe von Workflows, bis native Unterstützung verfügbar ist.
---
Zwanzig unterstützen noch keine Formelfelder (ab 2026), aber Sie können das gleiche Ergebnis mit Workflows erzielen. Mit diesem Workaround können Sie Feldwerte automatisch berechnen und ausfüllen – von einfachen Verkettungen bis hin zu komplexer Geschäftslogik.
## Häufige Anwendungsfälle
| Anwendungsfall | Formelbeispiel |
| --------------------------- | --------------------------------------- |
| **Vollständiger Name** | Vorname + " " + Nachname |
| **Erwarteter Betrag** | Betrag × Wahrscheinlichkeit |
| **Tage bis zur Fälligkeit** | Fälligkeitsdatum - Heute |
| **Tage in der Phase** | Heute - Phaseneintrittsdatum |
| **Lead-Score** | Punkte basierend auf mehreren Kriterien |
<Tip>
Ein vollständiges Beispiel für das Nachverfolgen der Zeit in Pipeline-Phasen finden Sie unter [Verfolgen, wie lange Chancen in jeder Phase bleiben](/l/de/user-guide/views-pipelines/how-tos/track-time-in-stage).
</Tip>
## Einfache Formel: Verkettung
### Beispiel: Vollständigen Namen automatisch ausfüllen
**Ziel**: Vor- und Nachname automatisch zu einem Feld für den vollständigen Namen kombinieren.
### Einrichtung
1. **Auslöser**: Datensatz wird aktualisiert oder erstellt (Personen)
2. **Filter**: Prüfen, ob sich Vorname oder Nachname geändert hat
3. **Code-Aktion**:
```javascript
export const main = async (params) => {
const { firstName, lastName } = params;
const fullName = [firstName, lastName]
.filter(Boolean)
.join(' ');
return { fullName };
};
```
4. **Datensatz aktualisieren**: Vollständigen Namen auf `{{code.fullName}}` setzen
## Numerische Formel: Erwarteter Betrag
### Beispiel: Erwarteten Umsatz berechnen
**Ziel**: Den Chancenbetrag mit der Wahrscheinlichkeit multiplizieren, um den erwarteten Betrag zu erhalten.
Den vollständigen Workflow finden Sie unter [Erwarteten Betrag in der Pipeline anzeigen](/l/de/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline).
### Einrichtung
1. **Auslöser**: Datensatz wird aktualisiert (Chancen, Feld Betrag ODER Wahrscheinlichkeit)
2. **Code-Aktion**:
```javascript
export const main = async (params) => {
const { amount, probability } = params;
const expectedAmount = (amount || 0) * (probability || 0) / 100;
return { expectedAmount };
};
```
3. **Datensatz aktualisieren**: Erwarteten Betrag auf `{{code.expectedAmount}}` setzen
## Datumsformel: Tagesberechnung
### Beispiel: Tage bis zur Fälligkeit einer Aufgabe
**Ziel**: Berechnen, wie viele Tage bis zum Fälligkeitsdatum einer Aufgabe verbleiben.
### Einrichtung
1. **Auslöser**: Datensatz wird aktualisiert oder erstellt (Aufgaben, Feld Fälligkeitsdatum)
2. **Code-Aktion**:
```javascript
export const main = async (params) => {
const { dueDate } = params;
if (!dueDate) {
return { daysUntilDue: null };
}
const due = new Date(dueDate);
const today = new Date();
const diffTime = due - today;
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return { daysUntilDue: diffDays };
};
```
3. **Datensatz aktualisieren**: Tage bis zur Fälligkeit auf `{{code.daysUntilDue}}` setzen
<Note>
Negative Werte weisen auf überfällige Aufgaben hin. Sie können dieses Feld verwenden, um Aufgaben nach Dringlichkeit zu filtern oder zu sortieren.
</Note>
## Bedingte Formel: Lead-Score
### Beispiel: Lead-Score anhand von Kriterien berechnen
**Ziel**: Leads anhand von Unternehmensgröße, Branche und Engagement bewerten.
### Einrichtung
1. **Auslöser**: Datensatz wird aktualisiert (Personen oder Unternehmen)
2. **Code-Aktion**:
```javascript
export const main = async (params) => {
const { companySize, industry, hasEmail, hasPhone, source } = params;
let score = 0;
// Company size scoring
if (companySize === 'Enterprise') score += 30;
else if (companySize === 'Mid-Market') score += 20;
else if (companySize === 'SMB') score += 10;
// Industry scoring
const targetIndustries = ['Technology', 'Finance', 'Healthcare'];
if (targetIndustries.includes(industry)) score += 25;
// Contact info scoring
if (hasEmail) score += 10;
if (hasPhone) score += 15;
// Source scoring
if (source === 'Referral') score += 20;
else if (source === 'Website') score += 10;
return { leadScore: score };
};
```
3. **Datensatz aktualisieren**: Lead-Score auf `{{code.leadScore}}` setzen
## Textformel: Domain-Extraktion
### Beispiel: Domain aus E-Mail extrahieren
**Ziel**: Die E-Mail-Domain automatisch extrahieren und speichern.
### Einrichtung
1. **Auslöser**: Datensatz wird aktualisiert (Personen, E-Mail-Feld)
2. **Code-Aktion**:
```javascript
export const main = async (params) => {
const { email } = params;
if (!email) return { domain: null };
const domain = email.split('@')[1]?.toLowerCase();
return { domain };
};
```
3. **Datensatz aktualisieren**: Feld Domain auf `{{code.domain}}` setzen
## Beste Praktiken
### Leistung
* Nur bei relevanten Feldänderungen auslösen
* Filter verwenden, um Datensätze ohne Berechnungsbedarf zu überspringen
* Komplexe Berechnungen in Workflows mit hohem Volumen vermeiden
### Fehlerbehandlung
* Vor Berechnungen auf null/undefined-Werte prüfen
* Standardwerte verwenden, wenn Daten fehlen
* Klare Fehlermeldungen zurückgeben, wenn Berechnungen fehlschlagen
### Tests
* Mit Randfällen testen (leere Felder, Nullwerte)
* Berechnungen vor der Aktivierung manuell überprüfen
* Workflow-Ausführungen auf unerwartete Ergebnisse überwachen
## Verwandt
* [Erwarteten Betrag in der Pipeline anzeigen](/l/de/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline)
* [Zeit in der Phase nachverfolgen](/l/de/user-guide/views-pipelines/how-tos/track-time-in-stage)
* [Workflow-Aktionen](/l/de/user-guide/workflows/capabilities/workflow-actions)

View File

@@ -0,0 +1,127 @@
---
title: Teammitglieder über eine zu prüfende Notiz benachrichtigen
description: Senden Sie automatische E-Mail-Benachrichtigungen, wenn Sie einem Kollegen die Überprüfung einer Notiz zuweisen.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
<Note>
**Das direkte Taggen von Teammitgliedern in Notizen wird noch nicht unterstützt.** Diese Funktion ist für die zweite Jahreshälfte 2026 geplant. In der Zwischenzeit bietet dieser Workflow einen praktischen Workaround.
</Note>
## Die Herausforderung
Sie möchten einen Kollegen in einer Notiz taggen, damit er eine Benachrichtigung zur Überprüfung erhält. Derzeit unterstützt Twenty keine @-Erwähnungen in Notizen oder Aufgaben.
## Der Workaround
Anstatt im Notiztext zu taggen, können Sie:
1. Erstellen Sie ein **Reviewer**-Beziehungsfeld im Objekt Notizen
2. Weisen Sie den Reviewer beim Erstellen oder Bearbeiten der Notiz zu
3. Lassen Sie einen Workflow automatisch eine E-Mail an den Prüfer mit einem Link zur Notiz senden
<Warning>
**Einschränkung**: Mit diesem Ansatz kann pro Feld nur ein Reviewer zugewiesen werden. Wenn Sie mehrere Personen benachrichtigen müssen, erstellen Sie zusätzliche Beziehungsfelder (z. B. Reviewer 1, Reviewer 2). Das skaliert nicht gut, wenn Sie viele Teammitglieder auf einmal taggen müssen.
</Warning>
## Schritt-für-Schritt-Einrichtung
### Schritt 1: Reviewer-Feld erstellen
<img src="/images/user-guide/workflows/reviewer-field-for-note.png" style={{width:'100%'}} />
1. Gehen Sie zu **Einstellungen → Datenmodell → Notizen**
2. Klicken Sie auf **Feld hinzufügen**
3. Konfigurieren:
| Einstellung | Wert |
| ---------------------- | ------------------------------------------- |
| **Name** | Reviewer |
| **Typ** | Beziehung |
| **Verknüpftes Objekt** | Arbeitsbereichsmitglied |
| **Beziehungstyp** | Viele Notizen → Ein Arbeitsbereichsmitglied |
4. Speichern Sie das Feld
### Schritt 2: Workflow erstellen
<VimeoEmbed videoId="1151897168" title="Video-Demonstration" />
#### Workflow-Trigger erstellen
1. Gehen Sie zur Hauptansicht und erstellen Sie einen neuen Workflow
2. Wählen Sie **Record Updated** als Auslöser
3. Wählen Sie **Note** als Objekt und geben Sie das Reviewer-Feld an.
4. Dadurch wird der Workflow immer dann ausgelöst, wenn der Reviewer einer Notiz aktualisiert wird.
#### Filter hinzufügen, um zu prüfen, ob der Reviewer gerade zugewiesen wurde
Fügen Sie eine **Filter**-Aktion hinzu, damit der Workflow nur fortgesetzt wird, wenn ein Reviewer zugewiesen ist:
| Bedingung | Wert |
| ------------ | -------------- |
| **Reviewer** | ist nicht leer |
#### Nach dem Arbeitsbereichsmitglied suchen
1. Fügen Sie eine **Datensätze suchen**-Aktion hinzu
2. Wählen Sie **Arbeitsbereichsmitglied** (unter Erweiterten Objekten)
3. Fügen Sie einen Filter hinzu:
| Bedingung | Wert |
| --------- | -------------------------------- |
| **ID** | entspricht `{{note.reviewerId}}` |
Dadurch wird der vollständige Datensatz des Arbeitsbereichsmitglieds abgerufen, einschließlich der E-Mail-Adresse und des Namens.
#### Benachrichtigungs-E-Mail senden
1. Fügen Sie eine **E-Mail senden**-Aktion hinzu
2. Konfigurieren:
| Feld | Wert |
| ----------- | ------------------------------------------------------------------- |
| **An** | Datensatz suchen → Erstes Arbeitsbereichsmitglied → Benutzer-E-Mail |
| **Betreff** | Eine Notiz benötigt Ihre Überprüfung |
| **Inhalt** | Siehe Beispiel unten |
**Beispiel für den E-Mail-Text:**
```text
Hi {{searchRecord.firstWorkspaceMember.name.firstName}},
You've been assigned to review a note.
View the note here:
https://yourSubDomain.twenty.com/object/note/{{recordIsUpdated.id}}
Best,
Twenty
```
<Note>
Ersetzen Sie `yourSubDomain` durch die tatsächliche Subdomain Ihres Twenty-Arbeitsbereichs.
</Note>
#### Testen und Aktivieren
1. Klicken Sie auf **Test**, um den Workflow manuell auszuführen
2. Erstellen oder bearbeiten Sie eine Notiz und weisen Sie einen Reviewer zu
3. Prüfen Sie den Posteingang des Reviewers auf die Benachrichtigungs-E-Mail
4. Aktivieren Sie den Workflow
## Verwendung
Sobald eingerichtet, kann Ihr Team diesen Workflow wie folgt verwenden:
1. Erstellen einer neuen Notiz (oder Bearbeiten einer bestehenden)
2. Auswählen eines Kollegen im Feld **Reviewer**
3. Der Kollege erhält automatisch eine E-Mail mit einem direkten Link zur Notiz
## Verwandt
* [Workflow-Trigger](/l/de/user-guide/workflows/capabilities/workflow-triggers)
* [E-Mails aus Workflows senden](/l/de/user-guide/workflows/capabilities/send-emails-from-workflows)
* [Benutzerdefinierte Felder erstellen](/l/de/user-guide/data-model/how-tos/create-custom-fields)
* [Beziehungsfelder erstellen](/l/de/user-guide/data-model/how-tos/create-relation-fields)

View File

@@ -0,0 +1,106 @@
---
title: E-Mail-Benachrichtigungen zu fälligen Aufgaben senden
description: Benachrichtigen Sie Teammitglieder automatisch über ihre anstehenden oder überfälligen Aufgaben.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
<img src="/images/user-guide/workflows/email_tasks_due.png" style={{width:'100%'}} />
Senden Sie tägliche E-Mail-Erinnerungen an jedes Teammitglied zu den heute fälligen Aufgaben.
## Übersicht
Dieser Workflow läuft nach einem Zeitplan und:
1. Ruft alle Mitglieder des Arbeitsbereichs ab
2. Durchläuft jedes Mitglied
3. Ermittelt deren heute fällige Aufgaben
4. Formatiert und sendet eine personalisierte E-Mail
## Schritt-für-Schritt-Einrichtung
<VimeoEmbed videoId="1147463514" title="Video-Demonstration" />
### Schritt 1: Trigger konfigurieren
1. Gehen Sie zu **Einstellungen → Workflows** und erstellen Sie einen neuen Workflow
2. Wählen Sie **Nach Zeitplan** als Trigger
3. Verwenden Sie einen Cron-Ausdruck für täglich um 8:00 Uhr: `0 8 * * *`
### Schritt 2: Nach allen Arbeitsbereichsmitgliedern suchen
1. Fügen Sie eine **Datensätze suchen**-Aktion hinzu
2. Wählen Sie **Arbeitsbereichsmitglieder** (unter Erweiterten Objekten)
3. Keine Filter erforderlich — dadurch werden alle Mitglieder zurückgegeben
### Schritt 3: Einen Iterator hinzufügen
1. Fügen Sie eine **Iterator**-Aktion hinzu
2. Setzen Sie das Eingabearray auf die Arbeitsbereichsmitglieder aus dem vorherigen Schritt
3. Alle Aktionen innerhalb des Iterators werden einmal pro Mitglied ausgeführt
### Schritt 4: Nach heute fälligen Aufgaben suchen (im Iterator)
1. Fügen Sie im Iterator eine **Datensätze suchen**-Aktion hinzu
2. Wählen Sie **Aufgaben** als Objekt
3. Filter hinzufügen:
* **Zuständige Person** = aktuelles Arbeitsbereichsmitglied (aus dem Iterator)
* **Fälligkeitsdatum** = heute
### Schritt 5: Aufgaben in E-Mail-Inhalt formatieren (im Iterator)
Fügen Sie eine **Code**-Aktion hinzu, um die Aufgaben in eine lesbare Liste mit Links zu formatieren:
```javascript
export const main = async (params: {
tasksDue?: Array<{ id: string; title: string }> | null | string;
}) => {
const tasksDue =
typeof params.tasksDue === "string"
? JSON.parse(params.tasksDue)
: params.tasksDue;
if (!Array.isArray(tasksDue) || tasksDue.length === 0) {
return {
formattedTasks: "No tasks due today."
};
}
const formattedTasks = tasksDue
.map(
t =>
`${t.title}\nhttps://yourSubDomain.twenty.com/object/task/${t.id}`
)
.join("\n\n");
return { formattedTasks };
};
```
<Note>
Ersetzen Sie `yourSubDomain` durch die tatsächliche Twenty-Arbeitsbereichs-Subdomain.
</Note>
### Schritt 6: E-Mail senden (im Iterator)
1. Fügen Sie eine **E-Mail senden**-Aktion hinzu (weiterhin im Iterator)
2. Konfigurieren:
| Feld | Wert |
| ----------- | ---------------------------------------------------------------------------------- |
| **An** | `{{iterator.currentItem.userEmail}}` (E-Mail-Adresse des Arbeitsbereichsmitglieds) |
| **Betreff** | Ihre heute fälligen Aufgaben |
| **Inhalt** | `{{code.formattedTasks}}` |
### Schritt 7: Testen und aktivieren
1. Klicken Sie auf **Test**, um den Workflow manuell auszuführen
2. Überprüfen Sie die Posteingänge auf E-Mails
3. Aktivieren Sie den Workflow
## Verwandt
* [Workflow-Aktionen](/l/de/user-guide/workflows/capabilities/workflow-actions)
* [E-Mails aus Workflows senden](/l/de/user-guide/workflows/capabilities/send-emails-from-workflows)
* [Arrays in Code-Aktionen verarbeiten](/l/de/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions)