trypost/lang/nl/automations.php
Paulo Castellano 58d8e066b5
Add workspace webhooks and drop the unused automation webhook node (#326)
* Add workspace webhooks and drop the unused automation webhook node.

Give workspaces HMAC-signed outgoing webhooks for the post lifecycle, with retry, auto-pause, replay, and live logs, and keep HTTP Request as the only outbound automation node.

* Tighten webhook controller and validation after review.

Drop the redundant workspace redirects, prune logs without counting, and validate events/status with Rule::enum.

* Move leftover webhook UI copy behind i18n.

HTTP status phrases, delete-cancel, and validation attribute names were still English literals.

* Build the webhook-paused email through Maizzle.

The hand-written Blade skipped the shared layout, header, and footer used by the other mail templates.

* Cover real webhook dispatch paths and restyle the webhook pages.

* Ask for the shared delete keyword when confirming a webhook delete.

The endpoint URL is a poor confirm string; posts and assets already use the common "delete" keyword.

* Fix webhook review blockers so CI can go green.

Drop leftover French automation keys, stop mutating Inertia log props, and show delivered_at instead of created_at.

* Close the remaining webhook review gaps.

Keep Echo log updates across infinite scroll, align the channel with the policy, persist log ids across retries, and fail unknown automation nodes without throwing.

* Stop webhook delivery after disable and record last sent only on success.

Queued jobs now skip paused or disabled endpoints unless the user replays, and changing the URL re-pings it first.

* Limit webhooks to owners and admins, and encrypt signing secrets.

Members can no longer create or inspect outgoing integrations, and secrets stay encrypted at rest.

* Cover webhook secret hiding, skip-ping, and failed-delivery edges.

* Send the full post on webhooks after labels and platforms are saved.

* Fix webhook payloads for integer media ids and type webhook status.

* Split the webhook show page into focused components.

* Reset live webhook logs when switching endpoints.

* Keep the newest webhook logs at the top after live merges.

* Cast media item ids to string without the extra scalar check.

* Add post.unscheduled webhooks and put the log id on the envelope.

Unscheduling is now a first-class event, and receivers can send the delivery id back so we can find the matching log.

* Translate webhook event names in the UI.

* Make the webhook show page full-width and stop stacking flash toasts.

* Translate remaining webhook UI copy in every locale.

* Sign webhook pings and drop author email from the payload.

* Send signed webhook tests after create instead of pinging on save.

Create and update only block private URLs so the receiver can copy the secret first. The show page then sends a signed webhook.test with an object data envelope.

* Polish webhook test UX and always mint the dispatch log id in the job.

Keep send-test in the actions menu (its own group) and drop the leftover constructor param so retries reuse the serialized id instead of a caller-supplied one.
2026-09-04 09:43:29 -03:00

402 lines
18 KiB
PHP

<?php
declare(strict_types=1);
return [
'mobile_notice' => 'De automatiserings-editor werkt het best op een groter scherm. Open het op een desktop om je workflow te bouwen.',
'title' => 'Automatiseringen',
'default_name' => 'Nieuwe automatisering',
'actions' => [
'new' => 'Nieuwe automatisering',
'edit' => 'Bewerken',
'save' => 'Opslaan',
'activate' => 'Activeren',
'pause' => 'Pauzeren',
'delete' => 'Verwijderen',
'retry' => 'Opnieuw proberen',
'guide' => 'Ontdek hoe het werkt',
],
'tabs' => [
'build' => 'Bouwen',
'variables' => 'Variabelen',
'test' => 'Testen',
],
'nav' => [
'workflow' => 'Workflow',
'invocations' => 'Uitvoeringen',
'metrics' => 'Statistieken',
'settings' => 'Instellingen',
],
'settings' => [
'general' => 'Algemeen',
'general_description' => 'Wijzig de naam van deze automatisering.',
'name_label' => 'Naam',
'name_saved' => 'Automatisering hernoemd.',
'status_title' => 'Status',
'status_description' => 'Activeer om te starten, of pauzeer om te stoppen.',
'activated_at' => 'Geactiveerd :date',
'paused_at' => 'Gepauzeerd :date',
'created_at' => 'Aangemaakt :date',
'danger_title' => 'Gevarenzone',
'danger_description' => 'Onomkeerbare acties.',
'delete_title' => 'Deze automatisering verwijderen',
'delete_description' => 'Verwijdert de automatisering en de uitvoeringsgeschiedenis permanent.',
],
'status_run' => [
'pending' => 'In afwachting',
'running' => 'Bezig',
'waiting' => 'Wachten',
'completed' => 'Voltooid',
'failed' => 'Mislukt',
'cancelled' => 'Geannuleerd',
],
'node_type' => [
'trigger' => 'Trigger',
'generate' => 'Content genereren',
'delay' => 'Vertraging',
'condition' => 'Voorwaarde',
'publish' => 'Publiceren',
'end' => 'Einde',
'fetch_rss' => 'RSS ophalen',
'http_request' => 'HTTP-verzoek',
],
'invocations' => [
'empty' => 'Nog geen uitvoeringen.',
'refresh' => 'Vernieuwen',
'search_placeholder' => 'Zoeken op uitvoerings-ID…',
'copied' => 'Uitvoerings-ID gekopieerd.',
'loading' => 'Stappen laden…',
'no_steps' => 'Geen stappen geregistreerd.',
'load_error' => 'Kon de stappen niet laden.',
'steps' => '{0}Geen stappen|{1}:count stap|[2,*]:count stappen',
'filter' => [
'all' => 'Alle statussen',
],
'columns' => [
'timestamp' => 'Tijdstip',
'run' => 'Uitvoering',
'status' => 'Status',
'message' => 'Laatste bericht',
'duration' => 'Duur',
],
'summary' => [
'completed' => 'Workflow voltooid',
'failed' => 'Workflow mislukt',
'running' => 'Workflow bezig',
'cancelled' => 'Workflow geannuleerd',
'pending' => 'Workflow in afwachting',
],
],
'metrics' => [
'overview' => 'Overzicht',
'runs_over_time' => 'Uitvoeringen in de tijd',
'posts_by_platform' => 'Posts per platform',
'no_posts' => 'Geen posts gepubliceerd in deze periode.',
'cards' => [
'runs' => 'Totaal uitvoeringen',
'completed' => 'Voltooid',
'failed' => 'Mislukt',
'in_progress' => 'Bezig',
'success_rate' => 'Slagingspercentage',
'avg_duration' => 'Gem. duur',
'posts_created' => 'Posts aangemaakt',
],
'legend' => [
'started' => 'Gestart',
'completed' => 'Voltooid',
'failed' => 'Mislukt',
],
],
'categories' => [
'sources' => 'Bronnen',
'content' => 'Content',
'flow' => 'Flow',
'output' => 'Uitvoer',
],
'variables' => [
'title' => 'Workflowvariabelen',
'hint' => 'Herbruikbare waarden die je overal kunt gebruiken met {{ variables.KEY }}. Versleuteld opgeslagen.',
'empty' => 'Nog geen variabelen.',
'key' => 'Sleutel',
'value' => 'Waarde',
'key_placeholder' => 'API_KEY',
'value_placeholder' => 'Waarde',
'add' => 'Nieuwe variabele',
],
'expr' => [
'trigger_event' => 'Naam van triggergebeurtenis',
'trigger_fired_at' => 'Wanneer de trigger afging',
'trigger_post_id' => 'ID van triggerende post',
'trigger_post_content' => 'Inhoud van triggerende post',
'trigger_post_status' => 'Status van triggerende post',
'trigger_post_scheduled_at' => 'Wanneer de post is gepland',
'trigger_post_published_at' => 'Wanneer de post is gepubliceerd',
'fetched_title' => 'Titel van opgehaald item',
'fetched_link' => 'Link van opgehaald item',
'fetched_date' => 'Publicatiedatum van opgehaald item',
'fetched_content' => 'Volledige inhoud van opgehaald item',
'fetched_description' => 'Samenvatting van opgehaald item',
'fetched_author' => 'Auteur van opgehaald item',
'fetched_image' => 'Afbeeldings-URL van opgehaald item',
'fetched_categories' => 'Categorieën van opgehaald item',
'fetched_enclosure' => 'Media van opgehaald item (audio/video/bestand)',
'fetched_pubdate' => 'Publicatiedatum van opgehaald item',
'fetched_http' => 'Opgehaald HTTP-item (voeg een veld toe)',
'generated_content' => 'AI-gegenereerde postinhoud',
'generated_post_url' => 'AI-gegenereerde post-URL',
'variable' => 'Workflowvariabele',
'now' => 'Huidige datum en tijd',
],
'test' => [
'description' => 'Voert de automatisering van begin tot eind uit met een gesynthetiseerde triggerpayload. Handig om elke node te valideren zonder te wachten op de echte planning of feed.',
'starting' => 'Testuitvoering starten…',
'in_progress' => 'Bezig',
'completed' => 'Voltooid',
'failed' => 'Mislukt',
'waiting' => 'Wachten',
'close' => 'Sluiten',
'no_node_runs' => 'Wachten tot de eerste node start…',
'node_input' => 'Invoer',
'node_output' => 'Uitvoer',
'node_error' => 'Fout',
'no_new_items' => 'Geen nieuwe items — er is niets stroomafwaarts uitgevoerd.',
'error_starting' => 'Kon de testuitvoering niet starten.',
'with_real_data' => 'Met echte gegevens',
'run' => 'Test uitvoeren',
'idle_hint' => 'Klik op Test uitvoeren om de automatisering van begin tot eind uit te voeren.',
'real_data_hint' => 'Deze test publiceert posts, verplaatst polling-watermerken en activeert externe neveneffecten.',
'dry_badge' => 'Testuitvoering',
],
'status' => [
'draft' => 'Concept',
'active' => 'Actief',
'paused' => 'Gepauzeerd',
],
'index' => [
'empty_title' => 'Nog geen automatiseringen',
'empty_description' => 'Maak je eerste automatisering aan om automatisch te gaan publiceren.',
'columns' => [
'name' => 'Naam',
'status' => 'Status',
'created' => 'Aangemaakt',
],
],
'form' => [
'activate_error_fallback' => 'Kon de automatisering niet activeren.',
'pause_error_fallback' => 'Kon de automatisering niet pauzeren.',
'save_error_fallback' => 'Kon de automatisering niet opslaan.',
'save_success' => 'Automatisering opgeslagen.',
'empty_canvas_title' => 'Begin met het bouwen van je automatisering',
'empty_canvas_description' => 'Sleep een node uit het linkerpaneel om te beginnen.',
'name_placeholder' => 'Naamloze automatisering',
],
'nodes' => [
'trigger' => 'Trigger',
'generate' => 'Genereren',
'delay' => 'Vertraging',
'condition' => 'Voorwaarde',
'publish' => 'Publiceren',
'end' => 'Einde',
'end_summary' => 'Stopt de automatisering hier',
'fetch_rss' => 'RSS ophalen',
'http_request' => 'HTTP-verzoek',
'handles' => [
'items' => 'heeft items',
'no_items' => 'geen items',
],
],
'config' => [
'select_placeholder' => 'Selecteren…',
'invalid_json' => 'Dit is nog geen geldige JSON.',
'expand_editor' => 'Editor uitvouwen',
'minimize_editor' => 'Minimaliseren',
'trigger' => [
'type' => 'Triggertype',
'types' => [
'schedule' => 'Planning',
'post_published' => 'Wanneer een post wordt gepubliceerd',
'post_scheduled' => 'Wanneer een post wordt gepland',
],
'post_published_hint' => 'Wordt uitgevoerd telkens wanneer een post in deze workspace wordt gepubliceerd. De gepubliceerde post is beschikbaar op {{ trigger.post }} voor stroomafwaartse nodes.',
'post_scheduled_hint' => 'Wordt uitgevoerd telkens wanneer een post in deze workspace wordt gepland. De geplande post is beschikbaar op {{ trigger.post }}.',
'schedule' => [
'field' => 'Triggerinterval',
'fields' => [
'minutes' => 'Minuten',
'hours' => 'Uren',
'days' => 'Dagen',
'weeks' => 'Weken',
'months' => 'Maanden',
],
'minutes_interval' => 'Minuten tussen triggers',
'hours_interval' => 'Uren tussen triggers',
'days_interval' => 'Dagen tussen triggers',
'hour' => 'Triggeren op uur',
'minute' => 'Triggeren op minuut',
'weekdays' => 'Triggeren op weekdagen',
'day_of_month' => 'Dag van de maand',
'weekday_names' => [
'sun' => 'Zo',
'mon' => 'Ma',
'tue' => 'Di',
'wed' => 'Wo',
'thu' => 'Do',
'fri' => 'Vr',
'sat' => 'Za',
],
'summary' => [
'every_n_minutes' => 'Wordt elke minuut uitgevoerd|Wordt elke :count minuten uitgevoerd',
'every_n_hours' => 'Wordt elk uur uitgevoerd op minuut :minute|Wordt elke :count uur uitgevoerd op minuut :minute',
'every_n_days' => 'Wordt elke dag uitgevoerd om :time|Wordt elke :count dagen uitgevoerd om :time',
'weekly' => 'Wordt elke :days uitgevoerd om :time',
'monthly' => 'Wordt op dag :day van elke maand uitgevoerd om :time',
],
],
],
'generate' => [
'social_accounts' => 'Social accounts',
'social_accounts_empty' => 'Geen gekoppelde social accounts. Koppel er eerst een.',
'target_slide_count' => 'Te genereren slides',
'prompt_template' => 'Prompt-sjabloon',
'prompt_template_hint' => 'Typ {{ om gegevens uit eerdere stappen in te voegen.',
'image_count' => 'Te genereren afbeeldingen',
'image_count_hint' => '0 = tekstpost (geen afbeelding). 1 = enkele afbeelding. 2+ = carrousel.',
'use_brand_voice' => 'Merkstem gebruiken',
'use_brand_voice_hint' => 'Pas je merkomschrijving en -stem toe. Schakel uit voor getrouwe curatie van externe bronnen (nieuws, RSS).',
'use_brand_visuals' => 'Merkvisuals gebruiken',
'use_brand_visuals_hint' => 'Stuur AI-afbeeldingen met je merkkleuren en -identiteit. Schakel uit voor neutrale beelden die alleen door het onderwerp worden bepaald.',
'style' => 'Stijl',
'account_summary' => ':count account · :format|:count accounts · :format',
'formats' => [
'single' => 'enkel',
'carousel' => 'carrousel',
],
],
'delay' => [
'duration' => 'Duur',
'unit' => 'Eenheid',
'units' => [
'minutes' => 'Minuten',
'hours' => 'Uren',
'days' => 'Dagen',
],
],
'condition' => [
'field' => 'Veld',
'operator' => 'Operator',
'operators' => [
'contains' => 'bevat',
'not_contains' => 'bevat niet',
'equals' => 'is gelijk aan',
'not_equals' => 'is niet gelijk aan',
'matches' => 'komt overeen met (regex)',
'greater_than' => 'groter dan',
'less_than' => 'kleiner dan',
],
'value' => 'Waarde',
],
'publish' => [
'mode' => 'Modus',
'modes' => [
'now' => 'Nu publiceren',
'scheduled' => 'Plannen',
'draft' => 'Opslaan als concept',
],
'scheduled_offset' => 'Verschuiving vanaf trigger (minuten)',
'offset_summary' => ':mode · +:offset min',
],
'end' => [
'reason' => 'Reden (optioneel)',
'reason_placeholder' => 'bijv. Uitgefilterd door voorwaarde',
],
'fetch_rss' => [
'feed_url' => 'Feed-URL',
'feed_url_hint' => 'Bij de eerste uitvoering wordt het watermerk op "nu" gezet, zodat historische items stroomafwaartse nodes niet overspoelen. Volgende uitvoeringen zien alleen items die nieuwer zijn dan de vorige poll.',
'inspect' => 'Feed inspecteren',
'inspecting' => 'Inspecteren…',
'inspect_hint' => 'Haal een voorbeeld op om de beschikbare velden te ontdekken voor gebruik in stroomafwaartse nodes.',
'inspect_error' => 'Kon deze feed niet lezen. Controleer de URL en probeer het opnieuw.',
'discovered_fields' => 'Beschikbare velden',
'discovered_empty' => 'Geen velden gevonden in het laatste item.',
],
'http_request' => [
'url' => 'URL',
'method' => 'Methode',
'auth_type' => 'Authenticatie',
'auth' => [
'none' => 'Geen (openbaar)',
'bearer' => 'Bearer-token',
'basic' => 'Basic auth',
'api_key' => 'API-sleutelheader',
],
'bearer_token' => 'Bearer-token',
'basic_username' => 'Gebruikersnaam',
'basic_password' => 'Wachtwoord',
'api_key_header' => 'Headernaam',
'api_key_value' => 'API-sleutel',
'body_template' => 'Body-sjabloon (JSON)',
'headers' => 'Headers',
'header_name' => 'Headernaam',
'header_value' => 'Waarde',
'add_header' => 'Header toevoegen',
'polling_section' => 'Lijst en ontdubbeling (optioneel)',
'polling_hint' => 'Wanneer het antwoord een lijst is, voert elk item de workflow apart uit. Een enkel object wordt één keer uitgevoerd.',
'items_path' => 'Itempad',
'items_path_hint' => 'Laat leeg als het antwoord al een array is. Gebruik een pad met punten (bijv. data.items) voor een geneste array, of * voor een object met id als sleutel.',
'item_key_path' => 'Itemsleutelpad',
'item_key_path_hint' => 'JSON-pad naar een uniek id (bijv. id). Al eerder geziene items worden overgeslagen, zodat een feed zonder datums toch alleen nieuwe items doorstuurt.',
'item_date_path' => 'Itemdatumpad',
'item_date_path_hint' => 'JSON-pad naar de tijdstempel van het item (bijv. published_at). Heeft de voorkeur boven het sleutelpad indien beschikbaar. De eerste poll legt de basislijn vast en stuurt niets door, zodat een bestaande feed op dag één nooit overspoelt.',
],
],
'delete' => [
'title' => 'Automatisering verwijderen',
'description' => 'Weet je zeker dat je deze automatisering wilt verwijderen? Alle uitvoeringen en triggeritems worden ook verwijderd. Deze actie kan niet ongedaan worden gemaakt.',
'confirm' => 'Verwijderen',
'cancel' => 'Annuleren',
],
'flash' => [
'deleted' => 'Automatisering succesvol verwijderd!',
],
'errors' => [
'no_active_social_accounts' => 'Geen actieve social accounts geconfigureerd voor deze automatisering.',
'must_have_one_trigger' => 'Een automatisering moet precies één triggernode hebben.',
'trigger_must_be_connected' => 'De triggernode moet met ten minste één node verbonden zijn.',
'graph_contains_cycle' => 'De automatiseringsgraaf bevat een cyclus.',
'only_failed_can_retry' => 'Alleen mislukte uitvoeringen kunnen opnieuw worden geprobeerd.',
'no_generated_post' => 'Geen gegenereerde post gevonden bij de uitvoering.',
'url_not_allowed' => 'De verzoek-URL verwijst naar een privé of onbereikbaar adres en is geblokkeerd.',
'node_no_longer_exists' => 'Node :node_id bestaat niet meer in de automatisering.',
'no_trigger_connection' => 'Geen node verbonden met de triggernode.',
'fetch_rss_missing_url' => 'De RSS-ophaalnode mist een feed-URL.',
'fetch_rss_request_failed' => 'Het verzoek voor de RSS-feed is mislukt.',
'fetch_rss_malformed' => 'De RSS-feed is onjuist opgemaakt.',
'http_missing_url' => 'De HTTP-verzoeknode mist een URL.',
'http_request_exception' => 'Het HTTP-verzoek gaf een uitzondering.',
'http_request_failed' => 'Het HTTP-verzoek is mislukt.',
'http_items_path_not_array' => 'Het itempad verwees niet naar een lijst.',
'generate_image_format_required' => 'AI-generatie maakt alleen afbeeldingen. Kies een afbeeldingsformaat (geen video).',
],
];