* 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.
402 lines
20 KiB
PHP
402 lines
20 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
return [
|
||
'mobile_notice' => 'オートメーションエディタは大きな画面での利用に最適です。ワークフローを作成するにはデスクトップで開いてください。',
|
||
'title' => 'オートメーション',
|
||
'default_name' => '新しいオートメーション',
|
||
|
||
'actions' => [
|
||
'new' => '新しいオートメーション',
|
||
'edit' => '編集',
|
||
'save' => '保存',
|
||
'activate' => '有効化',
|
||
'pause' => '一時停止',
|
||
'delete' => '削除',
|
||
'retry' => '再試行',
|
||
'guide' => '仕組みを学ぶ',
|
||
],
|
||
|
||
'tabs' => [
|
||
'build' => '作成',
|
||
'variables' => '変数',
|
||
'test' => 'テスト',
|
||
],
|
||
|
||
'nav' => [
|
||
'workflow' => 'ワークフロー',
|
||
'invocations' => '実行履歴',
|
||
'metrics' => 'メトリクス',
|
||
'settings' => '設定',
|
||
],
|
||
|
||
'settings' => [
|
||
'general' => '一般',
|
||
'general_description' => 'このオートメーションの名前を変更します。',
|
||
'name_label' => '名前',
|
||
'name_saved' => 'オートメーションの名前を変更しました。',
|
||
'status_title' => 'ステータス',
|
||
'status_description' => '有効化すると実行を開始し、一時停止すると停止します。',
|
||
'activated_at' => ':date に有効化',
|
||
'paused_at' => ':date に一時停止',
|
||
'created_at' => ':date に作成',
|
||
'danger_title' => '危険な操作',
|
||
'danger_description' => '取り消せない操作です。',
|
||
'delete_title' => 'このオートメーションを削除',
|
||
'delete_description' => 'オートメーションとその実行履歴を完全に削除します。',
|
||
],
|
||
|
||
'status_run' => [
|
||
'pending' => '保留中',
|
||
'running' => '実行中',
|
||
'waiting' => '待機中',
|
||
'completed' => '完了',
|
||
'failed' => '失敗',
|
||
'cancelled' => 'キャンセル済み',
|
||
],
|
||
|
||
'node_type' => [
|
||
'trigger' => 'トリガー',
|
||
'generate' => 'コンテンツを生成',
|
||
'delay' => '遅延',
|
||
'condition' => '条件',
|
||
'publish' => '公開',
|
||
'end' => '終了',
|
||
'fetch_rss' => 'RSS を取得',
|
||
'http_request' => 'HTTP リクエスト',
|
||
],
|
||
|
||
'invocations' => [
|
||
'empty' => 'まだ実行履歴がありません。',
|
||
'refresh' => '更新',
|
||
'search_placeholder' => '実行 ID で検索…',
|
||
'copied' => '実行 ID をコピーしました。',
|
||
'loading' => 'ステップを読み込み中…',
|
||
'no_steps' => '記録されたステップがありません。',
|
||
'load_error' => 'ステップを読み込めませんでした。',
|
||
'steps' => '{0}ステップなし|{1}:count 件のステップ|[2,*]:count 件のステップ',
|
||
'filter' => [
|
||
'all' => 'すべてのステータス',
|
||
],
|
||
'columns' => [
|
||
'timestamp' => 'タイムスタンプ',
|
||
'run' => '実行',
|
||
'status' => 'ステータス',
|
||
'message' => '最新メッセージ',
|
||
'duration' => '所要時間',
|
||
],
|
||
'summary' => [
|
||
'completed' => 'ワークフローが完了しました',
|
||
'failed' => 'ワークフローが失敗しました',
|
||
'running' => 'ワークフローを実行中',
|
||
'cancelled' => 'ワークフローをキャンセルしました',
|
||
'pending' => 'ワークフローは保留中です',
|
||
],
|
||
],
|
||
|
||
'metrics' => [
|
||
'overview' => '概要',
|
||
'runs_over_time' => '実行数の推移',
|
||
'posts_by_platform' => 'プラットフォーム別の投稿',
|
||
'no_posts' => 'この期間に公開された投稿はありません。',
|
||
'cards' => [
|
||
'runs' => '総実行数',
|
||
'completed' => '完了',
|
||
'failed' => '失敗',
|
||
'in_progress' => '進行中',
|
||
'success_rate' => '成功率',
|
||
'avg_duration' => '平均所要時間',
|
||
'posts_created' => '作成された投稿数',
|
||
],
|
||
'legend' => [
|
||
'started' => '開始',
|
||
'completed' => '完了',
|
||
'failed' => '失敗',
|
||
],
|
||
],
|
||
|
||
'categories' => [
|
||
'sources' => 'ソース',
|
||
'content' => 'コンテンツ',
|
||
'flow' => 'フロー',
|
||
'output' => '出力',
|
||
],
|
||
|
||
'variables' => [
|
||
'title' => 'ワークフロー変数',
|
||
'hint' => '{{ variables.KEY }} でどこからでも参照できる再利用可能な値です。暗号化して保存されます。',
|
||
'empty' => 'まだ変数がありません。',
|
||
'key' => 'キー',
|
||
'value' => '値',
|
||
'key_placeholder' => 'API_KEY',
|
||
'value_placeholder' => '値',
|
||
'add' => '新しい変数',
|
||
],
|
||
|
||
'expr' => [
|
||
'trigger_event' => 'トリガーイベント名',
|
||
'trigger_fired_at' => 'トリガーが発火した時刻',
|
||
'trigger_post_id' => 'トリガーとなった投稿 ID',
|
||
'trigger_post_content' => 'トリガーとなった投稿の内容',
|
||
'trigger_post_status' => 'トリガーとなった投稿のステータス',
|
||
'trigger_post_scheduled_at' => '投稿の予約日時',
|
||
'trigger_post_published_at' => '投稿が公開された日時',
|
||
'fetched_title' => '取得したアイテムのタイトル',
|
||
'fetched_link' => '取得したアイテムのリンク',
|
||
'fetched_date' => '取得したアイテムの公開日',
|
||
'fetched_content' => '取得したアイテムの全文',
|
||
'fetched_description' => '取得したアイテムの概要',
|
||
'fetched_author' => '取得したアイテムの作成者',
|
||
'fetched_image' => '取得したアイテムの画像 URL',
|
||
'fetched_categories' => '取得したアイテムのカテゴリ',
|
||
'fetched_enclosure' => '取得したアイテムのメディア(音声・動画・ファイル)',
|
||
'fetched_pubdate' => '取得したアイテムの公開日',
|
||
'fetched_http' => '取得した HTTP アイテム(フィールドを追加)',
|
||
'generated_content' => 'AI が生成した投稿の内容',
|
||
'generated_post_url' => 'AI が生成した投稿の URL',
|
||
'variable' => 'ワークフロー変数',
|
||
'now' => '現在の日時',
|
||
],
|
||
|
||
'test' => [
|
||
'description' => '合成したトリガーペイロードを使って、オートメーションを最初から最後まで実行します。実際のスケジュールやフィードを待たずに各ノードを検証するのに便利です。',
|
||
'starting' => 'テスト実行を開始しています…',
|
||
'in_progress' => '進行中',
|
||
'completed' => '完了',
|
||
'failed' => '失敗',
|
||
'waiting' => '待機中',
|
||
'close' => '閉じる',
|
||
'no_node_runs' => '最初のノードの開始を待っています…',
|
||
'node_input' => '入力',
|
||
'node_output' => '出力',
|
||
'node_error' => 'エラー',
|
||
'no_new_items' => '新しいアイテムがありません — 後続の処理は実行されませんでした。',
|
||
'error_starting' => 'テスト実行を開始できませんでした。',
|
||
'with_real_data' => '実データを使用',
|
||
'run' => 'テストを実行',
|
||
'idle_hint' => '「テストを実行」を押すと、オートメーションを最初から最後まで実行します。',
|
||
'real_data_hint' => 'このテストは投稿を公開し、ポーリングの基準を進め、外部への副作用を発生させます。',
|
||
'dry_badge' => 'ドライラン',
|
||
],
|
||
|
||
'status' => [
|
||
'draft' => '下書き',
|
||
'active' => '有効',
|
||
'paused' => '一時停止中',
|
||
],
|
||
|
||
'index' => [
|
||
'empty_title' => 'まだオートメーションがありません',
|
||
'empty_description' => '最初のオートメーションを作成して、自動で投稿を公開しましょう。',
|
||
'columns' => [
|
||
'name' => '名前',
|
||
'status' => 'ステータス',
|
||
'created' => '作成日',
|
||
],
|
||
],
|
||
|
||
'form' => [
|
||
'activate_error_fallback' => 'オートメーションを有効化できませんでした。',
|
||
'pause_error_fallback' => 'オートメーションを一時停止できませんでした。',
|
||
'save_error_fallback' => 'オートメーションを保存できませんでした。',
|
||
'save_success' => 'オートメーションを保存しました。',
|
||
'empty_canvas_title' => 'オートメーションの作成を始めましょう',
|
||
'empty_canvas_description' => '左側のパネルからノードをドラッグして始めましょう。',
|
||
'name_placeholder' => '無題のオートメーション',
|
||
],
|
||
|
||
'nodes' => [
|
||
'trigger' => 'トリガー',
|
||
'generate' => '生成',
|
||
'delay' => '遅延',
|
||
'condition' => '条件',
|
||
'publish' => '公開',
|
||
'end' => '終了',
|
||
'end_summary' => 'ここでオートメーションを停止します',
|
||
'fetch_rss' => 'RSS を取得',
|
||
'http_request' => 'HTTP リクエスト',
|
||
'handles' => [
|
||
'items' => 'アイテムあり',
|
||
'no_items' => 'アイテムなし',
|
||
],
|
||
],
|
||
|
||
'config' => [
|
||
'select_placeholder' => '選択…',
|
||
'invalid_json' => 'まだ有効な JSON ではありません。',
|
||
'expand_editor' => 'エディターを拡大',
|
||
'minimize_editor' => '最小化',
|
||
|
||
'trigger' => [
|
||
'type' => 'トリガーの種類',
|
||
'types' => [
|
||
'schedule' => 'スケジュール',
|
||
'post_published' => '投稿が公開されたとき',
|
||
'post_scheduled' => '投稿が予約されたとき',
|
||
],
|
||
'post_published_hint' => 'このワークスペースで投稿が公開されるたびに実行されます。公開された投稿は {{ trigger.post }} として後続のノードで利用できます。',
|
||
'post_scheduled_hint' => 'このワークスペースで投稿が予約されるたびに実行されます。予約された投稿は {{ trigger.post }} で利用できます。',
|
||
|
||
'schedule' => [
|
||
'field' => 'トリガー間隔',
|
||
'fields' => [
|
||
'minutes' => '分',
|
||
'hours' => '時間',
|
||
'days' => '日',
|
||
'weeks' => '週',
|
||
'months' => '月',
|
||
],
|
||
'minutes_interval' => 'トリガー間の分数',
|
||
'hours_interval' => 'トリガー間の時間数',
|
||
'days_interval' => 'トリガー間の日数',
|
||
'hour' => '実行する時',
|
||
'minute' => '実行する分',
|
||
'weekdays' => '実行する曜日',
|
||
'day_of_month' => '実行する日',
|
||
'weekday_names' => [
|
||
'sun' => '日',
|
||
'mon' => '月',
|
||
'tue' => '火',
|
||
'wed' => '水',
|
||
'thu' => '木',
|
||
'fri' => '金',
|
||
'sat' => '土',
|
||
],
|
||
'summary' => [
|
||
'every_n_minutes' => ':count 分ごとに実行|:count 分ごとに実行',
|
||
'every_n_hours' => ':count 時間ごとに :minute 分に実行|:count 時間ごとに :minute 分に実行',
|
||
'every_n_days' => ':count 日ごとに :time に実行|:count 日ごとに :time に実行',
|
||
'weekly' => '毎週 :days の :time に実行',
|
||
'monthly' => '毎月 :day 日の :time に実行',
|
||
],
|
||
],
|
||
],
|
||
'generate' => [
|
||
'social_accounts' => 'ソーシャルアカウント',
|
||
'social_accounts_empty' => '接続済みのソーシャルアカウントがありません。まず 1 つ接続してください。',
|
||
'target_slide_count' => '生成するスライド数',
|
||
'prompt_template' => 'プロンプトテンプレート',
|
||
'prompt_template_hint' => '{{ と入力すると、前のステップのデータを挿入できます。',
|
||
'image_count' => '生成する画像数',
|
||
'image_count_hint' => '0 = テキストのみの投稿(画像なし)。1 = 単一画像。2 以上 = カルーセル。',
|
||
'use_brand_voice' => 'ブランドボイスを使用',
|
||
'use_brand_voice_hint' => 'ブランドの説明とボイスを適用します。第三者ソース(ニュース、RSS)を忠実にキュレーションする場合はオフにしてください。',
|
||
'use_brand_visuals' => 'ブランドビジュアルを使用',
|
||
'use_brand_visuals_hint' => 'AI 画像をブランドカラーとアイデンティティで方向づけます。投稿のトピックのみに基づく中立的な画像にする場合はオフにしてください。',
|
||
'style' => 'スタイル',
|
||
'account_summary' => ':count 件のアカウント · :format|:count 件のアカウント · :format',
|
||
'formats' => [
|
||
'single' => '単一',
|
||
'carousel' => 'カルーセル',
|
||
],
|
||
],
|
||
'delay' => [
|
||
'duration' => '期間',
|
||
'unit' => '単位',
|
||
'units' => [
|
||
'minutes' => '分',
|
||
'hours' => '時間',
|
||
'days' => '日',
|
||
],
|
||
],
|
||
'condition' => [
|
||
'field' => 'フィールド',
|
||
'operator' => '演算子',
|
||
'operators' => [
|
||
'contains' => '含む',
|
||
'not_contains' => '含まない',
|
||
'equals' => '等しい',
|
||
'not_equals' => '等しくない',
|
||
'matches' => '一致(正規表現)',
|
||
'greater_than' => 'より大きい',
|
||
'less_than' => 'より小さい',
|
||
],
|
||
'value' => '値',
|
||
],
|
||
'publish' => [
|
||
'mode' => 'モード',
|
||
'modes' => [
|
||
'now' => '今すぐ公開',
|
||
'scheduled' => '予約',
|
||
'draft' => '下書きとして保存',
|
||
],
|
||
'scheduled_offset' => 'トリガーからのオフセット(分)',
|
||
'offset_summary' => ':mode · +:offset 分',
|
||
],
|
||
'end' => [
|
||
'reason' => '理由(任意)',
|
||
'reason_placeholder' => '例: 条件により除外',
|
||
],
|
||
'fetch_rss' => [
|
||
'feed_url' => 'フィード URL',
|
||
'feed_url_hint' => '初回実行時、基準は「現在」に設定され、過去のアイテムが後続ノードに大量に流れ込まないようにします。以降の実行では、前回のポーリングより新しいアイテムのみが対象になります。',
|
||
'inspect' => 'フィードを確認',
|
||
'inspecting' => '確認中…',
|
||
'inspect_hint' => 'サンプルを取得して、後続のノードで使用できるフィールドを確認します。',
|
||
'inspect_error' => 'このフィードを読み込めませんでした。URL を確認してもう一度お試しください。',
|
||
'discovered_fields' => '利用可能なフィールド',
|
||
'discovered_empty' => '最新のアイテムにフィールドが見つかりませんでした。',
|
||
],
|
||
'http_request' => [
|
||
'url' => 'URL',
|
||
'method' => 'メソッド',
|
||
'auth_type' => '認証',
|
||
'auth' => [
|
||
'none' => 'なし(公開)',
|
||
'bearer' => 'ベアラートークン',
|
||
'basic' => 'Basic 認証',
|
||
'api_key' => 'API キーヘッダー',
|
||
],
|
||
'bearer_token' => 'ベアラートークン',
|
||
'basic_username' => 'ユーザー名',
|
||
'basic_password' => 'パスワード',
|
||
'api_key_header' => 'ヘッダー名',
|
||
'api_key_value' => 'API キー',
|
||
'body_template' => 'ボディテンプレート(JSON)',
|
||
'headers' => 'ヘッダー',
|
||
'header_name' => 'ヘッダー名',
|
||
'header_value' => '値',
|
||
'add_header' => 'ヘッダーを追加',
|
||
'polling_section' => 'リストと重複排除(任意)',
|
||
'polling_hint' => 'レスポンスがリストの場合、各アイテムがワークフローを個別に実行します。単一のオブジェクトの場合は 1 回だけ実行されます。',
|
||
'items_path' => 'アイテムのパス',
|
||
'items_path_hint' => 'レスポンスがすでに配列の場合は空欄にしてください。ネストされた配列にはドット区切りのパス(例: data.items)を、id をキーとするオブジェクトには * を使用します。',
|
||
'item_key_path' => 'アイテムキーのパス',
|
||
'item_key_path_hint' => '一意の id への JSON パス(例: id)。すでに処理済みのアイテムはスキップされるため、日付のないフィードでも新しいエントリのみが転送されます。',
|
||
'item_date_path' => 'アイテム日付のパス',
|
||
'item_date_path_hint' => 'アイテムのタイムスタンプへの JSON パス(例: published_at)。利用可能な場合はキーのパスより優先されます。初回のポーリングでは基準を記録し何も転送しないため、既存のフィードでも初日から大量に流れ込むことはありません。',
|
||
],
|
||
],
|
||
|
||
'delete' => [
|
||
'title' => 'オートメーションを削除',
|
||
'description' => 'このオートメーションを削除してもよろしいですか?すべての実行とトリガーアイテムも削除されます。この操作は取り消せません。',
|
||
'confirm' => '削除',
|
||
'cancel' => 'キャンセル',
|
||
],
|
||
|
||
'flash' => [
|
||
'deleted' => 'オートメーションを正常に削除しました!',
|
||
],
|
||
|
||
'errors' => [
|
||
'no_active_social_accounts' => 'このオートメーションに有効なソーシャルアカウントが設定されていません。',
|
||
'must_have_one_trigger' => 'オートメーションにはトリガーノードが 1 つだけ必要です。',
|
||
'trigger_must_be_connected' => 'トリガーノードは少なくとも 1 つのノードに接続されている必要があります。',
|
||
'graph_contains_cycle' => 'オートメーションのグラフに循環が含まれています。',
|
||
'only_failed_can_retry' => '失敗した実行のみ再試行できます。',
|
||
'no_generated_post' => '実行で生成された投稿が見つかりません。',
|
||
'url_not_allowed' => 'リクエスト URL がプライベートまたは到達不能なアドレスを指しているためブロックされました。',
|
||
'node_no_longer_exists' => 'ノード :node_id はオートメーションに存在しなくなりました。',
|
||
'no_trigger_connection' => 'トリガーノードに接続されたノードがありません。',
|
||
'fetch_rss_missing_url' => 'RSS 取得ノードにフィード URL がありません。',
|
||
'fetch_rss_request_failed' => 'RSS フィードのリクエストが失敗しました。',
|
||
'fetch_rss_malformed' => 'RSS フィードの形式が不正です。',
|
||
'http_missing_url' => 'HTTP リクエストノードに URL がありません。',
|
||
'http_request_exception' => 'HTTP リクエストで例外が発生しました。',
|
||
'http_request_failed' => 'HTTP リクエストが失敗しました。',
|
||
'http_items_path_not_array' => 'アイテムのパスがリストとして解決されませんでした。',
|
||
'generate_image_format_required' => 'AI生成は画像のみ作成します。画像フォーマットを選んでください(動画不可)。',
|
||
],
|
||
];
|