ドキュメント &システムエンサイクロペディア
MarbleSend の包括的な技術ガイド、UI 要素ディレクトリ、および shared-hosting 最適化マニュアル。
システムアーキテクチャ&ホスティング基盤
設計思想: セルフホスト、シングルテナント、zero-build、shared-hosting フレンドリー
MarbleSend は、メールマーケティングソフトウェアにおける顕著な課題(高価な専用 VPS インスタンス、Redis サーバー、Node ビルドパイプライン、複雑な Docker オーケストレーションの必要性)を解決するためにゼロから構築されました。MarbleSend はサーバー側のコンパイルを一切行わず、純粋な PHP 8.2+ を使用して標準的な shared-hosting(cPanel、Hostinger、DirectAdmin、Plesk、LiteSpeed)上で動作します。
SQL Injection ゼロ
すべてのデータベースクエリは ORM のオーバーヘッドなしに厳格な prepared statements を使用します。
保存時暗号化(At-Rest)
SMTP 認証情報、AI API キー、および webhook secret は Crypto.php で暗号化されます。
二重送信防止
Worker は厳格な期限処理を伴う MySQL のステータス更新を介してアトミックにキューバッチを要求します。
即時デプロイ
コンパイル済み Tailwind CSS および vendored Alpine.js。zip をアップロードしてインストーラーを実行すれば完了です。
0.1 Zero-Build ホスティング&ランタイム哲学
最新のウェブアプリケーションの多くは、Node.js ビルドパイプライン、Redis デーモンサーバー、Docker オーケストレーション、または root VPS アクセスを要求します。MarbleSend はこのような複雑さを排除します。安価な共有ホスティング(cPanel、Hostinger、Plesk、LiteSpeed など)向けに特別に設計されており、サーバー側でのコンパイルを一切行わずに純粋な PHP 8.2+ で動作します。
サーバー側コンパイルゼロ
本番サーバー上での npm、Webpack、Vite、Composer は不要です。Tailwind CSS は静的アセットに事前コンパイルされ、Alpine.js はローカルに内包され、PHPMailer 6.9.x は vendor-lite フォルダに直接同梱されています。
省メモリ設計
メールキューのバッチ処理中であってもピークメモリ使用量は 32MB 未満に維持されます。共有ホスティングの厳しいメモリ制限(64MB〜128MB php.ini 割り当て)内でも快適に動作します。
禁止関数の不使用
共有ホスティング事業者によって無効化されがちな危険な関数(exec、shell_exec、system、passthru、eval、proc_close)を徹底的に排除しています。外部通信はすべてタイムアウト付きのネイティブ cURL を使用します。
0.2 セキュリティ境界とディレクトリ分離
MarbleSend は、公開 Web アセットを機密性の高いアプリケーションコードや storage から明確に切り離す厳格な 2 層ディレクトリレイアウトを実装し、ディレクトリトラバーサルや file 露出のリスクを排除しています。
分離された Document Root (public/)
Web サーバーに公開されるのは public/ ディレクトリのみです。ドメインまたはサブドメインの DocumentRoot を /public に設定してください。Apache や Nginx でディレクトリ一覧表示が有効な場合でも、コアソース files は閲覧できません。
保護されたアプリケーションコア (app/)
コントローラー、サービス、ライブラリ、ビュー、設定はすべて DocumentRoot 外の app/ に配置されます。app/config/config.php 内のデータベース認証情報や暗号化キーは直接 HTTP リクエストから到達不可能です。
セキュアな storage とマイグレーション
storage/ ディレクトリ(worker ログを保持)および migrations/(生の SQL スキーマ files を保持)は完全に public/ の外側に存在し、システムログやデータベース構造の不正ダウンロードを防止します。
0.3 Zero-ORM データベース& PDO Prepared Statements
Eloquent や Doctrine などの ORM は、過剰なメモリオーバーヘッド、複雑なオブジェクトハイドレーション層、予測不能な N+1 クエリを発生させます。MarbleSend は純粋なネイティブ PHP PDO を直接採用し、100% prepared statements でクエリを実行します。
100% Prepared Statements
すべてのデータベースクエリはパラメータを明示的にバインド(PDO::PARAM_STR、PDO::PARAM_INT)します。SQL 構文とユーザー入力値が混ざり合うことはなく、SQL インジェクション攻撃に対する数学的な免疫力を提供します。
予測可能な高パフォーマンスクエリ
直接 SQL 実行により ORM オブジェクトハイドレーションの負担を排除し、リスト操作やバッチキューの更新を共有データベース上で最大 5 倍高速かつ極小の CPU 負荷で実行します。
冪等なスキーママイグレーション
データベースバージョンは連番 SQL files(0001_initial.sql から 0019_add_feedback_attachment.sql)で管理され、IF NOT EXISTS ガードを備えた冪等ランナーによって実行され、cm_migrations テーブルに記録されます。
Single-Tenant データ分離
tenant_id 列を持たないシングルテナントスタンドアロンソフトウェアとして設計されています。インデックスはコンパクトに保たれ、シーケンシャルスキャンを防ぎ、他テナントへのデータ漏洩リスクは完全にゼロです。
0.4 At-Rest 暗号化と暗号標準
機密シークレットが平文で保存されることは決してありません。MarbleSend は、App\Lib\Crypto を通じて業界標準の認証付き対称暗号化を用いて認証情報を暗号化します。
AES-256-GCM 暗号化
Galois/Counter Mode の高度暗号化標準(AES-256-GCM)を採用し、機密性の確保と改ざん検知のための暗号学的整合性検証を両立しています。
固有の 96-bit ランダム IV
暗号化ごとに random_bytes() で暗号学的に安全な 12 バイト(96 ビット)の初期化ベクトル(IV)を生成するため、同一の平文であっても常に全く異なる暗号文が生成されます。
暗号化シークレットカタログ
SMTP リレーパスワード、BYOK AI API キー(OpenAI、Claude、Gemini、DeepSeek、Kimi、OpenRouter)、Webhook 署名シークレット、Envato Purchase Code を自動的に保護します。
マスターキーの隔離保管
32 バイトの ENCRYPTION_KEY はインストール時に生成され、app/config/config.php(パーミッション 0600)内にのみ保存されます。データベース内に暗号化キーが保存されることはありません。
0.5 デュアル Worker エンジンと並行処理安全性
MarbleSend は、時間のかかる処理やスケジュール実行タスクをすべて統合バックグラウンド worker ランナーに委譲し、管理画面の高速レスポンスを常時維持します。
単一マスターバックグラウンドランナー
worker.php がキューの一括送信、定周期スケジュールの実行、RSS フィード post のポーリング、オートレスポンダーシーケンスのトリガー、未開封 Campaign の再送信を一元統括します。
柔軟な CLI Cron と Web-Cron
ネイティブのシステム crontab(* * * * * php /path/to/worker.php)または安全な外部 HTTP ping(/cron.php?key=YOUR_KEY)のどちらからでも実行可能で、両パスとも全く同一のサービスロジックを呼び出します。
アトミックなキュー獲得(二重送信防止)
worker インスタンスはアトミックな SQL ステータス更新(UPDATE cm_email_queue SET status = 'processing' WHERE status = 'pending' LIMIT N)でキューバッチを獲得します。プロセスが重複起動しても重複送信は発生しません。
ハートビートと停滞ジョブの自動回復
実行ハートビートを cm_settings に記録します。ホスティングのタイムアウト等で worker プロセスが中断された場合、後続の worker 実行が停滞キューアイテムを自動検出して安全に復旧します。
0.6 サーバー要件とホスティング互換性マトリクス
MarbleSend は、基準となる PHP 8.2+ 要件を満たすすべての標準的な共有ホスティング環境、コントロールパネル、サーバー構成において検証済みです。
| コンポーネント | 最小要件 | 推奨環境 | 運用上の注記 |
|---|---|---|---|
| PHP ランタイム | PHP 8.2.0+ | PHP 8.2 または 8.3 | すべてのアプリケーション files で strict_types=1 を宣言。 |
| データベースエンジン | MySQL 8.0+ / MariaDB 10.6+ | MariaDB 10.11+ または MySQL 8.0+ | InnoDB エンジン必須。UTF8MB4 完全 Unicode 文字セット対応。 |
| 必須 PHP 拡張モジュール | pdo_mysql, openssl, mbstring, json, curl, simplexml, sodium | すべての標準コア拡張が有効であること | 共有ホスティングの 99% で標準提供。オプション: 地域書式用 intl。 |
| Web サーバー | Apache, Nginx, LiteSpeed, Caddy | Apache + mod_rewrite または LiteSpeed | ルートおよび public/ 配下に設定済み .htaccess files を同梱。 |
| メモリ割り当て | 32MB memory_limit | 64MB 〜 128MB | メモリ枯渇を防ぐためキューのチャンクは保守的なバッチサイズで処理。 |
| Cron スケジューラ | CLI crontab または Web-Cron HTTP ping | CLI cron 毎分 1 回実行 | CLI アクセスのない環境向けに Web-Cron フォールバック(/cron.php?key=...)を用意。 |
検証済みホスティングコントロールパネル
cPanel、Hostinger hPanel、Plesk、DirectAdmin、CyberPanel、AApanel、CloudPanel、および標準的な Ubuntu/Debian LAMP/LEMP 構成で動作確認および完全検証済みです。
ダッシュボード概要 (/dashboard)
オーディエンスの健全性、配信 KPI、worker ハートビート、およびスケジュール自動化のための集約されたミッションコントロール。
ダッシュボード構成要素の詳細&サポートインスペクター
バックエンドの詳細を確認するには、以下の要素にカーソルを合わせるかクリックしてください総送信数
ログ集計&月間カウンター開封数 / 開封率
1x1 トラッキングピクセル& Apple MPP に関する注記クリック数 / CTR
クリックスルーリダイレクトインジェクター配信停止オーディエンス
購読解除率と RFC 準拠Worker ハートビート
Cron ステータス&1分間隔配信量推移チャート
7日間・30日間・90日間・年間推移最近の配信一覧テーブル
ステータス遷移と監査証跡到達性ヘルス
SMTP プロファイル準備状況1.1 メールパフォーマンス KPI カード
| 要素 | 計算とデータソース | 視覚的意味 | サポート防止の根拠 |
|---|---|---|---|
| 総送信数カード | COUNT(cm_email_logs) + SUM(cm_campaigns.sent_count) | 送信されたこれまでのブロードキャストおよびスケジュールメールの合計数を表示します。サブテキストには今カレンダー月に送信されたボリュームが表示されます。 | 古いログエントリがプルーニングされた際の混乱を防ぎます。過去の Campaign カウンターにより、生涯合計が減少することはありません。 |
| 総開封数 / 開封率 | COUNT(DISTINCT contact_id WHERE opened_at IS NOT NULL) / Total Sent * 100 | HTML メールのフッターに挿入された透明な 1x1 トラッキングピクセルを介してエンゲージメントを測定します。 | Apple MPP 免責事項: iOS の Mail Privacy Protection は Apple プロキシ経由で画像を事前取得するため、開封率が人為的に上昇する可能性があります。CTR が真のビジネス指標となります。 |
| 総クリック数 / CTR | COUNT(DISTINCT contact_id WHERE clicked_at IS NOT NULL) / Total Sent * 100 | ユニーク購読者のリンククリックを測定します。/track/click.php を経由して書き換えられます。 | 統計の整合性を維持するため、配信停止リンクおよび確認リンクは Campaign の CTR から除外されます。 |
| 配信停止カード | COUNT(status = 'unsubscribed') / Total Contacts * 100 | 必須のワンクリック配信停止メカニズムを通じてオプトアウトした受信者リストの割合。 | 健全なしきい値は 0.5% 未満です。配信停止率が 1% を超える場合は、オーディエンスの疲弊、購入リストの使用、または関連性の低さを示しています。 |
総送信数と月間配信スループット
通常配信、定期配信、RSS 連動、自動応答経由で配信された全メール総数を追跡。サブテキストは当月の送信数を表示します。過去の Campaigns 累計値が保持されるため、ログの整理後も総数が減ることはありません。
ユニーク開封数と Apple MPP の影響
メールフッターに埋め込まれた透明な 1x1 ピクセルで計測。Apple Mail Privacy Protection (MPP) による自動プリロードで開封率が見かけ上増加する場合があるため、クリック率(CTR)こそが真のエンゲージメント指標です。
ユニーククリック数と URL 書換エンジン
本文内のリンクはすべて /track/click.php を経由するように自動置換され、転送前に連絡先 ID、Campaign ID、遷移先 URL、日時を記録します。解除リンク(/unsubscribe.php)や確認リンク(/confirm.php)は追跡から除外されます。
購読解除連絡先とドメイン評価の保護
本文の解除リンクまたは RFC 8058 ワンクリックヘッダーで解除された読者数。健康なリストでは 0.5% 未満を保ちます。1.0% を超えた場合、Gmail や Yahoo 等によるスパム判定を避けるためリストの点検を促します。
1.2 オペレーション& Worker ヘルスハートビート
MarbleSend は単一のマスターバックグラウンドランナー worker.php で動作します。ダッシュボードは cm_settings['worker_last_run'] を検査して、cron が60秒ごとに実行されているかを判断します。
アクティブ状態(正常な Cron)
worker.php が直近3分以内に実行されると、バッジに「アクティブ」と表示されます。キューバッチはリアルタイムで処理され、スケジュールされたニュースレターは定刻にトリガーされ、オートレスポンダーも迅速に実行されます。
非アクティブ状態(Cron 未検出)
3分以上ハートビートが記録されない場合、バッジは赤色に変わります。カードをクリックすると、正確な crontab CLI コマンドと web-cron fallback URL が記載された Settings → システム にすぐに移動します。
有効連絡先と全読者総数の比較
全登録者のうち active 状態の割合を表示。MarbleSend は厳格な4段階ステータス(active、pending、unsubscribed、suppressed)を管理しており、配信ワーカーは WHERE status = 'active' の相手にのみ送信します。
月間および通算 Campaigns 総数
当月配信されたブロードキャストと歴代 Campaigns の累計を表示し、配信頻度と運用実績を一目で把握できます。
次回予定配信の自動解決
有効な定期配信(next_run_at ASC LIMIT 1)を照会し、次回予定とカウントダウンを表示。実行日時は SchedulerService::computeNextRun() によりタイムゾーンと夏時間を考慮して正確に UTC 保存されます。
Worker ハートビートと共用サーバー Cron
worker.php が過去 180 秒以内に稼働したかを判定。共用サーバー(cPanel 等)では crontab に * * * * * php /path/to/worker.php >/dev/null 2>&1 を設定。CLI が使えない場合は Web-Cron エンドポイント(/cron.php?key=YOUR_KEY)を利用可能です。
1.3 Campaign 成長ビジュアライザー
成長ビジュアライザーは、7日間、30日間、90日間、年初来(YTD)の4つの選択可能な期間でボリューム分布を描画します。各バーは集計された時間バケットを表し、ホバー時に送信数と開封数を表示します。
直近の週次(7日)、月次サイクル(30日)、四半期(90日)、年初来累計の間で素早く表示を切り替えられます。
ピーク送信量に応じた CSS flexbox で瞬時に描画。重いグラフライブラリを排除し、モバイルや格安サーバーでも快適に動作します。
バーに触れると正確な日時、送信総数、ユニーク開封実績がポップアップで明瞭に比較できます。
ライブ配信フィードとシステム死活監視
右側カラムでは最新の Campaign 送信進捗をステータスバッジ(Completed、Sending 点滅、Failed、Draft)や配信比率、ワーカー状態と共にリアルタイム表示します。
status = 'completed'
status = 'sending'
status = 'failed'
status = 'draft'
Campaigns 履歴と配信監査テーブル
下部の監査表には直近の配信名、ステータス、生成種別(manual、定期配信、RSS 連動、未開封再送)、送信完了率、確認済み開封率が一覧化されます。
Campaign の件名、作成日、および作成元タグ(manual、recurring、rss、または resend_unopened)を表示します。
配信成功メッセージと失敗メッセージの即時カウント、およびリアルタイムの開封率とクリック率のパーセンテージ。
受信者レベルのイベントログおよび未開封者への再送信モーダル用の Campaign レポートページへの直接ショートカット。
1.6 クイックショートカットと業務自動化
定期メルマガの予約、RSS ブログ更新通知、読者リストの CSV 取込、ダブルオプトイン確認、不達アドレスの自動抑止など、重要フローへの直接導線を提供します。
自動化フロー(定期配信& RSS)
Cron スケジュールや連携先 WordPress/Ghost/Substack の RSS 新着記事検知により、手作業なしで自動的にメールマガジンを配信します。
オーディエンス&購読者管理
CSV での連絡先一括登録、リスト分類、double opt-in 準拠の徹底、配信エラーや解除済みアドレスの自動隔離を実行します。
Campaign マネージャー&レポート (/campaigns)
高速ブロードキャストコンポーザー、タグターゲット受信者セレクター、プリフライト安全エンジン、および詳細な配信レポート。
Interactive Campaigns UI Inspector
任意のコンポーネントをクリックしてスキーマへの影響と運用ヒントを確認リアルタイム配信モニター
リアルタイム統計とイベント受信者セレクター
Tag フィルタリングと全選択トリプルビューエディター
コード・分割・プレビューPreflight 検証エンジン
6項目の自動セキュリティ点検テスト送信診断
キューを使わない即時テストUTM とリンク書き換え
UTM パラメータと 302 クリック追跡配信履歴アーカイブ
status および送信元フィルター配信後詳細レポート
CTR・MPP・未開封再送2.1 ライブ Campaign モニターバナー
ブロードキャストがアクティブに配信されているときはいつでも、固定モニターバナーが /campaigns の上部にスライドイン表示されます。ページ全体をリロードすることなく、1.5秒ごとに /api/campaigns/:id/progress をポーリングします。
Summer Launch Newsletter
Sending74% complete
7,420 / 10,000 emails
待機中
2,528
送信中
40
成功
7,420
失敗
12
Recent Events Real-time status
1.5秒ごとのポーリングエンジン
/api/campaigns/:id/progress を1.5秒ごとに非同期取得し、ブラウザをリロードすることなく最新の配信スループットを表示します。
直近の配信イベントストリーム
最新5件の受信者 status 変動、リアルタイムの配信完了通知、および SMTP エラー詳細を表示するライブイベントログ。
バックグラウンドの worker.php に遅延が発生したり cron が停止している場合、修復手順を示す警告バッジが表示されます。
2.2 受信者セレクター&タグフィルター(左カラム)
左側の列では、購読者を正確に絞り込むことができます。管理者はカスタム連絡先タグでフィルタリングし、メールや名前の一部で検索し、個々の連絡先を選択するか「一致するすべてを選択」をクリックできます。
ステートマシンのフィルタリング保証:
選択や検索に関係なく、クエリエンジンは厳格に status = 'active' を適用します。配信停止、保留中、または除外(suppressed)された連絡先はキューから自動的に除外されます。
複数 Tag の積集合による絞り込み
tag を指定して特定の読者セグメントを選択できます。重複する対象読者数がリアルタイムで瞬時に算出されます。
300ms デバウンス付きインクリメンタル検索
300ms のデバウンス処理により、大規模な読者リストでもデータベースに負荷をかけずに名前やメールアドレスで即座に絞り込めます。
一括選択コントロール
連絡先を個別に選択することも、「すべて選択」で現在の検索条件に一致する読者全員をワンクリックで指定することも可能です。
グループ
連絡先はグループで整理されます(1件の連絡先を複数のグループに入れられ、すべての連絡先は少なくとも1つ、既定では General に属します)。Select Recipients で「グループ別」を選ぶと、選択したグループのすべてのアクティブな連絡先に送信されます(表示中のページだけでなくグループ全体)。「手動で選択」では個別の連絡先を選べます(1つのグループで絞り込み可能)。
グループは、スケジュールの対象、autoresponder ルールのトリガー、サインアップページの登録先、未開封者への再送の絞り込みにも使えます。グループを削除しても連絡先は削除されません。そのグループに依存する autoresponder ルールは無効になります。
2.3 Campaign コンポーザー&分割エディターモード
分割モード
左側でコード編集を行い、右側でリアルタイムに応答性の高い iframe プレビューを同時に表示します。
コード専用モード
ガター行番号と syntax タブを備えた全幅の集中できる HTML コードエディター。
ライブプレビューモード
デスクトップ(100%)、タブレット(600px)、およびモバイル(375px)のデバイスビューポート切り替えを備えたサンドボックスレンダリング。
Placeholder 変数と置換エンジン
{{name}}、{{email}}、{{unsubscribe_link}}、{{offer_url}}、{{track_pixel}} タグを使用してメールを動的にパーソナライズできます。
サンドボックス化されたレスポンシブ表示
配信前に隔離された iframe 内でスマートフォン(375px)、タブレット(600px)、PC(100%)での表示レイアウトを確認できます。
2.4 6項目の自動プリフライト安全チェック
壊れたプレースホルダー、配信停止リンクの欠落、スパムトリガーなどの致命的なミスを防ぐため、MarbleSend では配信開始前にプリフライトチェックが必要です。
| 安全チェック | 重要度 | ルールと検出 | 不合格時の結果 |
|---|---|---|---|
| 1. 配信停止リンク | 重大(CRITICAL) | {{unsubscribe_link}} token の存在を確認します。 | 送信がブロックされます。CAN-SPAM、GDPR、および2024年の Yahoo/Google 送信者要件に基づき必須です。 |
| 2. プレースホルダーの妥当性 | 重大(CRITICAL) | 不明なプレースホルダータグ(例: {{first_nam}} のようなタイプミス)を検出します。 | 不明なタグが修正または削除されるまで送信はブロックされます。 |
| 3. 受信者オーディエンス | 重大(CRITICAL) | 0人を超えるアクティブな受信者が選択されていることを検証します。 | 空の選択に対してブロードキャストすることはできません。 |
| 4. SMTP 接続性 | 重大(CRITICAL) | 選択された SMTP プロファイルのホストと認証情報を検証します。 | 不適切なリレー認証情報によるキューの停止を防止します。 |
| 5. スパムトリガーワード | 警告(WARNING) | 件名と本文からスパムトリガーフレーズ(「100% free」、「act now」、「limited time」など)をスキャンします。 | 警告バナーが表示されます。管理者は確認して続行できます。 |
| 6. 件名の長さ | 情報(INFO) | モバイルでの最適な件名表示のために30〜60文字を推奨します。 | 開封率向上のための情報通知。 |
Preflight 安全点検ゲート
キュー投入前に6つの自動安全ルールを判定します。「CRITICAL」判定の項目が1つでもある場合、配信実行ボタンが無効化されます。
2.5 テスト送信診断&確認モーダル
何千通ものメールをキューにコミットする前に、「テストメールを送信」ボタンを使用すると、データベースの受信者リストに触れることなく、管理者または QA メールボックスに直接1通のテストメッセージを即座に送信できます。すべてのプレースホルダータグ({{first_name}}、{{email}}、{{unsubscribe_link}})にはモックプレビュー値が設定されるため、Gmail、Apple Mail、Outlook にわたるメールの描画状態を確認できます。
テストデータの自動展開
リアルな見本値(例:Jane Doe、デモ用配信停止リンク)を読者変数に代入し、実際の受信状態を正確に目視確認できます。
送信前最終確認ダイアログ
キューを生成する前に、総受信者数、選択中の送信者プロファイル、適用中の UTM タグを確認できる2段階のモーダル確認。
2.6 自動 UTM トラッキングインジェクション
すべてのアウトバウンドアンカータグ(<a href="...">)は App\Services\TrackingInjector を介して処理されます。UTM パラメーター(utm_source、utm_medium、utm_campaign、utm_content)は、クリックリダイレクトのラッピング前に自動的に追加されます。mailto リンク、tel リンク、および配信停止リンクはそのまま保持されます。
ステップ1: UTM クエリパラメータの付与
既存のクエリパラメータを保持したまま、すべてのハイパーリンクに utm_source、utm_medium、utm_campaign、utm_content を付加します。
ステップ2: 開封トラッキングピクセルの埋め込み
メールクライアントでの表示時に開封イベントを記録するため、閉じ </body> タグの直前に 1x1 の透過 GIF を挿入します。
ステップ3: 302 クリック転送エンジン
外部リンクを /track/click.php?h=... に書き換え、ミリ秒単位の超高速転送を行いながらファーストタッチのクリックログを記録します。
RFC 規約に基づく厳格な除外措置
配信停止リンク、mailto/tel リンク、double opt-in 確認リンクは、UTM 付与およびクリック転送処理から厳格に除外されます。
2.7 Campaign 履歴&ポートフォリオ (/campaigns/history)
完全な履歴ポートフォリオでは、作成元(manual、recurring、rss、resend_unopened)、ステータス(completed、sending、failed、draft)、および日付範囲にわたる複数属性のフィルタリングが提供されます。管理者は複数の Campaign を選択して、集約された CSV 配信ログをダウンロードできます。
配信元パイプラインの追跡
配信を手動 Composer、定期スケジュール、RSS ブログ連動、または未開封者への再送に分類して管理します。
複数 status 絞り込みと CSV 出力
完了、送信中、失敗、下書きの各状態でアーカイブを検索し、詳細な配信ログをワンクリックで一括ダウンロードできます。
ワンクリック配信複製
過去の配信を HTML デザイン、subject 行、送信元設定をすべて維持したまま composer に再ロードして複製できます。
2.8 アナリティクスレポート&「未開封者に再送信」機能
任意: グループを選ぶと、そのグループに属する未開封者にのみ再送します。再送が元のキャンペーンの受信者を超えることはありません。
/campaigns/:id/report にて、MarbleSend は包括的な Campaign 終了後レポートを表示します:
4つの Bento パフォーマンス指標
送信総数(100%)、配信エラー数、ユニーク開封数と開封率、ユニーククリック数と CTR を総合的に集計します。
時間帯別エンゲージメント推移曲線
配信後72時間の開封の集中度を1時間ごとに可視化し、読者に最も届きやすい最適な配信時間帯を特定します。
未開封読者へのピンポイント再送
opened_at IS NULL の読者だけを対象に Campaign を自動複製し、新しい subject で再アプローチして、既存開封者に重複配信することなく15〜25%の追加開封を獲得できます。
連絡先ハブ&成長ツール (/contacts)
購読者のライフサイクル管理、CSV インポート、GDPR コンプライアンス、カスタム登録ページ、およびオートレスポンダー。
インタラクティブ連絡先 UI インスペクター
コンポーネントをクリックしてスキーマへの影響と運用ヒントを確認4状態ステートマシン
active/pending/unsub/supp検索&フィルターエンジン
タグ、ステータス&デバウンス監査&同意ドロワー
IP、タイムスタンプ&バウンスRFC 4180 CSV インポーター
5万行対応&重複防止ガードホスト型登録ページ
Double opt-in&ファネルタグ Autoresponder
イベント駆動型ドリップ規則一括管理ハブ
ページ横断セグメンテーションGDPR プライバシー&完全削除
JSON 出力&完全抹消3.1 4状態の購読者ステートマシン
MarbleSend はすべての連絡先に対して厳格で統一されたステートマシンを維持します。付随する boolean フラグはありません。すべての送信パイプラインは WHERE status = 'active' でフィルタリングします。
アクティブ購読者
オプトイン確認済み、有効なメール。Campaign、スケジュール、およびオートレスポンダーを受信する資格があります。
ダブルオプトイン保留中
ダブルオプトインフォームから登録し、確認メールのクリック待ち。確認されるまでブロードキャストから除外されます。
配信停止済み
配信停止リンクをクリック済み。二度と送信されません。明示的な再オプトインなしに手動で再アクティブ化することはできません。
ハードバウンス / 苦情
無効なメールボックス(5xx SMTP)、スパム苦情、または管理者による手動除外により永久に除外されます。
| 状態 | 遷移トリガー | 遷移先状態 | Campaign 配信への影響 |
|---|---|---|---|
| active | 購読者が配信停止リンクまたは RFC 8058 ヘッダーをクリック | unsubscribed | 今後のすべての broadcast およびスケジュールキューから直ちに除外。 |
| active | 5xx SMTP 恒久バウンスまたは連続3回目のソフトバウンス | suppressed | 送信ドメインのレピュテーションを守るため永久に隔離。 |
| pending | 購読者が double opt-in 確認トークンリンクをクリック | active | active に昇格。Campaigns および autoresponders の受信対象に復帰。 |
| suppressed | 管理者による手動での抑制解除(確認付き) | active | ソフトバウンスカウンターをリセットし、有効配信キューに復帰。 |
アーキテクチャガード:副次的なブール値フラグの完全排除
MarbleSend は単一の ENUM 列 (cm_contacts.status) を徹底しています。他社システムでは is_active、is_unsubscribed、is_bounced 等の競合でデータ破損が頻発します。MarbleSend ではすべての配信クエリが曖昧さなく WHERE status = 'active' を含みます。
3.2 リアルタイムフィルター、検索&行アクション
連絡先テーブルは、タグピル、購読者ステータス(active、pending、unsubscribed、suppressed)による即座の Alpine.js リアクティブフィルタリング、およびメールと名/姓にわたるフリーテキストデバウンス検索を備えています。
すべての連絡先は少なくとも1つのグループ(既定は General)に属します。グループフィルターでテーブルを絞り込み、「グループを管理」でグループの作成・名前変更・削除ができます。グループを削除しても連絡先は削除されません。
JSON タグ保存&正規化
タグは cm_contacts.tags に正規化された JSON 配列として保存されます。大文字小文字を区別せず、トリミングされ、高速検索用にインデックス化されます。
300ms デバウンス即時検索
メール、名、姓を同時に検索し、データベース負荷を最小限に抑えるため 300ms のデバウンスを適用します。
サーバーサイドページネーション&拡張性
効率的な SQL LIMIT および OFFSET クエリにより、メモリ使用量を抑えながら5万件以上の購読者をスムーズに閲覧します。
ページをリロードすることなく、名前、カスタムメタデータ、およびタグチップをインラインで更新します。
連絡先を即座に除外(suppress)し、すべてのキューから直ちに対象外とします。
GDPR 第17条に従い、連絡先プロファイル、ログ、およびキューアイテムを永久に削除(purge)します。
3.3 詳細ドロワー、GDPR 監査証跡& JSON エクスポート
連絡先の行をクリックすると、監査ドロワーがスライドして開きます。生涯メトリクス(総受信メール数、開封率、クリック数)、オプトイン IP アドレス、オプトイン日時、登録フォーム slug、および第15条(アクセス権)と第20条(データポータビリティ)に準拠するためのワンクリック GDPR JSON エクスポートボタンが表示されます。
オプトイン日時&同意元
法的検証のため、正確な日時と獲得チャネル(手動、CSV インポート、登録ページ、API)を記録します。
検証済み IP アドレスの取得
フォーム送信時の購読者 IP アドレスを記録し、GDPR や CAN-SPAM に準拠した同意の明確な証拠を提供します。
ライフタイムエンゲージメントテレメトリ
累計送信量と検証済み開封日時を監視し、アクティブな購読者と休眠購読者を正確に分類します。
ソフトバウンスの自動昇格
連続した一時的配信エラー(X / 3)を追跡します。連続3回目のソフトバウンスが発生すると、ステータスが自動的に suppressed に遷移します。
3.4 CSV インポーター&列マッピング
インポーターは最大 50,000 行の CSV files を解析します。区切り文字(カンマ、セミコロン、タブ)を自動検出し、列をメール、名、姓、タグにマッピングするための視覚的なドロップダウンを提供します。
インポートした連絡先を追加するグループを選びます(未選択なら General)。既存の連絡先はそれらのグループに追加され、すでに属しているグループから外れることはありません。
メモリ安全なチャンクアップロード
最大50,000行のファイルをトランザクション単位で分割処理し、制約の厳しい共用サーバーでもメモリ消費を32MB未満に抑えます。
区切り文字の自動判別&マッピング
カンマ、セミコロン、タブを自動検出し、メール、名、姓、タグの直感的な列マッピングを提供します。
一括タグ付け&インポート後監査
取り込んだ全連絡先にグローバルタグを一括適用し、追加、更新、スキップされた件数を明確に報告します。
重複をスキップ
既存の連絡先の詳細とタグを保持します。新しい行のみが挿入されます。
空のフィールドを更新
既存のデータを上書きすることなく、欠落している名前を入力し、新しいタグを追加します。
すべて上書き
読み込まれた CSV file に一致するように名前とタグを完全に更新します。
3.5 公開登録ページ (/s/:slug)
連絡先のタブ 2 にあります。カスタムの見出し、説明、入力ラベル、送信ボタンを備えたブランド独自の独立した登録ページを作成できます。機能は以下のとおりです:
このページからの登録者が追加されるグループを選びます(未選択なら General)。後で削除されたグループは自動的に対象から外れます。
アクティブなすべての登録ファネルにおける累計表示回数を監視します。
ホスト型フォーム全体での閲覧数に対する送信完了率を算出します。
最大20ページの運用枠に対する稼働中ランディングページ数を表示します。
直近30日間のローリング期間中に獲得した新規購読者を計測します。
マルチチャネル埋め込み連携
ホスト型 URL (/subscribe?slug=...)、クリーンな HTML コード、レスポンシブ iframe、JS モーダルポップアップでどこにでも埋め込み可能です。
自動確認メール送信を伴う HMAC 署名付き確認 token を生成します。
登録時に指定の購読者タグを割り当て、カスタマイズされたステップ配信(drip sequence)をトリガーします。
オプトイン後、新しい購読者をサンクスページまたはリードマグネットの URL に誘導します。
3.6 オートレスポンダー&ステップ配信(Drip Sequences)
Contacts のタブ3にあります。新しい購読者がアクティブになった時点(登録の直後、または double opt-in の確認後)でキューに入る自動ウェルカムメールを設定します。ルールはタグまたはグループに一致し、遅延の設定はありません。メールはバックグラウンドの worker が配信し、suppression ルールが自動的に適用されます。
ルールはタグの代わりにグループでも起動できます。グループルールは、そのグループに新しいアクティブな連絡先が作成されたとき、またはメールで確認したときに実行されます。既存の連絡先を後からグループに追加しても実行されません(タグルールと同じ)。グループを削除するとルールは無効になります。
タグ基準イベントリスナー
新しいアクティブな購読者がルールのタグを持つ、またはそのグループに属しているときに実行されます。登録ページ、API 呼び出し、手動追加(single opt-in)の直後、または double opt-in が確認されたときです。CSV インポートでは実行されず、既存の連絡先に後からタグやグループを追加しても実行されません。
専用 SMTP ルーティング
一斉配信とは切り離し、高い評価を持つトランザクション専用 SMTP プロファイル経由で配信します。
Worker による非同期バックグラウンド処理
メール生成と送信を worker.php に委ねることで、Web タイムアウトを防ぎフォームの応答性を維持します。
ループ防止&重複ガード
同一タグが再度付与された場合でも、重複したウェルカムメールが送信されないよう保護します。
3.7 一括管理&リストセグメンテーション (/contacts/list)
/contacts/list にて、バッチ操作で大量のリストを管理します: ページをまたいだ選択、一括でのタグ適用または削除、何千ものコールドリードの一括除外、またはターゲットセグメントの UTF-8 CSV files へのエクスポート。
「グループに追加」と「グループから削除」は選択したすべての連絡先に適用されます。最後のグループから外すと General に戻ります。
タグの一括追加
既存のタグを消去することなく、選択した連絡先全員に1回のクエリでタグを追加します。
タグの一括削除
複数リストをまたいで、選択した連絡先から特定のタグを的確に除去します。
絞り込み CSV エクスポート
フィルター後の購読者リストを全メタデータ付きで RFC 4180 準拠の CSV ファイルへ直接出力します。
一括抑制 (Suppression)
送信者の評価スコアを保つため、休眠またはリスクの高い連絡先を即座に隔離します。
一括配信停止
外部データやオフラインキャンペーン経由の配信停止依頼を一括処理します。
GDPR 完全抹消
GDPR 第17条に基づき、購読者データと関連するテレメトリログを恒久的に削除します。
3.8 GDPR プライバシー、監査エクスポート&削除基準
EU 一般データ保護規則 (GDPR)、カリフォルニア州 CCPA、および CAN-SPAM の要件に厳格に準拠した組み込みプライバシー管理。
GDPR エクスポート(JSON)には、連絡先が属するグループも含まれます。
第15条・第20条:構造化 JSON データ出力
購読者プロファイル、同意 IP、オプトイン時刻、配信ログを含む構造化 JSON データを生成します。
第17条:忘れられる権利(完全削除)
完全削除は cm_contacts、cm_email_logs、cm_email_queue にカスケード適用され、個人データを完全に破棄します。
抑制解除の安全確認バリア
無効なメールボックスへの誤送信を防ぐため、抑制されたアドレスの復帰には管理者による明示的な再確認が必要です。
テンプレートスタジオ& AI コピーライター (/templates)
メールに安全な8種類のテーブルレイアウト、ミニチュアCSSリセット付きのサンドボックスiframeプレビュー、販売向けAIコピーライター、そしてニュースレター用のMarkdownニュース投稿。
Templates Studio UI インスペクター
下の各コンポーネントをクリックして、データベースクエリ、スキーマへの影響、運用ヒントを確認できますTemplate ライブラリ
即時検索と slug キーStarter レイアウト
テーブル構造による8種のメールレイアウト生コードエディター
Tab インデントと整形機能隔離された Viewport
デスクトップおよびモバイル枠動的 Tokens パレット
1クリックプレースホルダー挿入テストメール送信機能
リアルタイム SMTP 検証モーダルAI Copywriter ドロワー
Templates の生成とリファイン件名レビューツール
1–100 スコアとスパム検査ニュース投稿
ニュースレター用のMarkdown記事4.1 Template ライブラリ、カスタム Slugs、メタデータ管理
すべてのマーケティング、トランザクション、自動返信メール templates を一元管理する中央リポジトリです。クライアント側の即時検索、不変 URL slugs、リアルタイムのドラフト状態表示を備えています。
不変の Template Slugs
Slug ID(例: #monthly-newsletter)は作成時に設定され、保存後はロックされます。これにより自動 RSS Campaigns や配信シーケンスのリンク切れを防ぎます。
サブセコンド・デバウンス検索
高速なクライアント側 Alpine フィルターが、不要な DB 問い合わせを発生させることなく、template 名、件名、slug を即座に照合します。
ライブドラフト状態の同期
専用の破線インジケーターカードが、作業中のインメモリドラフトと保存済みの本番 templates を視覚的に区別し、誤った上書きを防ぎます。
独立した Campaigns 履歴スナップショット
ライブラリ内の template を編集または削除しても、過去の配信履歴が変化することはありません。送信済み Campaigns は cm_campaigns 内に静的コピーを安全に保持します。
4.2 検証済みのテーブルベース・レスポンシブ Starter レイアウト8選
従来のデスクトップメールクライアント(特に Word HTML エンジンを使用する Microsoft Outlook)は CSS Grid や Flexbox をサポートしていません。MarbleSend は Gmail、Outlook、Apple Mail、Yahoo でテスト済みの8種類のテーブルベースレイアウトを標準装備しています。
必須の配信停止フッターを備えたクリーンなキャンバス。
ヒーローバナー、バリュープロポジション、太字の CTA。
厳選されたエディトリアル、2カラムのハイライト記事。
ヘッダー帯と、ニュース投稿スケジュール用の {{news_posts}} ブロック。
個別オンボーディング、3ステップのスタートガイド。
日時バッジ、登壇者プロフィール、RSVP ボタン。
ナンバリング記事、読了時間、著者タグ。
緊急割引クーポン、損失回避コピー。
ネストされたテーブル構造とインライン CSS
各 starter レイアウトは、ピクセル幅を明示しセル余白をゼロにしたネストされた <table> タグと、インライン化された CSS によって構築され、確実な表示安定性を保証します。
4.3 生 HTML コードエディターとクリーンフォーマッター
メール開発者向けに設計されたエディターで、Tab キーによるインデント制御、文字数のリアルタイム監視、不要な余白の自動クリーンアップ機能を搭載しています。
Tab キーによるインデント捕捉
Tab キーを押すとブラウザのフォーカスを移動させずに2スペースが挿入され、エディター内で快適にコード構造を整えられます。
ワンクリック・コード整形("Clean")
インラインスタイルを保持したまま、不揃いなインデントを整え、不要な連続改行を削除し、テーブル構造を美しく再編成します。
容量監視と切り捨て防止
リアルタイム文字数カウンターが容量を監視します。HTML を 102 KB 未満に維持することで、Gmail による「[Message clipped]」での本文省略を未然に防止します。
WYSIWYG ビルダー特有の不要コードを排除
HTML を直接制御することで、ビジュアルエディターが生成しがちな余計な CSS クラス、非標準フォント、不可視の span タグによる到達性の悪化を防ぎます。
4.4 サンドボックス隔離マルチデバイス・レスポンシブ Viewports
サンドボックス化された iframe 内でデスクトップおよびモバイルの表示をシミュレートし、管理画面へのスタイル干渉を防ぎながら即座に視覚フィードバックを提供します。
Iframe セキュリティと CSS 隔離
sandbox="allow-same-origin" 属性により、メール内の CSS ルールが MarbleSend 管理画面のスタイルへ干渉するのを完全に防ぎます。
デスクトップと 320px モバイル表示の切り替え
全幅のデスクトップ表示と実機サイズの 320px スマホフレームをワンタッチで切り替え、1カラム表示のレスポンシブ性を確認できます。
リアルタイム件名シミュレーションバー
上部のプレビューヘッダーに解析済みの件名行がリアルタイムに反映され、送信前にパーソナライズ置き換え後の見た目を正確にチェックできます。
動的 Syntax 構文エラー警告バナー
ドラフトのコードを常時スキャンし、閉じられていないプレースホルダーや非対応トークンを検知すると直ちに警告バナーを表示します。
4.5 動的パーソナライズ Tokens と RFC 規格準拠
配信時にテンプレートエンジンがtokenを受信者の属性、安全な追跡リンク、RSS記事の要約、ニュース投稿へと動的に置き換えます。
受信者の氏名(値が存在しない場合は自動的に "there" にフォールバック)
受信者のメールアドレス
RFC 8058 規格に準拠した必須のワンクリック配信停止リンク
登録ページ用のダブルオプトイン(double opt-in)確認 URL
自動 RSS ニュースレター向けのブログ記事ループ出力ブロック
連携している RSS/Atom コンテンツフィードの名称
直近に公開された最新ブログ記事のタイトル
ニュースレター内に新しく含まれるフィード記事の件数
ニュースレタースケジュール用のニュース投稿ブロック(カバー、タイトル、サブタイトル、本文)
この送信に含まれるニュース投稿の数
この送信で最も新しいニュース投稿のタイトル
法的要件と到達率の維持
すべてのマーケティング配信には {{unsubscribe_link}} が必須です。適切な配信解除機能を持たない配信は CAN-SPAM、GDPR、CASL に違反し、送信ドメインのブラックリスト入りの原因となります。
4.6 単一テスト送信診断と事前チェック
スケジュール設定や一斉配信を行う前に、選択した SMTP プロファイルを経由して任意のテストアドレスへ実機確認用メールを送信できる診断モーダルです。
複数 SMTP プロファイルの選択切り替え
設定済みの任意の SMTP プロファイルを経由させてテスト送信を行い、各送信サーバーにおける SPF、DKIM、到達状況を直接テストできます。
プレースホルダーのダミー値シミュレーション
Tokens を現実的なテストデータ(例: "John Doe")へ自動変換し、文字の折り返しやレイアウトの配置バランスを正確に確認できます。
キューを介さない即時送信
バックグラウンドキュー(cm_email_queue)を介さず MailerFactory で同期的に送信されるため、成功・失敗の判定をその場ですぐに得られます。
受信トレイとダークモードの表示確認
個人の Gmail、Outlook、Apple Mail アカウントに直接テストを送り、ダークモードにおける色の反転やボタンの視認性を実機で確認できます。
4.7 訴求力の高い AI Copywriting エンジン BYOK
中間サーバーを介さず BYOK(Bring Your Own Key)で直結動作し、高転換率で安全なメール templates を高速に作成・推敲する内蔵 AI ツールです。
重要な原則:生成品質は Prompt と選択した LLM モデルに依存します
MarbleSend は単一の閉じた AI に制限しません。生成はお客様が設定した BYOK プロバイダー経由で実行されるため、メールのレイアウト品質、訴求力、HTML テーブルの正確さ、件名の分析精度は、入力した prompt の具体性と選択した LLM モデルの推論能力という 2 つの変数に本質的に左右されます。
1. ユーザー Prompt の具体性とコンテキストの深さ
AI モデルは提供された指示の明確さを忠実に反映します。「プロモーションメールを書いて」といった汎用的な prompt では一般的な文章しか生成されません。優れた結果を得るには、ターゲット読者、主要な悩み、独自の提案、トーン(緊急性、親しみやすさ、ビジネス調)、明確な Call-to-Action(CTA)など構造化された情報を指定してください。「テンプレート編集」タブでは、「第 2 段落を短くする」「CTA ボタンに 20% オフを強調する」「3 つのメリット枠を追加する」など具体的な指示を与えることで段階的に洗練できます。
2. LLM モデルの階層と推論能力
Settings → AI Providers では、最先端のフロンティア推論モデル(DeepSeek-V4.1-flash、Claude 5 Sonnet、GPT-6 など)や軽量なローカルモデル(Ollama や Groq 経由の 7B〜8B パラメータなど)を接続できます。上位モデルは、複雑な HTML テーブルの入れ子構造、パーソナライズ token({{name}}、{{email}}、{{unsubscribe_link}})の自然な配置、高いコンバージョンを生むコピーライティングに極めて優れています。「件名オプション」タブのスコア(1〜100)、スパムリスク診断、候補提案も有効なモデルによってリアルタイムに評価され、高性能なモデルほど鋭い講評と魅力的な別案を提示します。
MarbleSend 組み込みの System Prompt ガードレール
prompt の長さやモデルの選択にかかわらず、AiService.php は堅牢なメールセーフ設計を自動適用します。単一テーブルのレスポンシブ構造(最大幅 600px、清潔な背景、高コントラストカード)、Outlook や Gmail に対応した壊れないテーブル製 CTA ボタン、到達率を保護する外部画像ゼロ設計、グローバル規制に準拠するためのフッターへの {{unsubscribe_link}} token 必須挿入が含まれます。
Template 全体の新規生成
ターゲット読者層、オファー、トーン、希望する長さに合わせて、最適化されたレスポンシブなテーブル構造の HTML メールをゼロから生成します。
コンテキスト認識リファイン
エディターで開いている既存のコードを読み取り、「3つのメリット枠を追加して」「CTA ボタンの緊急性を強めて」といった指示に応じて部分修正を行います。
インタラクティブなビジュアル比較
並列したサンドボックス iframe に「変更前」と「変更後」が同時に表示され、結果を目で見て納得した上でエディターに適用できます。
主要プロバイダーの API キー取得手順
API キーとモデル ID を取得したら、MarbleSend で以下の簡単なステップに従って設定します:
4.8 AI 件名スコアと到達性インスペクター
保有するすべての templates の件名を分析し、開封率の予測、迷惑メール判定リスク、文字数の省略チェックを実施して改善案を提示します。
ライブラリ内全件名の一括読み込み
cm_templates テーブルに登録されたすべての件名を一覧表示し、現在エディターで開いている template の件名を自動で強調表示します。
1–100 の多角的スコアリング
有効な LLM が好奇心の刺激、明瞭さ、提供価値、緊急性を総合的に判断し、100点満点で客観的な評価点を算出します。
スマホ画面での省略とスパム単語の監査
スマートフォンの通知領域を超える文字数(50文字以内を推奨)を警告し、「無料」「緊急 $$$」などのリスクワードや過剰な記号を検出します。
高成約率の代替案バリエーション
好奇心訴求、具体的メリット、損失回避など異なる切り口の魅力的な代替案を提案し、ワンクリックでエディターへ反映できます。
ニュース投稿 — ニュースレター向け Substack 風の記事
テンプレートの「投稿」タブで記事を書きます(ライブプレビュー付き Markdown)。「ニュース投稿」に設定したニュースレターのスケジュールは、テンプレートの {{news_posts}} プレースホルダーを埋めて、準備完了の投稿を古いものから順に1回だけ送信します。投稿はメールの中にのみ存在し、公開ページはありません。
書いて準備完了にする
ツールバーまたはプレーンな Markdown を使います。下書きから準備完了に切り替えた後にのみ、投稿は送信されます。
テンプレートのプレースホルダー
記事を表示したい場所に {{news_posts}} を置きます(「ニュース投稿ニュースレター」スターターにはすでに含まれています)。{{news_posts_count}} と {{news_latest_post_title}} は件名で使えます。
スケジュールする
スケジュールで「ニュースレター」を選び、コンテンツソースで「ニュース投稿」を選びます。その時点以降に準備完了になった投稿のみが送信されるため、過去の記事が再送されることはありません。スマート除外は使用されません。
安全設計
投稿のテキストは HTML エスケープされ、https のリンクと画像のみ許可されます。Gmail が配信停止リンクを切り詰めないよう、各メールを約100 KB未満に保ってください。エディターが警告します。
投稿ワークスペースの概要
テンプレートを開き、投稿タブに切り替えます。左がライブラリ、右がライブプレビュー付きエディターで、テンプレートスタジオと同じレイアウトです。
| 部分 | 役割 |
|---|---|
| ライブラリ | すべての投稿を、下書きまたは準備完了のバッジ、送信回数、最終更新時刻とともに一覧表示します。検索ボックスはタイトルとサブタイトルで絞り込み、ゴミ箱アイコンはホバー時に表示されます。 |
| タイトル・サブタイトル・カバー | タイトルは必須です(255文字まで、1行)。サブタイトル(500文字まで)はその下に表示されます。カバー画像は https のURLである必要があり、それ以外は保存時に拒否されます。 |
| ステータススイッチ | 下書きの投稿は送信されません。投稿を準備完了にすると、準備完了になった時刻が記録され、その時刻がどのスケジュールが送信できるかを決めます。 |
| Markdownエディター | ツールバーのボタン(見出し、太字、斜体、リンク、リスト、引用、区切り線、画像)が選択範囲の前後にsyntaxを挿入します。1つの投稿には最大100,000文字を入れられます。 |
| ライブプレビュー | 未保存の投稿を、選んだテンプレート内で実際の送信と同じコードで表示し、メールサイズをKBで示します。{{name}} などのプレースホルダーにはサンプル値が使われます。 |
| プレースホルダーのショートカット | エディター下のボタンが {{news_posts}} をコピーするので、テンプレートに貼り付けられます。 |
Markdownリファレンス
投稿テキストはMarkdownの小さく安全なサブセットで書きます。このリスト以外はそのままの文字として扱われます。
| Syntax | 結果 |
|---|---|
| ## Heading ### Smaller | 見出し(レベル1〜3はメール対応の見出しになります) |
| **bold** *italic* | 太字と斜体 |
| [text](https://example.com) | リンク。http、https、mailto のアドレスだけがリンクになり、それ以外のスキーム(javascript: など)はそのままの文字になります。 |
| - item 1. item | 箇条書きと番号付きリスト |
| > quote | ブロック引用 |
| --- | 区切り線 |
|  | 画像。https のみ。画像をブロックする読者のため、必ず短い説明を付けてください。 |
| (blank line) | 段落は空行で区切ります。単独の改行は段落内の改行のままです。 |
| <script>alert(1)</script> | 生のHTMLは解釈されません。入力した <script> や <img> タグは文字のまま表示されます。 |
{{news_posts}} プレースホルダー群
テンプレートに置いてください。ニュース投稿スケジュールが送信時に、{{name}} などの受信者ごとのtokenが解決される前にこれらを埋めます。
| プレースホルダー | 置き換わる内容 |
|---|---|
| {{news_posts}} | この送信の投稿ブロック:各投稿のカバー画像、タイトル、サブタイトル、本文(古い順)。テンプレート本文に必須です。 |
| {{news_posts_count}} | この送信に含まれる投稿の数(例:1)。件名と本文で使えます。 |
| {{news_latest_post_title}} | この送信で最も新しい投稿のタイトル。件名に最適です。 |
本文に必須
テンプレート本文に {{news_posts}} がないと、ニュース投稿スケジュールは保存時に拒否されます。後でテンプレートを編集した場合、実行は安全に失敗します(投稿は保留のまま)。
生のテキストとして送信されません
他の場所(手動Campaign、RSSスケジュール、テンプレートのみのスケジュール)で使うと、プレースホルダーは空のテキストに置き換えられ、Campaignの事前チェックが送信前に警告します。
パーソナライズと追跡
投稿テキストは通常の処理を通ります。投稿内の {{name}} は受信者ごとにパーソナライズされ、リンクにはUTMパラメーターとクリック追跡が付き、テンプレートの配信停止リンクはそのまま保たれます。
投稿のライフサイクル
すべての投稿は同じ単純な状態を進みます。ライブラリのバッジには常に現在の状態が表示されます。
下書き
執筆中です。送信されません。準備完了の投稿を下書きに戻すと、準備完了の時刻が消えます。
準備完了
送信待ちです。スケジュールは、そのスケジュールのニュース投稿モードがオンになった後に準備完了になった投稿だけを送信します。すでに準備完了の投稿を再保存しても、キュー内の順番は変わりません。
送信済み
スケジュールごとに記録され、ライブラリでは「送信済み 1×」と表示されます。後から編集しても、スケジュールが同じ投稿を2回送信することはありません。
削除済み
投稿とその配信履歴を削除します。すでに配信されたメールには影響せず、削除した投稿は復元できません。
メールサイズと安全性
投稿は全文をメールの中に含みます(公開ページはありません)。そのため、リンクだけのダイジェストよりもサイズと安全性が重要です。
まずエスケープ
入力した文字はすべて、書式を適用する前にHTMLとしてエスケープされるため、スクリプトやタグが受信者の受信トレイに届くことはありません。
https のみ
画像とカバーは https である必要があります。リンクは http、https、mailto を受け付けます。それ以外のスキームは文字として表示されます。
約100 KB未満に保つ
Gmailは約102 KBを超えるメッセージを切り詰め、配信停止リンクを含むフッターを隠します。プレビューはサイズをKBで表示し、80 KBを超えると警告します。長い記事ではメールあたりの投稿数を少なくしてください。
公開アーカイブなし
投稿はあなたが送るメールの中にだけ存在します。Webページ、画像アップロード、自動AI呼び出しはなく、画像はURLでリンクします。
簡易トラブルシューティング
| 症状 | 確認すること |
|---|---|
| プレビューに記事が表示されない | 選択したテンプレートに {{news_posts}} プレースホルダーがありません(リストでは「{{news_posts}} なし」と表示されます)。別のテンプレートを選ぶか、プレースホルダーを追加してください。 |
| 「サイズの大きいメール」の警告 | 投稿を短くする、重い書式を取り除く、またはスケジュールの「メールあたりの投稿数」を減らしてください。 |
| リンクをクリックできない | [text](https://…) の形で、http、https、mailto のアドレスで書いてください。それ以外のスキームは文字のままです。 |
| 画像が表示されない | アドレスは https で始まり、公開アクセス可能である必要があります。読者が許可するまでリモート画像をブロックするメールアプリもあります。 |
Schedules & RSS 自動化 (/schedules)
定期ニュースレター配信(テンプレートまたはニュース投稿)、対話型の月間配信カレンダー、周期エンジン、動的オーディエンス指定、ブログRSS/Atomの自動Campaigns。
スケジュール・RSS・ニュース投稿 UIインスペクター
下の各コンポーネントをクリックして、DBクエリ、スキーマへの影響、運用ヒントを確認できます
カレンダー & 月間マトリックス
視覚的スケジュールマップ & ケイデンス定期実行エンジン
毎日・毎週・毎月 & カスタム自動ブログクローラー
ハッシュ重複排除 & キャッシュ動的オーディエンス
実行秒にタグを動的クエリ実行ログ
実行監査 & 重複配信防止即時実行 Run Now
スケジュールを変更せず即時配信サーバー最適化
厳選された8つの運用ガイドラインCron Heartbeat & ロック
ノンブロッキング並行実行ガードニュース投稿モード
Substack風のニュースレター5.1 デュアルモード運用: スケジュールマネージャー & カレンダービュー
MarbleSendは業務スタイルに合わせた2つの同期表示を提供します。コンパクトなBentoグリッドマネージャー(/schedules)と広範な月間カレンダー(/schedules/list)です。
高密度テーブル & Bentoビュー
次回配信カウントダウン、アクティブトグル、テンプレートプレビュー、直接実行ショートカットとともに全定期タスクを表示します。
7列インタラクティブカレンダーグリッド
日曜日から土曜日の標準カレンダー上で将来の配信を視覚化。当日ハイライト、月切り替え、クリック可能なイベントチップを搭載しています。
選択スケジュールの詳細ドロワー
安全なサンドボックス内テンプレートプレビュー、定期配信ルール、宛先タグルール、クイック操作を備えた即時インスペクションドロワー。
5.2 ケイデンスエンジン、繰り返しルール & UTCタイムゾーン正規化
定期配信はSchedulerService::computeNextRun()によって処理され、手動のタイムスタンプ計算を排除し、堅牢なPHP DateTimeImmutable演算を採用しています。
UTCでの一元保存とローカル時間での表示
すべてのnext_run_at値はcm_schedules内にUTCで保存されます。ブラウザ表示時には管理者の表示タイムゾーンに変換され、配信ウィンドウを保持します。
日次および週次の繰り返し
指定時刻での毎日の配信や、曜日ピルボタンによる特定の曜日(火曜と木曜の朝など)の選択をサポートします。
月次の日付自動クランプ調整
毎月29〜31日に設定された配信の場合、日数が少ない月(2月28/29日など)ではその月の最終日に自動調整されます。
タイムゾーンと夏時間(DST)の自動調整
ネイティブのPHP DateTimeZone計算を使用し、夏時間の移行時でも指定した現地時間に正確にトリガーされます。
5.3 自動RSS & Atomフィードクローラーパイプライン
MarbleSendはネイティブのSimpleXMLとcURLを使用してブログやフィードに直接接続し、サードパーティツールなしで新着記事を自動Campaignsに変換します。
デュアルフォーマットパーサー (RSS 2.0 & Atom 1.0)
外部ライブラリなしでXMLルート要素を自動検査し、タイトル、要約、パーマリンク、公開タイムスタンプを抽出します。
配信前のリアルタイムフィード診断
「Test Feed」ボタンによりフィードURLへリアルタイム接続し、XMLスキーマを検証、HTTP 200を確認して最新3記事をプレビューします。
重複排除 & 初期スナップショット
last_rss_item_idと公開日を追跡します。作成時に最新記事IDを基準点として記録し、過去のアーカイブ記事を遡って配信することを防ぎます。
5.4 実行時の動的オーディエンス解決 & 宛先ターゲティング
スケジュールの対象はグループにも絞り込めます(タグと併用する場合は両方に一致が必要)。そのグループが削除されると、誰にも送らないまま動き続ける代わりにスケジュールが無効になります。
静的なCampaignスナップショットとは異なり、定期スケジュールはイベントがトリガーされるまさにその秒に宛先リストを動的に決定します。
リアルタイムのオーディエンス自動拡張
配信直前に登録されたりタグが付与された購読者も、手動のre-syncなしで次回の配信に自動的に組み込まれます。
厳格な到達性ステータスフィルター
配信クエリはWHERE status = 'active'を強制し、保留中、配信停止、抑制リストの連絡先を定期キューから確実に除外します。
タグベースのセグメント隔離
全アクティブ連絡先への配信のほか、JSONタグ配列(例: #weekly-digest, #customers)に一致する特定セグメントのターゲティングに対応します。
5.5 実行ログ、監査 & 単一キャッチアップポリシー
各自動実行はcm_schedule_occurrencesに不変の監査レコードを作成し、実行時刻、結果、宛先数、エラーテレメトリを記録します。
3つの状態を持つ実行テレメトリ
'completed'(キュー投入完了)、'skipped'(新着記事なし)、'failed'(SMTP切断、無効テンプレート、ネットワークタイムアウト)を明確に区別します。
単一キャッチアップによる冪等性保護
複数の予定期間中にcronワーカーが停止していた場合、復旧時に最大1回のみキャッチアップ配信を行い、next_run_atを未来に進めます。
実行履歴監査モーダル
サイドバーの「View Execution History」をクリックすることで、過去の実行履歴、宛先ボリューム、エラー診断ログをUI上で直接確認できます。
5.6 オンデマンド手動配信 ("Run Now") & 緊急オーバーライド
管理者はカウントダウンをスキップし、「Trigger Send Now」アクションを使用して任意のスケジュールの臨時配信を即座に開始できます。
即時キューコンパイル
テンプレートを即座にコンパイルし、アクティブな対象者を解決してcm_email_queueにバッチ投入し、次回のワーカーサイクルに備えます。
既存の定期配信スケジュールの維持
手動即時配信を実行しても、予定されているnext_run_atのタイムスタンプがずれたり遅延したりすることはなく、通常のカレンダー周期を維持します。
診断 & 速報発信用ユーティリティ
実際の購読者データでテンプレートの表示確認を行ったり、営業時間外に緊急のお知らせを急遽配信する用途に最適です。
5.7 フェイルセーフ並行処理、重複防止 & ノンブロッキングファイルロック
MarbleSendは安価な共有サーバー環境においてメールの重複配信を防止するためのエンタープライズ並行処理制御を備えています。
ノンブロッキングflock並行性ロック
worker.phpはstorage/worker.lockの排他flockロックを取得します。前回の実行が高レイテンシSMTPリレーで処理中であれば、後続の呼び出しは静かに終了します。
デュアルワーカーのプロトコル同等性
CLI worker.phpとHTTP cron.phpは同一の実行パスとロック機構を共有し、cPanel cronと外部webhook間で一貫した動作を保証します。
アトミックなタスク予約
実行予定のスケジュールはアトミックなPDOプリペアドステートメントで予約され、マルチスレッド環境でもキューの重複投入を防ぎます。
5.8 共有サーバー向けチューニング & 厳選された8つの最適化ヒント
Schedulesページの動的Optimization Tipカードは、共有サーバーでの安定配信のために実証済みの8つの運用推奨事項を提供します:
最高の開封率とクリック率を得るには、受信者の現地時間の火曜日または木曜日の09:00〜10:30の間に配信をスケジュールします。
プロセスの衝突なしに秒単位の正確性を確保するため、flock保護を有効にしてworker.phpを毎分(* * * * *)実行します。
ピーク時の競合状態(race condition)を排除するため、LIMIT句を含むインデックス付きプリペアドステートメントでcm_email_queueを照会します。
連絡先を地域タグ(#us-east, #apac, #emea)で分類し、深夜3:00のメール配信を避けるために分散スケジュールを割り当てます。
CDNエッジノードとXMLキャッシュが完全に同期するよう、CMSでブログ記事が公開されてから1〜2時間後にRSS配信をスケジュールします。
共有サーバー上でテーブルサイズを軽量に保ちインデックスを最適に維持するため、cm_schedule_occurrencesから過去ログを定期的に削除します。
件名を新しくしてopened_at IS NULLの購読者に48〜72時間後に再送することで、15〜25%のエンゲージメントを取り戻せます。
送信ドメインの評判を保護するため、自動RSS通知と大量のマーケティング配信にはそれぞれ別個のSMTPプロファイルを割り当てます。
5.9 ニュース投稿スケジュール(Substack風ニュースレター)
ニュースレターのスケジュールは、固定のテンプレート1つではなく記事を送信できるようになりました。コンテンツソースを「ニュース投稿」にすると、各実行でテンプレート → 投稿の次の準備完了の投稿が配信され、{{news_posts}} 経由でテンプレートに挿入されます。待機中の投稿がなければ何も送信されません。
どのコンテンツソースを使うべきですか?
テンプレートのみ
毎回同じテンプレートを送信します。定期的なお知らせやリマインダー向けです。スマート除外が使えます。
RSSダイジェスト
外部ブログフィードの新着投稿。初回実行では既存の投稿を既読にするだけで、以降の実行は新着投稿だけを送信します。
ニュース投稿
MarbleSend内で書く記事です。準備完了の各投稿は古い順に1回ずつ送信されます。Substack風のニュースレターに最適です。
6ステップで設定
- 1テンプレート → 投稿を開き、Markdownで記事を書きます。
- 2テンプレートを作成または開き、記事を表示したい場所に {{news_posts}} を置きます(「ニュース投稿ニュースレター」スターターにはすでに含まれています)。
- 3スケジュール → 新規を開き、タイプはニュースレターのままにして、コンテンツソースを「ニュース投稿」に設定します。
- 4テンプレート、オーディエンス、SMTPプロファイル、メールあたりの投稿数(1〜20)、周期を選びます。
- 5保存します。このスケジュールが送信できるのは、この時点より後に準備完了になった投稿だけです。
- 6投稿を準備完了にします。次回の実行、または今すぐ実行で配信されます。
実行ごとに送信される投稿
各実行で、スケジュールは次の4つのルールをこの順で使って投稿を選びます。
準備完了のみ
下書きは、どれだけ古くても無視されます。
カットオフ以降
投稿は、スケジュールのニュース投稿モードがオンになった後に準備完了になっている必要があります。既存のアーカイブが再送されることはありません。
このスケジュールでまだ未送信
配信はスケジュールごとに記録されるため、2つのスケジュールがそれぞれ同じ投稿を1回ずつ送信できますが、2回送信することはありません。
古い順、上限まで
「メールあたりの投稿数」(既定1、最大20)が、まとめる数を制限します。残りは次回の実行を待ちます。
各実行が記録するもの
各実行はスケジュールの履歴に表示されます。投稿が配信済みとして記録されるのは、メールのバッチが実際にキューに入ったときだけです。
送信済み
Campaignが作成されキューに入りました(例:「1 post · 5 recipients queued」)。投稿はこのスケジュールによって送信済みと記録されます。
スキップ:新しい投稿なし
待機中の準備完了の投稿がありません。何も送信されず、スケジュールは次回の実行で再試行します。
スキップ:受信者なし
オーディエンスが空でした。投稿は保留のままで、オーディエンスにアクティブな連絡先ができ次第送信されます。
失敗
テンプレートが存在しないか、{{news_posts}} が含まれなくなりました。投稿は保留のままです。テンプレートを修正して再実行してください。
今すぐ実行とテスト送信
今すぐ実行
実際の実行で、ワーカーが約1分以内に処理します。保留中の投稿を送信し、配信済みとして記録します。
テストダイジェストを送信
次の保留中の投稿(なければ最新の準備完了の投稿)を、スケジュール自身のSMTPプロファイルで1つのアドレスに送信します。配信済みとしては記録されず、1分あたり5件のテスト上限を共有します。
編集と一時停止
- スケジュールをテンプレートのみからニュース投稿に切り替えると、その時点で新しいカットオフが設定され、戻すと消えます。
- スケジュールフォームを保存すると、テンプレートに {{news_posts}} が含まれているか再確認されます。一時停止と再開はオン/オフのスイッチを切り替えるだけで確認は行わないため、常に一時停止できます。
- ニュース投稿モードではスマート除外は自動的にオフになります。オンだと、以前の号を受け取った全員を除外してしまうためです。
- ニュース投稿はニュースレタースケジュール専用です。RSSスケジュールは独自のフィードロジックを保ちます。
スケジュール画面の見方
- スケジュール一覧では、これらのスケジュールが「ニュースレター」ではなく「ニュース投稿」と表示されます。
- 詳細パネルには、このスケジュールで待機中の準備完了の投稿数が表示されます。
- フォームでは、{{news_posts}} のないテンプレートに印が付き、選ぶと警告が表示されます。
簡易トラブルシューティング
| 症状 | 確認すること |
|---|---|
| 準備完了の投稿が送信されませんでした | スケジュールの保存(またはニュース投稿への切り替え)の後に準備完了になったか、スケジュールが有効かを確認し、履歴の「no recipients」または「failed」を見てください。 |
| 投稿を書いた直後にスケジュールが「no new posts」と表示します | 投稿がまだ下書きか、このスケジュールですでに送信済みの可能性があります。テンプレート → 投稿を開き、バッジと「送信済み N×」を確認してください。 |
| 保存できません:テンプレートに {{news_posts}} が必要です | プレースホルダーをテンプレート本文に追加するか(件名だけでは不可)、別のテンプレートを選んでください。 |
| 古い投稿を再送したい | その本文を新しい投稿にコピーして準備完了にしてください。スケジュールが同じ投稿を2回送信することはありません。 |
Settings &インフラストラクチャ (/settings)
SMTP マルチリレー管理、cron ハートビート、23言語対応、配信到達性診断、およびライセンス認証。
Settings・インフラストラクチャ UI Inspector
下のコンポーネントをクリックして、データベーススキーマへの影響、バックグラウンド処理、運用ガイドラインを確認してください
SMTP プロファイル
自前 SMTP と管理型 SES リレーWorker と Cron
1分ごとの実行間隔23言語&テーマ
RTL ミラー&ダーク/ライトモードREST API キー
スコープ付き開発者アクセスイベント Webhook
HMAC-SHA256 イベントプッシュ到達性スイート
SPF、DKIM、DMARC & BIMIAI プロバイダー
BYOK と MarbleSend クレジットEd25519 ライセンス
暗号化グラントトークン6.1 デュアル配信アーキテクチャ: 自前 SMTP & 管理型 Amazon SES リレー
MarbleSend は 2 つの堅牢なトランスポートモデルによりキャンペーン実行と配信リレーを分離します: (1) 既存メールサーバーを接続する Bring Your Own (BYO) SMTP、(2) AWS 設定や IP ウォーミングなしで即座に企業規模クラウド配信が可能な Amazon SES 経由の MarbleSend SMTP。柔軟なプロファイル紐付け、デフォルトへの安全なフォールバック、原子的クレジット管理を完備しています。
Postmark、Mailgun、Brevo、SendGrid、Resend、またはサーバーの cPanel メールボックスなど標準 SMTP プロバイダーを接続。STARTTLS 対応ポート 587、暗黙的 SSL/TLS ポート 465、ローカルリレー用ポート 25、カスタム認証と送信者ヘッダーの分離をサポートします。
6.1.1 SMTPサーバープロバイダー(無料、商用、共有ホスティング)
SMTPディレクトリ&比較標準SMTP認証情報を使用して自前のメール配信を接続します。専用サイバークラウドまたは既存のホスティングから選択します。
標準の共有ホスティングメールボックスには厳しい送信制限(通常1日100〜500通)があります。マーケティング配信には、ビジネスメールプランへのアップグレードまたはクラウドリレーの利用を推奨します。
大量送信と高い到達率のために最適化されています。
| プロバイダー / ウェブサイト | 無料枠 | 商用価格 | SMTPホスト&ポート | 主なルールと制限事項 |
|---|---|---|---|---|
| Amazon SES (Direct) | Free tier on EC2 only (62k/mo); Otherwise pay-as-you-go | $0.10 / 1,000 emails ($1 per 10k) | email-smtp.<region>.amazonaws.com Port 587 (TLS) or 465 (SSL) |
Requires AWS account setup, IAM SMTP user credentials, and sandbox exit request. |
| Brevo | 300 emails / day (Free forever) | Starter from ~$9/mo (5k emails) to ~$18/mo (20k emails) | smtp-relay.brevo.com Port 587 (TLS) |
Free tier resets daily. Great for low-volume testing without entering a credit card. |
| Mailgun (Sinch) | Trial (5,000 emails for 30 days) | Foundation: $35/mo (50,000 emails); Scale: $90/mo | smtp.mailgun.org (or smtp.eu.mailgun.org) Port 587 (TLS) or 465 (SSL) |
Robust analytics and deliverability. Supports EU data residency. |
| Twilio SendGrid | 100 emails / day (Free forever) | Essentials: ~$19.95/mo (50k emails); Pro: ~$89.95/mo | smtp.sendgrid.net Port 587 (TLS) (User: apikey) |
Requires Two-Factor Authentication. Username must literally be apikey. |
| Postmark (ActiveCampaign) | Free Developer trial: 100 emails/mo | From $15/mo (10,000 emails), $55/mo (50,000 emails) | smtp.postmarkapp.com Port 587 (TLS) or 2525 |
Industry-leading transactional speed and strict spam filters. Separate broadcast streams required. |
| Resend | 3,000 emails / month (100 / day free) | Pro: $20/mo (50,000 emails/mo) | smtp.resend.com Port 465 (SSL) or 587 (TLS) (User: resend) |
Modern developer experience, clean UI, quick domain verification via DNS. |
通常のcPanelメールボックスは日常の連絡向けであり、一斉配信には厳しく制限されています。
Business Email Plans (Per Mailbox)
1 GB storage, 1 forwarding rule, 1 alias, up to 100 mailboxes/domain. Standard webmail & antispam. Strict sending cap (~100-200/day).
5 GB storage, 5 forwarding rules, 5 aliases, expandable mailbox storage. No mailbox limit per domain.
20 GB storage, 20 forwarding rules, 10 aliases, AI Kodee mailbox assistant & smart replies.
50 GB storage, 50 forwarding rules, 30 aliases, full AI suite & priority deliverability.
Hostinger Reach (Email Marketing)
100 recipients, 200 emails / month. Suitable for basic transactional testing.
500 recipients, 500 emails / month, 10 AI credits, remove Reach branding, automations.
1,000 recipients, 7,000 emails / month, 20 AI credits, custom HTML code, send-time optimization.
• cPanel Shared: Max ~500 emails/hour per cPanel domain.
• Private Email: Starter (~$1.24/mo per mailbox, 5GB). Pro (~$2.82/mo, 30GB).
• SMTP Host: mail.privateemail.com (Port 465 SSL or 587 TLS).
• Shared cPanel: Default cap ~500 emails/hour. Internal mail system may defer large sudden bursts.
• Professional Email: Integrated with Microsoft 365 or Google Workspace ($2.99–$9.99/mo).
• SMTP Host: box###.bluehost.com or mail.yourdomain.com (Port 465 SSL).
• Site Tools Mail: Included in hosting (StartUp, GrowBig, GoGeek).
• Rate Limits: ~400 emails/hour on StartUp; up to ~800/hour on GoGeek. Strictly intended for transactional mail.
• SMTP Host: mail.yourdomain.com (Port 465 SSL).
• Paid Business Email: ~$1.99/mo per mailbox (25GB storage).
• Strict Outbound Policy: Maximum 100 recipients per hour. Mass marketing prohibited via shared SMTP.
• SMTP Host: smtp.dreamhost.com (Port 465 SSL or 587 TLS).
• cPanel Limit: Max 500 emails/hour per domain on shared plans.
• Workspace Option: Google Workspace addon ($6–$18/mo).
• SMTP Host: mail.yourdomain.com (Port 465 SSL or 587 TLS).
• M365 Reseller: Email Essentials from ~$1.99–$5.99/mo (10GB-50GB).
• SMTP Relay Note: Direct SMTP AUTH requires enabling Authenticated SMTP in the M365 Admin Portal.
• SMTP Host: smtp.office365.com (Port 587 TLS).
サーバー環境とファイアウォールに合わせて適切なポートを選択してください。
The modern standard for email client-to-relay submission (RFC 6409). Starts in cleartext and immediately upgrades connection to TLS. Supported by almost all cloud relays.
Implicit TLS/SSL wrapper connection (RFC 8314). Required by Hostinger, Namecheap cPanel, and selected enterprise relays. Highly reliable when hosting firewalls restrict 587.
Server-to-server MTA routing. Almost universally blocked on cloud hosts (Hostinger, AWS, DigitalOcean, Hetzner, etc.) to combat spam. Do NOT use for outbound SMTP credentials.
6.1.1 マネージド Amazon SES Relay とカスタム送信者ドメイン
MANAGED SESapi.marblesend.com を通じて MarbleSend が管理するエンタープライズクラウド配信インフラストラクチャ。共有ホスティングにおける SMTP ポート遮断、IAM 認証情報管理、IP レピュテーションリスクを排除します。2 つの送信者モード(Friendly From と Easy DKIM)、無料スタータークレジット、アトミック ledger 監査、オンデマンドの動的スケーリングを提供します。
MarbleSend が設定・管理する企業向け Amazon SES クラウド配信。AWS アカウント作成、IAM 認証情報管理、IP ウォーミングは一切不要。決済サービス事業者経由でオンデマンドにクレジットをチャージし、リアルタイムに残高を確認できます。
MarbleSend SES 経由で送信される各メールは、キュー項目の UUID 冪等性(cm_addon_ledger.uq_addon_ledger_key)を用いて原子的に 1 クレジットを仮確保します。リレー送信に失敗した場合は手動操作なしで即時解放・返金されます。
Test Connection モーダルは MailerFactory 経由で即時 SMTP ハンドシェイクとテスト送信を実行。認証エラー(535 Auth Failed)、リレー拒否(550 Relay Denied)、TLS タイムアウトを生のソケット対話で即座に診断できます。
一斉配信キャンペーン、定期スケジュール、自動応答は cm_campaigns.smtp_profile_id により個別の SMTP プロファイルに紐付け可能。未指定の場合はデフォルト設定(is_default = 1)へ自動ルーティングされます。
BYO SMTP と MarbleSend SES のいずれを選択した場合でも、送信元ドメインに有効な SPF、DKIM、DMARC レコードが必須です。MarbleSend 組み込みの 4 柱配信診断ツールが DNS を能動的に検査し、受信箱への確実な到達を支援します。
6.1.2 SES Relay での送信ルール
Amazon SES はリストをきれいに保つ送信者向けのサービスであるため、これらのルールはこのアプリだけでなく MarbleSend のリレー自体が強制します。無効にすることはできず、SES Relay 経由で送信されるすべてのメールに適用されます。
最初の送信の前に、Settings → SMTP設定 → 送信者情報と許容される利用 で、法的名称、郵送先住所、国、電話番号を入力し、利用規定(Acceptable Use Policy)に同意してください。保存するまで送信はブロックされたままです。名前と住所はすべてのメールのフッターに表示され、電話番号は表示されません。
すべてのキャンペーン本文に {{unsubscribe_link}} タグが必要で、ない場合は送信が拒否されます。さらにリレーが List-Unsubscribe とワンクリックのヘッダー、および名前・住所・配信停止リンク・「Sent with MarbleSend」を含むフッターを追加します。フッターは削除できません。
SES Relay を使用している間、登録ページと API は常に double opt-in を使い、公開登録には Cloudflare Turnstile が必須で、CSV インポートでは全員が許可したことを確認するチェックが必要です。配信停止した人や抑制(suppressed)された人は、公開フォームから再登録できません。
ハードバウンスとスパム苦情は自動的に MarbleSend に届き、連絡先は suppressed になります。リレーは suppressed のアドレスへの送信も拒否し、クレジットは消費されません。ソフトバウンスは再試行され、繰り返し失敗した場合のみ抑制されます。
各アカウントには 1 日の送信上限があります(既定では 2,000 通)。バウンスや苦情の割合が高すぎる場合は、サポートがアカウントを確認するまで送信が自動的に一時停止し、ライセンスが無効な場合も停止します。Settings → SMTP設定 のバナーが理由を説明し、キュー内のメールは失われずに待機します。
メールは marblesend.com(確認済みの場合はご自身のドメイン)の DKIM で署名されます。Return path には mail.marblesend.com を使うため、SPF が整合し DMARC も通過します。返信は設定した Reply-To アドレスに届きます。
Easy DKIM 3件のCNAME設定ディレクトリ(マルチプロバイダー対応)
主要なホスティング会社やドメインレジストラでAWS SESのEasy DKIM用CNAMEレコード3件を正しく追加し、構文ミスを防ぎ即座に検証を完了するための実践的なDNS設定ガイドです。
ユニバーサルDNSアーキテクチャと基本原則
Easy DKIMは3件のCNAMEレコードを介して暗号署名をAmazon SESに委任します。AWSが手動のDNS更新を必要とせずに背後で1024/2048ビットRSAキーを自動ローテーションするため、これら3件のレコードは永続的に維持する必要があります。
| レコード種別 | ホスト名 / 名前 | 値 / ターゲット / 参照先 | TTL |
|---|---|---|---|
| CNAME | <token1>._domainkey.yourdomain.com | <token1>.dkim.amazonses.com | 300 (or Auto) |
| CNAME | <token2>._domainkey.yourdomain.com | <token2>.dkim.amazonses.com | 300 (or Auto) |
| CNAME | <token3>._domainkey.yourdomain.com | <token3>.dkim.amazonses.com | 300 (or Auto) |
原則1:「二重ドメイン」の罠に注意
多くの管理画面はホスト名欄の末尾にルートドメイン名を自動補完します。「token._domainkey.yourdomain.jp」と貼り付けると「token._domainkey.yourdomain.jp.yourdomain.jp」として解決され、検証が失敗します。完全修飾名が明示的に要求されない限り、必ず「token._domainkey」のみを入力してください。
原則2:TXTではなくCNAMEを使用
静的公開鍵を含むTXTレコードを使う従来のDKIMとは異なり、Amazon SES Easy DKIMはtoken.dkim.amazonses.comを直接参照する3件のCNAMEレコードを使用します。TXTを選択しないでください。
原則3:プロキシ無効化(Cloudflare グレークラウド)
Cloudflare等をご利用の場合、3件のDKIM CNAMEレコードは「DNSのみ(グレーの雲 / プロキシ無効)」に設定してください。HTTPプロキシはCNAME先を隠蔽し、メールの暗号検証を阻害します。
# Check resolution via dig (macOS / Linux): dig CNAME <token1>._domainkey.yourdomain.com +short # Check resolution via nslookup (Windows / PowerShell): nslookup -type=CNAME <token1>._domainkey.yourdomain.com
Hostinger (hPanel DNSゾーン)
hPanel DNS| レコード種別 | ホスト名 / 名前 | 値 / ターゲット / 参照先 | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (hPanel auto-appends .yourdomain.com) | <token>.dkim.amazonses.com | 300 (or 14400) |
Hostinger hPanelダッシュボードにログインし、「ドメイン」に移動します。
対象ドメインを選択し、左サイドバーの「DNS / ネームサーバー」をクリックします。
DNSレコードの管理で、タイプをCNAMEに切り替えます。
名前欄には「token._domainkey」のみを入力します(hPanelが自動補完します)。
ターゲットに「token.dkim.amazonses.com」を入力し、TTLを300またはデフォルト(14400)にします。
「レコードを追加」をクリックし、3件すべてのトークンについて同様に繰り返します。
DreamHost (DreamHost Webパネル)
DreamHost Web Panel| レコード種別 | ホスト名 / 名前 | 値 / ターゲット / 参照先 | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (DreamHost appends .yourdomain.com) | <token>.dkim.amazonses.com | Default |
DreamHost Webパネルにログインし、Websites > Manage Websitesに移動します。
ドメインを探し、DNS Settingsをクリックします。
「Add a custom DNS record」までスクロールし、Add Recordをクリックします。
Name欄に「token._domainkey」を入力します(ドメイン名は自動付与されます)。
TypeをCNAMEにし、Value欄に「token.dkim.amazonses.com」を入力します。
Save / Add Recordをクリックして保存します。3件すべて繰り返します。
Namecheap (アドバンスドDNS)
Advanced DNS| レコード種別 | ホスト名 / 名前 | 値 / ターゲット / 参照先 | TTL |
|---|---|---|---|
| CNAME Record | <token>._domainkey (never paste root domain here) | <token>.dkim.amazonses.com | Automatic (or 1 min) |
Namecheapにログインし、Domain Listからドメイン横のManageをクリックします。
上部の「Advanced DNS」タブに切り替えます。
Host Recordsセクションで赤色の「ADD NEW RECORD」ボタンをクリックします。
Typeプルダウンから「CNAME Record」を選択します。
Host欄には「token._domainkey」のみを入力します(ドメイン名は入力不要です)。
Targetに「token.dkim.amazonses.com」を入力し、TTLをAutomatic(または1 min)に設定して緑のチェックマーク✓で保存します。3件すべて登録します。
Bluehost (アカウントマネージャー / Zone Editor)
Bluehost DNS| レコード種別 | ホスト名 / 名前 | 値 / ターゲット / 参照先 | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (Bluehost handles suffix automatically) | <token>.dkim.amazonses.com | 4 Hours (or Default) |
Bluehostアカウントマネージャーにログインし、Domainsから対象ドメインを選択します。
DNSタブに移動します(従来のプランではcPanel Zone Editorを開きます)。
CNAME (Alias) セクションまでスクロールし、Add Recordをクリックします。
Host Record欄に「token._domainkey」を入力します。
Points To欄に「token.dkim.amazonses.com」を入力し、TTLを選択します。
Saveをクリックします。残り2件のCNAMEも同様に登録します。
SiteGround (Site Tools DNSゾーンエディター)
Site Tools DNS| レコード種別 | ホスト名 / 名前 | 値 / ターゲット / 参照先 | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (Site Tools appends .yourdomain.com) | <token>.dkim.amazonses.com | 1 hour (3600) |
SiteGroundクライアントエリアにログインし、WebsitesからSite Toolsを開きます。
左側メニューの「Domain」を展開し、「DNS Zone Editor」をクリックします。
レコード作成画面で「CNAME」タブを選択します。
Name欄に「token._domainkey」を入力します(右側にドメイン名が固定表示されます)。
Resolves To欄に「token.dkim.amazonses.com」を入力し、TTLを1時間(3600)のままにします。
Createをクリックします。3件すべて同様に登録します。
HostGator (cPanel Zone Editor)
cPanel Zone Editor| レコード種別 | ホスト名 / 名前 | 値 / ターゲット / 参照先 | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (cPanel automatically appends dot) | <token>.dkim.amazonses.com | 14400 (or 3600) |
HostGatorポータルにログインし、cPanelを開きます。
「Domains」セクション内の「Zone Editor」をクリックします。
ドメインを探し、「+ CNAME Record」をクリックします。
Name欄に「token._domainkey」を入力します(ドメイン名とドットが自動補完されます)。
CNAME / Record欄に「token.dkim.amazonses.com」を入力します。
Add a CNAME Recordをクリックします。3件すべて登録します。
GoDaddy (ドメインポートフォリオ DNS)
GoDaddy DNS| レコード種別 | ホスト名 / 名前 | 値 / ターゲット / 参照先 | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (never include root domain in GoDaddy) | <token>.dkim.amazonses.com | 1/2 Hour (or Default) |
GoDaddyアカウントにログインし、「マイプロダクト」を開きます。
対象ドメインの横にある「DNS」(または3点アイコン > DNSの管理)をクリックします。
DNSレコードセクションで「新しいレコードを追加」をクリックします。
種別プルダウンで「CNAME」を選択します。
名前欄には「token._domainkey」のみを入力します(ドメイン名は絶対に入力しないでください)。
値に「token.dkim.amazonses.com」を入力し、TTLを1/2時間(またはデフォルト)にして保存します。3件すべて登録します。
3件のCNAMEレコードを保存後、DNSの伝播には通常5〜30分(TTLにより最大24〜48時間)かかります。MarbleSendの「設定 > SMTP」に戻り、カスタム送信ドメインカードの「DNSを検証」をクリックしてください。Amazon SESにより確認されると、ステータスが「検証済み」に切り替わります。
6.2 バックグラウンド Worker ハートビート、1分 Cron & Concurrency Guard
MarbleSend はバックグラウンドでメールを送信します。cron ジョブは、ホスティングパネルにあるタイマーで、毎分 MarbleSend を起こして、スケジュールや autoresponder の実行、失敗した配信の再試行、bounce の収集、長い Campaign の継続を行わせます。送信した Campaign はすぐに始まりますが、あとで行う必要のある処理はすべてこのタイマーに依存します。Settings → システム に Cron未検出 と表示される場合、タイマーがない、毎分動いていない、または場所が間違っています。下の 3 つの手順で解決できます。
Settings → システム を開き、Cron Job コマンド を探して コマンドをコピー をクリックします。この行にはすでに正しい folder が含まれており、サーバーが教えてくれる場合は正しい PHP も含まれています。そのまま使ってください。このページの下にある例は行の形を示すだけです。Settings が PHP を検出できなかったと表示した場合は、ホスティング会社に PHP のコマンドラインのパスを尋ね、行の先頭の php を置き換えてください。
下からホスティング会社を選んでください。メニュー名は時々変わるので、最も近いものを探してください。どのパネルでも、ジョブは毎分 (* * * * *) 実行する必要があり、コマンドは手順 1 の行です。Plesk、DirectAdmin などのパネルでは Scheduled Tasks または Cron Jobs と呼ばれます。
Hostinger (hPanel)
- サイトの hPanel → Websites → Dashboard を開き、サイドバーの Cron Jobs をクリックします。
- Type を Custom に設定します。(PHP タイプは .php file のパスだけを受け付けます。あなたの行には PHP コマンドも含まれています。)
- 手順 1 の行を Command to run に貼り付けます。
- スケジュールを毎分に設定するか、* * * * * と入力します。
- Save をクリックします。ジョブは List of Cron Jobs に表示され、最後の出力も読めます。
Hostinger は cron ジョブを UTC で実行します。Single プランでは cron ジョブは 2 つまで、Premium 以上のプランでは無制限です。
Namecheap
Namecheap のホスティングアカウントから cPanel を開き、次の手順に従ってください。
- cPanel を開き、Advanced セクションの Cron Jobs をクリックします。
- Add New Cron Job で、Common Settings の Once Per Minute (* * * * *) を選びます。
- 手順 1 の行を Command に貼り付けます。
- Add New Cron Job をクリックします。これでジョブは毎分実行されます。
Namecheap は共有サーバーで、5 分より短い間隔の cron ジョブや、5 つを超える cron ジョブを許可していません。毎分必要な場合は、下の Web-Cron を使ってください。
Bluehost
- Bluehost Portal にログインし、Websites をクリックして、サイトの Manage Site をクリックします。
- Advanced タブを開き、Cron Jobs を見つけて Manage、続いて Add Cron をクリックします。
- Common Settings で頻度を選びます(または Minute、Hour、Day、Month、Weekday を入力します)。
- 手順 1 の行を Command に貼り付けて Add をクリックします。
Bluehost 自身のドキュメントには、共有ホスティングでは cron ジョブは 15 分以上の間隔でのみ実行されると書かれています(1 ページには 5 分とあります)。毎分必要な場合は、下の Web-Cron を使ってください。
HostGator
Customer Portal で Websites → Manage Site → Advanced を開き、Cron Jobs の下で Manage、続いて Add Cron をクリックします。フォームは cPanel と同じ項目なので、下の手順が当てはまります。または cPanel → Advanced → Cron Jobs を開いてください。
- cPanel を開き、Advanced セクションの Cron Jobs をクリックします。
- Add New Cron Job で、Common Settings の Once Per Minute (* * * * *) を選びます。
- 手順 1 の行を Command に貼り付けます。
- Add New Cron Job をクリックします。これでジョブは毎分実行されます。
HostGator のヘルプページには、共有ホスティングで許可される最短の間隔が書かれていません。毎分が拒否される場合は、下の Web-Cron を使ってください。
GoDaddy
GoDaddy の製品ページで、Linux Hosting の横の Manage をクリックし、cPanel Admin を開いて、次の手順に従ってください。
- cPanel を開き、Advanced セクションの Cron Jobs をクリックします。
- Add New Cron Job で、Common Settings の Once Per Minute (* * * * *) を選びます。
- 手順 1 の行を Command に貼り付けます。
- Add New Cron Job をクリックします。これでジョブは毎分実行されます。
GoDaddy のヘルプページには、許可される最短の間隔が書かれていません。毎分が拒否される場合は、下の Web-Cron を使ってください。
DreamHost
- DreamHost パネルを開き、Cron Jobs に移動して Add New Cron Job をクリックします。
- ユーザー(既存の SFTP または shell ユーザー)を選び、ジョブにタイトルを付け、必要なら出力用のメールアドレスを入力します。
- 手順 1 の行を Command に貼り付けます。DreamHost は PHP を /usr/local/php83/bin/php のようなパスに置いています(お使いの PHP バージョンを使ってください)。
- 実行時刻を設定し、2 つの実行が重ならないよう locking をオンにして、保存します。
カスタムのタイミングでは、パネルで選べるのは 1 時間あたり最大 12 の異なる分までなので、作れる最短の定期スケジュールは 5 分ごとです。時刻は太平洋時間です。毎分必要な場合は、下の Web-Cron を使ってください。
SiteGround
- Site Tools → Devs → Cron Jobs を開きます。
- リストから間隔を選びます(または分、時、日、月、曜日を設定します)。
- 手順 1 の行を Command に貼り付けます。出力用のメールアドレスは任意です。
- Create をクリックします。
SiteGround のドキュメントには Twice Per Hour などのプリセットが載っていますが、最短の間隔は書かれていません。プランに毎分のオプションがない場合は、下の Web-Cron を使ってください。
- Settings → システム を開き、Web-Cron URL をコピーします。秘密のトークンが含まれているため、非公開にしてください。
- cron-job.org などの cron サービスで無料アカウントを作成します。
- ジョブを作成し、URL を貼り付けて、毎分実行するように設定します。保存して有効にします。
- Web-Cron とホスティング会社の cron ジョブは、どちらか一方だけを使ってください。両方は不要です。
1〜2 分待ってから Settings → システム を再読み込みします。バッジが 正常稼働中 になり、最終ハートビート に直近 1 分以内の時刻が表示されるはずです。同じページの サイトの状態 では worker が 合格 と表示されます。ホスティング会社が 5 分または 15 分ごとのジョブしか許可しない場合、バッジは直近 5 分以内の実行を期待するため、正常稼働中 と Cron未検出 の間で切り替わることがあります。それでも worker が実行されるたびにメールは送信されます。
- PHP コマンドが間違っています。ホスティング会社に PHP のコマンドラインのパスを尋ね(例: Hostinger では /opt/alt/php83/usr/bin/php、多くの cPanel ホストでは /usr/local/bin/php)、行の先頭の php を置き換えてください。
- 行の一部しか貼り付けられていません。末尾の >/dev/null 2>&1 を含めて、行全体を貼り付けてください。
- folder が違います。worker.php は public を含む folder にあり、public の中ではありません。
- エラーを確認するには、>/dev/null 2>&1 なしでジョブを一度実行し、その出力を読みます。正常な worker は worker.php: processed=0 のような行を出力します。
- ジョブが同じアカウントの別のサイト用になっています。コマンド内の folder を確認してください。
- 保存してから再確認するまで、最大 5 分待ってください。
技術に詳しい方向け
メールの作成、配信先リストの解決、送信処理、および webhook トリガーは、1分ごとのバックグラウンド worker を通じて非同期に実行されます。MarbleSend は、プロセスの競合を防ぐノンブロッキング file ロックで保護されたデュアルエントリーポイント構成(ネイティブ CLI worker.php または HTTP cron.php)を採用しています。
* * * * * php /home/USER/your-folder/worker.php >/dev/null 2>&1
OS のシェルから直接実行されます(* * * * * php /path/to/worker.php >/dev/null 2>&1)。HTTP タイムアウトや Web ゲートウェイの制限を完全に回避します。
GET https://your-domain.com/cron.php?token=SECURE_TOKEN
シェルアクセス権がないホスティング環境では、外部監視サービスから GET /cron.php?token=SECURE_TOKEN を呼び出すことで、同じキュー処理を安全にトリガーできます。
Worker は起動時に storage/worker.lock を flock(LOCK_EX | LOCK_NB) でロックします。以前の実行がまだ進行中の場合、後続の実行は競合することなく直ちに終了します。
インデックス付きステータスクエリを使用して、キューから50件ずつアトミックに取得します。失敗した送信は指数バックオフで再試行され、上限回数に達するとエラーとなります。
6.3 23のネイティブ言語、RTL アラビア語&管理者セキュリティ機構
MarbleSend は、グローバルにアクセス可能なセルフホスト型プラットフォームとして設計されています。人間が精査した23言語のネイティブ辞書、アラビア語の自動右横書き(RTL)レイアウトミラーリング、永続的なテーマカスタマイズ、厳格なシングルテナントセキュリティを提供します。
app/lang/*.php 内の言語ファイルは純粋な PHP 配列であり、gettext バイナリや外部翻訳 API を必要とせず、ミリ秒未満でメモリに読み込まれます。
アラビア語(ar)を選択すると、HTML ドキュメントに dir='rtl' が自動注入され、サイドバー、テーブル列、ドロワー、アイコンが UI 全体で反転配置されます。
ダーク、ライト、OS 設定の間でシームレスに切り替えます。選択内容は Cookie(marblesend_theme)に保存され、読み込み時の画面のチラつきを防ぎます。
cm_settings.admin_user 内の管理者情報は bcrypt(コスト係数 12)で暗号化されます。ログイン時のセッション ID 自動再生成によりセッション固定化攻撃から保護されます。
6.3.1 二要素認証(TOTP)と QR コードの設定
二要素認証は、管理者アカウントに 2 つ目の鍵を追加します。パスワードの後、MarbleSend は 30 秒ごとに変わり、あなたのスマートフォンだけが生成できる 6 桁のコードを求めます。任意の機能で、約 1 分で有効にでき、Google Authenticator、Microsoft Authenticator、1Password、Bitwarden、Authy、Aegis など、標準的な認証アプリならどれでも使えます。場所は Settings → 言語とアカウント → 二要素認証(TOTP) です。
MarbleSend はオープンな TOTP 標準(RFC 6238:HMAC-SHA1、6 桁、30 秒ステップ)を使用します。有効化するとランダムなシークレットが作成され、一度だけアプリと共有されます。以降のログインではパスワードに続いて現在のコードが必要です。使用済みのコードは再利用できず、2 段階目は 5 分で期限切れになります。
1)Settings → 言語とアカウント を開いて「有効にする」を押します。2)認証アプリで「QR コードをスキャン」を選び、画面に表示された四角い図をスキャンします。3)アプリに表示された 6 桁のコードを入力し、「確認して有効にする」を押します。4)一度だけ表示される 8 つのリカバリーコードを保存します。パスワードマネージャーにコピーするか、印刷してください。
QR 画像は、お使いのインストール環境が小さなベクターグラフィックとして描画します。シークレットがオンラインの QR ジェネレーターやその他の第三者に送信されることはありません。スキャンできない場合(たとえばアプリが同じスマートフォン上にある場合)は、QR コードの下に表示されるセットアップキーまたは otpauth リンクを使用してください。シークレットは、他のすべての認証情報と同様に、ENCRYPTION_KEY で暗号化(AES-256-GCM)して保存されます。
正しいパスワードの後に、6 桁のコードを求められます。誤ったコードはアカウントごとに試行回数が制限されるため、推測は現実的ではありません。正しく入力してもコードが拒否される場合は、スマートフォンの日付と時刻が自動設定になっているか確認してください。時計がずれていると誤ったコードが生成されます。
2FA を有効にすると、使い切りのコードが 8 つ作成されます。それぞれ、6 桁のコードの代わりにコード欄で一度だけ使えます。ハッシュとしてのみ保存されるため、再表示はできません。「新しいリカバリーコード」(現在のコードが必要)を使うとセット全体が置き換わり、古いコードは無効になります。
パスワードを忘れた場合にメールで届くリンクは、意図的に2FAを回避しないため、ここでは役に立ちません。サーバーで「php tools/reset-admin.php」を実行してください(SSH またはホスティングのターミナル)。管理者パスワードのリセット、ロックアウトの解除、すべてのセッションの終了、2FA の無効化が行われ、その後、新しい端末で再度有効にできます。通常の無効化は、同じカードの「無効にする」を使います(パスワードと、現在のコードまたはリカバリーコード)。
6.3.2 サインアップ保護(Cloudflare Turnstile):無料キーの取得方法
Turnstile は、Cloudflare が提供する無料でプライバシーに配慮した CAPTCHA の代替です。有効にすると、公開登録ページ(/s/your-page のフォームと /subscribe)は、購読を受け付ける前に訪問者が実在の人間であることを確認し、ボットによるリストや確認メールの氾濫を防ぎます。組み込みの honeypot と IP ごと・アドレスごとの制限に加えて動作し、SES Relay 経由で送信している間を除き任意です(最後の注記を参照)。ご自身の無料 Cloudflare アカウントから、Site key(公開)と Secret key(非公開)の 2 つのキーが必要です。ドメインの DNS に Cloudflare を使う必要はありません。
dash.cloudflare.com にアクセスして登録(無料)するか、ログインします。Turnstile を使うために、ウェブサイトを Cloudflare に追加したり DNS を変更したりする必要はありません。
ダッシュボードのメニューで「Turnstile」を開き(または検索し)、「Add widget」を押します(古いダッシュボードでは「Add site」)。メニュー名は時々変わります。Application security の下にある Turnstile を探してください。
好きな名前を付けます(例:「MarbleSend signup」)。Hostname に、MarbleSend が動作しているドメインを https:// やパスなしで追加します(例:app.yourdomain.com)。サインアップページが別のドメインで表示される場合は、そのドメインも追加します。localhost は、自分のコンピューターでテストするときだけ追加してください。
Managed(推奨)を選びます。ほとんどの訪問者はパズルなしで通過でき、Cloudflare は不審な訪問のときだけ簡単なクリックを求めます。Non-interactive はクリック不要の短い進行バーを表示し、Invisible は何も表示しません。pre-clearance はオフのままにして、Create を押します。
Cloudflare に Site key(公開)と Secret key(非公開)が表示されます。両方をコピーしてください。シークレットは、各訪問者を Cloudflare で確認するためにサーバーだけが使うものなので、公開の場所には絶対に貼り付けないでください。後からウィジェットの設定で確認やローテーションができます。
Settings → 言語とアカウント → 登録保護(Cloudflare Turnstile) を開き、Site key と Secret key を貼り付けて「保存」を押します。バッジが「保護は有効です」に変わります。後で無効にするには、両方の欄を空にして保存します。保存されたシークレットは暗号化されて保管され、二度と表示されません。維持するには欄を空のままにしてください。
公開サインアップページのひとつをブラウザーのプライベートウィンドウで開くと、ボタンの上に Turnstile ウィジェットが表示されます。テスト用アドレスで購読すると、確認メールが届くはずです。チェックを通過していない送信は拒否されます。
サーバーが Cloudflare の検証サービスに接続できない場合(障害または外向き接続のブロック)、MarbleSend は通常、すべての訪問者を締め出す代わりに登録を通し、その事象を記録します。honeypot と IP ごと・アドレスごとの制限は引き続き適用されます。SES Relay 経由で送信している間は逆に、フェイルクローズドとなり、Cloudflare に再び接続できるまで登録は拒否されます。
Cloudflare はテスト用のダミーキーを公開しています。Site key 1x00000000000000000000AA と Secret key 1x0000000000000000000000000000000AA の組み合わせは常に成功します。実際のサイトを保護するものではないため、公開前にご自身のキーに置き換えてください。
ウィジェットが表示されない:ページのホスト名が Turnstile ウィジェットに登録されているか、ブラウザー拡張機能が challenges.cloudflare.com をブロックしていないか確認してください。「Invalid site key」:Site key にスペースが含まれてコピーされたか、別のウィジェットのものです。本物の訪問者が拒否される:Secret key を貼り付け直してください。Site key と同じウィジェットのものである必要があります。
Managed Amazon SES Relay 経由で送信する場合、公開登録フォームでは Turnstile が必須です。2 つのキーを保存するまで、登録ページには「現在、登録を一時的にご利用いただけません」と表示され、Settings → 言語とアカウント には該当カードへ移動するボタン付きの通知が表示されます。このモードでは、登録ページや API 呼び出しが single opt-in を要求していても、新しい購読者は全員メールで確認(double opt-in)する必要があります。
6.4 スコープ付き REST API キー&開発者プログラムアクセス
REST API を使用すると、外部 Web サイト、ランディングページ、モバイルアプリ、および公式 WordPress プラグイン MarbleSend Forms が連絡先データベースや配信エンジンと安全に連携できます。API キーには暗号化プレフィックス、一方向 SHA-256 保存、きめ細かな権限スコープが採用されています。
キーは ms_ プレフィックスと random_bytes(24) による32バイトの暗号論的乱数で生成されます。生のシークレットトークンは作成時に1度だけ表示されます。
cm_api_keys.key_hash には SHA-256 ハッシュ(hash('sha256', $rawKey))のみが保存されます。万一データベースが流出しても、有効なトークンを復元することは不可能です。
キーを特定の権限に制限します:contacts:read、contacts:write、campaigns:read、campaigns:write、campaigns:send、schedules:read、schedules:write。
リクエストは Authorization: Bearer ms_... ヘッダーで認証され、hash_equals() で検証されます。テレメトリは呼び出しごとに正確な last_used_at タイムスタンプを記録します。
6.5 アウトバウンドイベント Webhook & HMAC-SHA256 暗号配信
連絡先イベント(subscribed、confirmed、unsubscribed、suppressed)には、tags に加えて {id, name} の groups 配列が含まれます。
Webhook は外部エンドポイントへのリアルタイム HTTP イベントストリーミングを提供し、CRM、Slack 通知、カスタム自動化が購読者の登録、Campaigns の配信、登録解除、ハードバウンスに即座に反応できるようにします。
重要なトリガーを購読します:contact.created、contact.unsubscribed、campaign.sent、campaign.bounced、link.clicked。各 webhook で個別に有効化できます。
各 webhook POST リクエストには、hash_hmac('sha256', $payload, $secret) で生成された X-MarbleSend-Signature: sha256=... ヘッダーが含まれ、受信側で検証可能です。
失敗した配信(HTTP 5xx またはタイムアウト)は指数バックオフ再試行をトリガーします。連続してエラーが発生するエンドポイントは自動的に一時停止されます。
Test Webhook ボタンはテストペイロードを即座に送信します。配信履歴ドロワーには HTTP ステータスコード、ミリ秒単位のレイテンシ、エラー応答が表示されます。
6.6 4本柱の到達性スイート(SPF、DKIM、DMARC、BIMI)
到達性は、メールが受信トレイに届くか迷惑メールフォルダに振り分けられるかを左右します。MarbleSend には組み込みの DNS 検査エンジンがあり、サードパーティ API を介さずに権威ネームサーバーへ直接4つの非ブロッキングクエリを実行します。
ルート TXT レコードの v=spf1 構文を検査します。承認された SMTP ホストメカニズムを検証し、DNS 参照制限(10回を超えるとエラー)を警告し、修飾子を分析します。
selector._domainkey.domain.com を照会して公開 RSA または Ed25519 キーを検証します。送信メールヘッダーが送信元ドメインに対して暗号検証できることを保証します。
_dmarc.domain.com のポリシータグ(p=none、p=quarantine、p=reject)を検査します。2026年現在、Gmail と Yahoo は一括送信者に対して rua レポート付きの有効な DMARC レコードを義務付けています。
SVG Tiny P.S. ブランドロゴと認証マーク証明書(VMC)について default._bimi.domain.com を照会し、受信トレイに公式ブランドアバターを表示できるようにします。
6.7 デュアルモード AI エンジン: BYOK プロバイダー & MarbleSend AI クレジット
MarbleSend はコピーライティング、件名生成、スパムスコア監査向けに柔軟なデュアルモード AI エンジンを提供します: (1) 手数料なしで主要 LLM に直結する Bring Your Own Key (BYOK)、(2) API キー管理なしで厳選された最高性能モデルを従量課金で即座に利用できる MarbleSend AI クレジット。
OpenAI、Anthropic Claude、Google Gemini、DeepSeek、Moonshot、OpenRouter、またはプライベート Ollama に直接接続。API キーは AES-256-GCM で安全に暗号化保存されます。中間マージンなしでサーバーから各社 API へ直接通信します。
MarbleSend が直接管理するプリペイド式 AI クレジット。メールマーケティングの成約率と到達性に特化して厳選された高効率モデルを提供します。ベンダー側で最適なモデル選定と更新を動的に行い、1 回の生成につき原子的に 1 クレジットを消費します。
Official add-on pricing is retrieved dynamically from admin.marblesend.com. Purchase top-up credit packs via global and local payment gateways with instant real-time balance activation.
All BYOK credentials are encrypted at rest with hardware-accelerated AES-256-GCM using your installation's unique APP_KEY. No prompt contents, contact lists, or recipient emails are ever stored or logged by the license server.
6.7.1 デフォルトモデルの選択と実行ルーティング
MarbleSend がアプリ全体で AI コピーライティング、件名の提案、到達性監査をどのように処理するかを定義します。公式リレーと独自の BYOK を柔軟に切り替えられます。
メールのコンバージョンに最適化された厳選モデルに設定不要でアクセス。開発者アカウントや API キーの管理は不要です。
手数料ゼロでサーバーからプロバイダーへ直接通信。登録済みのプロバイダーとモデルをデフォルトエンジンとして自由に指定できます。
テンプレートスタジオ、件名スコアインスペクター、AI アシストは設定されたデフォルトに従って動作し、クレジット残高不足時も安全に通知します。
現在の選択は cm_settings.ai_provider_default に安全に保存され、すべての管理者セッションと worker タスクで一貫して適用されます。
6.7.2 MarbleSend AI クレジットとマネージドリレーハブ
MarbleSend AI クレジットは、サードパーティの請求や利用枠の管理に煩わされることなく、メール執筆を従量制で即座に利用できる環境を提供します。
有効化されたすべてのライセンスに、ライセンスサーバーから取得した無料スタータークレジットが付与され、AI 機能をすぐに体験できます。
生成ごとに cm_addon_ledger 経由で正確に 1 クレジットが消費されます。一意のトランザクション UUID により通信リトライ時の二重引き落としを防ぎます。
クレジットパック(例: ai_100)は公式カタログから動的に読み込まれます。決済は当社の決済サービス事業者を通じて安全に処理されます。
購入完了後、Webhook により即座に残高へ反映されます。1 クリックの手動更新ボタンでサーバーの最新状態といつでも同期できます。
6.7.3 設定済みプロバイダーと BYOK インフラストラクチャ
暗号化されたキー保管、デュアル API プロトコル、リアルタイムの接続診断により、複数の外部 LLM サービスを一元管理します。
OpenAI、Anthropic Claude、Google Gemini、DeepSeek、Moonshot、OpenRouter、ローカル Ollama との同時接続を維持します。
標準の OpenAI 互換形式 (/chat/completions) と Anthropic 形式 (/v1/messages) をサポートし、独自のプロキシ Base URL にも対応します。
すべての BYOK API キーは AES-256-GCM で暗号化されて保存されます。HTML レスポンスやログに出力されることはありません。
接続テストボタンにより軽量なテストリクエストを送信し、本番適用前に認証状態と応答レイテンシ (ms) を確認できます。
主要プロバイダーの API キー取得手順
MarbleSend は BYOK 方式によりサードパーティのプロキシを介さず直接 AI プロバイダーと通信します。以下に公式コンソールのリンク、手順、モデル一覧をまとめました:
ローカル・セルフホストおよび代替プロバイダー(Ollama、Groq、Mistral、GLM)
費用ゼロのローカル AI を利用する場合は Ollama (ollama.com) をインストールしてモデルを実行(例: ollama run llama3.1)、Base URL を http://localhost:11434/v1 に設定し、OpenAI 形式を選択して "No Auth" にチェックを入れます。高速クラウド推論なら console.groq.com で無料 Groq キーを発行できます。
Settings ➔ AI Providers での設定手順 (/settings)
API キーとモデル ID を取得したら、MarbleSend で以下の簡単なステップに従って設定します:
メインサイドバーから Settings をクリックし、"AI Providers" タブに切り替えます(/settings から直接開けます)。
Quick Add の各プリセット(OpenAI、DeepSeek、Gemini、Anthropic など)をクリックして自動入力するか、"+ Add Provider" で個別追加します。
プロトコル形式を選択します(OpenAI format または Anthropic format)。事前入力された Base URL を確認してください。
秘密キーを入力欄に貼り付けます。MarbleSend は Crypto.php による AES-256-GCM で強力に暗号化し、平文で保存されることはありません。
利用したいモデル ID と context window を入力し、"Test Connection" をクリックしてリアルタイムに接続確認を行った上で保存します。
タブ上部の "Default AI Model" で設定したプロバイダーとモデルを選択し、"Save Default" をクリックすると全機能で有効になります。
6.8 暗号化 Ed25519 ライセンスグラントトークンエンジン
MarbleSend は、PHP ネイティブの libsodium 拡張機能を介して非対称 Ed25519 暗号化を使用し、製品の真正性を検証します。初回アクティベーション時に署名付き License Grant Token が発行され、常時接続不要でローカル検証されます。
sodium_crypto_sign_verify_detached() を使用してデジタル署名を検証します。データベースレコードに対する手動改ざんは即座に数学的署名を破綻させます。
署名付きトークンには、ライセンスドメイン名、プラン(Regular または Extended)、有効な機能が埋め込まれています。ドメイン移行は Settings から直接実行できます。
一時的なネットワーク障害やライセンスサーバーのメンテナンスによって、メール送信や cron タスクが中断されることはありません。制限前に7日間の猶予が与えられます。
ライセンスが失効した場合でも、購読者データ、Campaigns、分析レポート、エクスポートツールへのアクセスは 100% 維持され、新規配信のみが一時停止されます。
1日1回、ワーカーがライセンスサーバーに新しいバージョンがあるか問い合わせます。送信されるのは購入コードとインストール済みバージョンのみで、手動確認と同じです。このタブの「リリースの更新」でオフにできます。オフにすると確認は行われず、更新バナーも表示されません。開発用インストール(APP_ENV=local)はこの通信を行いません。連絡先やCampaignsに関する情報は一切送信されません。
「変更履歴」(サイドバーのドキュメントの上)には、各リリースがアップグレード手順とともに表示されます。新しいリリースがあると、ダッシュボードにバナーが表示され(セキュリティ更新はすべてのページに赤いバナーを表示し、閉じられません)、「変更履歴」の横にドットが表示され、有効な場合はバージョンごとに1通のメールがデフォルトのSMTPプロファイル経由で管理者アドレスに届きます。リリースノートは英語で書かれています。
よくある質問と診断
最も一般的な shared-hosting の問題に対する即時解決策。
7.1 Dashboard と運用診断
7.1.1 Dashboard に "Worker Not Detected" または非アクティブと表示されるのはなぜですか?
OS の crontab が実行されていないか、PHP CLI のパス指定が誤っているか、残存したロック file が実行を妨げています。
Worker は実行ごとに cm_settings.worker_last_run を UTC タイムスタンプで更新します。180秒以上経過するとダッシュボードが非アクティブと判定します。
Settings → System を開き、表示されている正確な crontab コマンドをコピーしてください。CLI が制限されている場合は cron-job.org で Web-Cron URL を1分毎に設定します。storage/worker.lock も確認してください。
7.1.2 Dashboard の開封率・クリック率が外部 SMTP プロバイダのログと異なるのはなぜですか?
Apple Mail Privacy Protection (MPP) による事前読み込み、プロキシキャッシュ、受信者による画像ブロック、UTM パラメータを削除する広告ブロッカーの影響です。
MarbleSend は cm_email_logs.opened_at を記録するために 1x1 の透明追跡 GIF を埋め込みます。画像ブロック時は未記録となり、Apple MPP は Apple サーバー到着時に即座に事前取得します。
最も確実な指標としてユニーククリック率 (CTR) を重視してください。MarbleSend はすべてのテンプレートリンクを public/click.php 経由でリダイレクトし、不正のないクリックを記録します。
7.2 Campaign 配信と Preflight 診断
7.2.1 Campaign の一斉配信が途中で一時停止または停止したのはなぜですか?
大量配信中に shared hosting の PHP CLI または Web サーバー実行時間制限 (max_execution_time 30s/60s) に達したためです。
MarbleSend はキューを50件ずつのアトミックなバッチで処理します。制限時間が近づくと worker は安全に終了し、メモリ枯渇を防ぐため cm_email_queue に進捗を保存します。
手動操作は不要です!次の1分ごとの cron 実行で、重複送信することなく cm_email_queue 内の未処理 pending データを自動的に引き継いで送信します。
7.2.2 自動化された 6 項目の Preflight 安全性チェックが campaign の配信開始をブロックするのはなぜですか?
必須の {{unsubscribe_link}} が欠落しているか、件名が無効、アクティブな宛先が0件、または syntax プレースホルダーが閉じられていません。
Preflight エンジンは、ステータスを queued や sending に進める前に、コンプライアンスと deliverability に関する6つの重要項目を検証します。
配信前モーダルの赤い警告を確認してください。{{unsubscribe_link}} を挿入し (RFC 8058 および CAN-SPAM で義務付け)、選択したタグにアクティブな contacts が含まれていることを確認します。
7.2.3 "Resend to Non-openers" はいつ利用可能になり、読者の疲弊をどう防ぎますか?
配信処理中、または安全な待機時間が経過する前は、Campaign レポートの再送ボタンは無効化されています。
MarbleSend は campaign のステータスが completed であることを必須とし、各タイムゾーンの読者が読む猶予として最低 24〜48 時間待つことを推奨しています。
配信完了後に "Resend to Non-openers" をクリックしてください。opened_at IS NULL の contacts のみを対象とした新しい子キャンペーンが作成され、件名を変更してテストできます。
7.3 Contacts 管理・CSV インポートとバウンス対応
7.3.1 CSV インポーターで行がスキップされたり、特定の購読者 record がインポートできないのはなぜですか?
RFC 5322 に準拠しないメール syntax、"Skip Duplicates" 有効時の重複アドレス、非 UTF-8 文字コード、または配信停止済み contacts の存在です。
MarbleSend は各行を精査し、filter_var(FILTER_VALIDATE_EMAIL) で検証の上、cm_contacts と照合して unsubscribed や bounced を上書きしないよう保護します。
CSV file を BOM なし UTF-8 で保存してください。列マッピング (email, name, tags) を確認し、インポート完了モーダルでスキップされた行番号を照合してください。
7.3.2 MarbleSend はソフトバウンス (Soft Bounce) とハードバウンス (Hard Bounce) をどのように区別しますか?
恒久的な配信失敗 (SMTP 5xx エラー: メールボックスが存在しない) と一時的な配信失敗 (SMTP 4xx エラー: 容量超過、レート制限) の違いです。
5xx 応答時は直ちに contact を bounced に変更します。4xx 応答時は cm_email_logs に試行を記録し、最大3回まで再試行した後に bounced に移行します。
ハードバウンスとなった連絡先を再有効化しないでください。無効アドレスへの送信は Gmail や Yahoo における送信元ドメインの評価を著しく低下させます。
7.4 Template レンダリング・Outlook 対応と email-safe 設計
7.4.1 デスクトップ版 Microsoft Outlook でメールテンプレートのレイアウトが崩れるのはなぜですか?
Windows 版 Microsoft Outlook は Microsoft Word (MSO) のレンダリングエンジンを使用しており、CSS Flexbox、Grid、margin auto、HTML5 タグをサポートしていません。
Word MSO は明示的なピクセル幅とインラインスタイルを持つ従来のテーブルベース構造 (nested <table>, <tr>, <td>) のみを解釈します。
MarbleSend に組み込まれている 8 種類の検証済み email-safe スターターレイアウトをご利用ください。入れ子構造の HTML テーブルと MSO 条件分岐コメント (<!--[if mso]>) により完璧に表示されます。
7.4.2 Gmail でメールの末尾に "[Message clipped] View entire message" と表示されるのはなぜですか?
メールの生の HTML ファイルサイズが Gmail の厳格な上限である 102 KB (104,448 バイト) を超えているためです。
102 KB を超えると Gmail はメッセージを切り詰め、本文の一部やフッターの配信停止リンク、追跡ピクセルを非表示にしてしまいます。
画像をインラインの base64 形式ではなく外部の HTTPS サーバーにホストしてください。不要な CSS を削減し、Templates Studio の "Clean HTML" で整形してから送信してください。
7.4.3 メールで {{news_posts}} が空になる、または表示されないのはなぜですか?
プレースホルダーは、コンテンツソースが「ニュース投稿」のニュースレタースケジュールでのみ埋められます。手動Campaign、RSSスケジュール、テンプレートのみのスケジュールでは空のテキストに置き換えられます。
テンプレートがニュース投稿の取得元なしで {{news_posts}} を使うと、Campaignの事前チェックが警告を表示します。テンプレート → 投稿のプレビューには常に埋め込み済みのブロックが表示されます。
テンプレートを「ニュース投稿」に設定したニュースレタースケジュール経由で送信するか、他で使うテンプレートからプレースホルダーを削除してください。
7.5 Schedules 定期配信・RSS フィードと Worker 周期
7.5.1 ブログに新しい記事が公開されたのに、自動 RSS 配信が送信されなかったのはなぜですか?
フィード URL にアクセスできないか、XML の syntax が不正であるか、最新記事の GUID が cm_schedules.last_rss_item_id と一致していたためです。
MarbleSend は最新記事の SHA-256 ハッシュを last_rss_item_id に記録します。新しい <item> や <entry> が見つからない場合、worker はキューを作成せず安全にスキップします。
/schedules で設定を開き "Test Feed" をクリックして実際の XML 応答を確認してください。RSS が有効な <pubDate> と一意の <guid> を出力しているか確認してください。
7.5.2 サーバーや worker cron が数日間停止した場合、定期的な schedules はどうなりますか?
worker プロセスが停止している間に、スケジュールされた実行間隔が複数回経過してしまった状態です。
MarbleSend は SchedulerService で厳格な "Single Catch-Up Policy" を適用します。遅延分を一度に送信して受信箱を圧迫するのを防ぐため、直近の1回分のみを実行します。
cron が再開されると、正確に1回分のキャッチアップ配信が作成・送信されます。その後、next_run_at は自動的に将来の次回予定日時に更新されます。
7.5.3 ニュース投稿スケジュールが準備完了の投稿を送信しなかったのはなぜですか?
投稿がスケジュールのニュース投稿モードがオンになる前に準備完了になった、すでにこのスケジュールで配信済み、またはオーディエンスやテンプレートが実行を妨げたかのいずれかです。
スケジュールの履歴を開きます。「no new posts」は対象がないこと、「no recipients」はオーディエンスが空だったこと、「failed」はテンプレートが存在しないか {{news_posts}} がないことを意味します。
スケジュールの作成後に投稿のコピーを準備完了にし、オーディエンスまたはテンプレートを修正してから、今すぐ実行を使ってください。
7.5.4 2つのスケジュールが同じ投稿を送信できますか?
配信は投稿ごとではなく、スケジュールごとに追跡されます。
各ニュース投稿スケジュールは、自分が配信した投稿を独自に記録するため、ライブラリには合計の「送信済み N×」が表示されます。
はい。両方のスケジュールの作成後に準備完了になった投稿は、それぞれが1回ずつ送信します。どちらも2回送信することはありません。
7.6 Settings 設定・Deliverability 到達性・Webhooks とライセンス
7.6.1 SMTP エラー "535 Authentication Failed" または "550 Relay Access Denied" を診断・解決するにはどうすればよいですか?
SMTP 認証情報の誤り、ポートと暗号化方式の不一致 (ポート 587 STARTTLS vs ポート 465 SSL)、または送信元アドレスが未承認であるためです。
Settings → SMTP設定には、PHPMailer と SMTP サーバー間の直接の対話ログを確認できるライブソケットテストが用意されています。
通常はポート 587 の TLS を使用してください。Gmail/Google Workspace では App Password を生成します。Amazon SES ではドメインを検証し、cPanel ではメールアドレス全体をユーザー名に入力します。
7.6.2 Deliverability Suite で SPF、DKIM、または DMARC の検証エラーが表示されるのはなぜですか?
送信元ドメインの DNS レコードの欠落、SPF における 10 回の lookup 上限超過、または DKIM セレクターの不一致です。
MarbleSend は権威ネームサーバーに対して直接非ブロッキング DNS クエリ (dns_get_record) を行い、SPF (root TXT)、DKIM (selector._domainkey)、DMARC (_dmarc) を検証します。
SMTP 中継の include 構文を SPF に追加してください。DKIM セレクターが推奨値と一致しているか確認し、DMARC に有効なレポート用 rua アドレスを設定してください。
7.6.3 Webhooks のサーキットブレーカー (Circuit Breaker) はどのように動作し、停止したエンドポイントを再開するにはどうすればよいですか?
受信先エンドポイントが HTTP 5xx エラーを連続して返したか、タイムアウト (>10秒)、または 404 Not Found を返したためです。
サーバーキューの滞留を防ぐため、MarbleSend は配信失敗を監視し、連続してエラーが発生した場合に自動的に一時停止 (enabled = 0) します。
Webhook 送信履歴ドロワーを開き、HTTP ステータスコードとエラー内容を確認してください。受信側サーバーの復旧後、"Test Webhook" を実行し、HMAC 署名を確認して再度有効化します。
7.6.4 Ed25519 ライセンス検証の仕組みと、7 日間のオフライン猶予期間 (Grace Window) とは何ですか?
ネットワークの切断、DNS 解決の失敗、または認証元ライセンスサーバーの一時的なメンテナンスです。
ライセンスの真正性は libsodium の sodium_crypto_sign_verify_detached() によりメモリ内でローカル検証されます。データベースを不正に改ざんすると署名が無効化されます。
MarbleSend は 7 日間のオフライン猶予期間 (grace_until) を提供します。配信は中断されません。有効期限が切れた場合でも、既存データやレポートは soft-lock の下で 100% 閲覧可能です。
WordPress & サードパーティ製フォーム連携
WordPress サイトで購読者を集め、MarbleSend に送ります。連携プラグインは独自の購読フォームを備え、WPForms、Contact Form 7、Fluent Forms、Formidable Forms、Forminator と接続できます。
フォーム連携インスペクター
コンポーネントを選ぶと、その hook、送信する内容、設定のヒントが表示されます。
REST API ブリッジ
データベースを共有しない送信キュー
Transient ストレージMarbleSend Form
Shortcode、Block、WidgetWPForms hook
wpforms_process_completeContact Form 7 hook
wpcf7_mail_sentFluent Forms hook
submission_insertedFormidable Forms
frm_after_create_entryForminator hook
submit_before_set_fieldsタグ別の自動返信
タグとウェルカムメール先に連携プラグインをインストールしてください(marblesend-forms.zip)
MarbleSend は独自のサーバーで動くため、WordPress から購読者を送るには小さなプラグインが必要です。このプラグインは MarbleSend の内蔵フォームを動かし、WPForms、Contact Form 7、Fluent Forms、Formidable Forms、Forminator と接続します。無料で、WordPress 6.3 以上と PHP 7.4 以上が必要です。MarbleSend との通信は REST API だけで行います。
Settings メニューはどこに表示されますか?
プラグインを有効にすると、wp-admin の Settings の下に 2 つのページが表示されます。MarbleSend Forms(接続 URL、API key、既定のタグ、失敗ログ)と MarbleSend Integrations(フォームプラグインごとのフィールド対応付け)です。どちらも WordPress 側にあり、MarbleSend のダッシュボードにはありません。 独自のフォームと、そのグループ・タグ・スパム対策は、サイドバーの MarbleSend Forms で管理します。
1. marblesend-forms.zip をダウンロードする
marblesend-forms.zip は MarbleSend の Settings → ライセンス から、または https://marblesend.com/download/marblesend-forms.zip から直接ダウンロードできます。そのままインストールできる WordPress プラグインの zip です。展開せずにそのままアップロードしてください。
2. WordPress にインストールして有効化する
wp-admin で Plugins → Add New → Upload Plugin を開き、marblesend-forms.zip を選んで Install Now、続けて Activate Plugin をクリックします。後で更新するときは、新しい zip を同じ方法でアップロードします。WordPress がインストール済みのバージョンを置き換えるか確認し、設定は保持されます。
3. API key を接続する(contacts:write)
MarbleSend で Settings → API・Webhook を開き、contacts:write scope の API key を作成します。WordPress で Settings → MarbleSend Forms を開き、MarbleSend Site URL と key を入力して保存し、Test Connection をクリックします。Connected と scope の contacts:write が表示されれば成功です。 続けて、MarbleSend から読み込まれる一覧から Default Group と Default Tags を選ぶか、そこで新しいグループを作成します。
4. フォームを対応付ける
wp-admin で Settings → MarbleSend Integrations を開きます。有効なフォームプラグインが、そのフォームとともに表示されます。Enabled にチェックし、メールのフィールドと(あれば)名前のフィールドを入力し、必要ならタグを追加して保存します。内蔵フォームに対応付けは不要です。
8.1 プラグインが MarbleSend と通信する仕組み
プラグインは HTTPS で MarbleSend の REST API を呼び出すため、WordPress と MarbleSend は別々のサーバーで動かせます。MarbleSend のデータベースにはアクセスしません。
WordPress が MarbleSend のテーブルを読むことはなく、MarbleSend が wp_posts や wp_users を読むこともありません。両者は別のホスト、別のデータベースで動かせます。
すべてのリクエストに Settings → API・Webhook の Bearer API key が付きます。contacts:write scope で足りるため、この key では Campaign の送信もスケジュールの変更もできません。
Settings → MarbleSend Forms の Test Connection は GET /api/verify-key を呼び出し、key の scope を表示します。URL や key の誤りがすぐ分かります。
送信は POST /api/contacts に届きます。新しいメールアドレスはコンタクトになります。既存のコンタクトはステータスを保ち、既存のタグに新しいタグが追加されます。名前が変わるのは、フォームが名前を送ったときだけです。double opt-in が有効な場合、新しいコンタクトは確認するまで pending のままです。
curl -X POST https://your-domain.com/api/contacts \
-H "Authorization: Bearer ms_live_abc123..." \
-H "Content-Type: application/json" \
-d '{"email":"visitor@example.com","name":"John Doe","tags":["newsletter","source:wpforms"]}'
任意: 連絡先を特定のグループに入れるには "group_ids":[1,2] を追加します(グループ一覧は GET /api/groups、省略時は General)。GET /api/contacts は group_id でグループ別に絞り込めます。
8.2 送信キューと WP-Cron
MarbleSend が遅い、または届かないときでも、訪問者のフォームが固まったり lead を失ったりしてはいけません。フォームプラグインの送信はキューに入り、バックグラウンドで送られます。
フォームプラグインが送信すると、MarbleSend_Integration_Base::dispatch() がフィールドを整形し、WordPress transient(set_transient)に保存します。訪問者が待っている間に MarbleSend へのリクエストは行われません。
WP-Cron のイベント marblesend_forms_process_queue が約 1 分後に予約され、キューにある送信を送ります。
WP-Cron はキューの各項目を 1 回だけ送ります。内蔵フォームはまず MarbleSend を直接呼び出し、その呼び出しが失敗した場合に限り、WP-Cron による 1 回の試行のために送信をキューに入れます。キューの項目は最長 1 時間保持されます。
送信に失敗した場合、または WP-Cron が送る前に項目が期限切れになった場合、プラグインは marblesend_forms_log に 1 行追加し(直近 50 件の records を保持)、wp-admin に管理者向け通知を表示します。Settings → MarbleSend Forms にログと保留中の項目数が表示されます。
// Non-blocking submission buffer in WordPress
set_transient('marblesend_forms_queue_' . wp_generate_uuid4(), $payload, 3600);
if (!wp_next_scheduled('marblesend_forms_process_queue')) {
wp_schedule_single_event(time() + 5, 'marblesend_forms_process_queue');
}
8.3 内蔵の購読フォーム
プラグインには購読フォームが含まれているため、フォームビルダーは不要です。shortcode、Gutenberg ブロック、ウィジェットのいずれかで追加できます。3 つとも同じコードが動きます。
[marblesend_form]、Gutenberg ブロックの marblesend/subscribe-form、または MarbleSend Subscribe Form ウィジェットを使います。shortcode は tags、show_name(1 または 0)、consent(必須チェックボックスの文言)を受け付けます。ブロックとウィジェットにも同じオプションがあります。 MarbleSend Forms → Add New Form で独自のフォームを作成し、[marblesend_form id="12"] で埋め込みます。
画面外の honeypot フィールド(marblesend_hp)、フォーム送信時に取得する nonce(キャッシュされたページが期限切れの nonce を返すことはありません)、IP ごとに 60 秒あたり 5 回までの制限(IP はハッシュ化して保存)を備えます。honeypot が入力されたリクエストや有効な nonce がないリクエストには、通常に見える成功メッセージを返して破棄します。リクエストが多すぎる場合は、短い「しばらくお待ちください」のメッセージが表示されます。 エディターで作成したフォームでは、Settings → MarbleSend Forms で設定した Cloudflare Turnstile または Google reCAPTCHA も使えます。
ページは再読み込みされません。プラグインはすぐにコンタクトを MarbleSend に送ります(タイムアウト 5 秒)。MarbleSend に届かない場合やプラグインが未設定の場合は、送信が WP-Cron の 1 回の試行のためにキューに入り、訪問者には成功メッセージが表示されます。リクエスト自体が失敗した場合は、フォームにエラーが表示され、再送信できます。
訪問者がメールアドレスだけを入力した場合、API が名前を必要とするため、新しいコンタクトには @ より前の部分が名前として付きます。既存のコンタクトは名前をそのまま保ちます。すべてのコンタクトにタグ source:wp-form と、フォームおよび Settings → MarbleSend Forms で設定したタグが付きます。double opt-in が有効な場合、訪問者にはメールの確認を促すメッセージが表示されます。 連絡先は、フォームのグループ、または Settings → MarbleSend Forms の Default Group に入ります。
[marblesend_form tags="newsletter,inbound" show_name="1" consent="I agree to receive email updates and accept the privacy policy."]
8.4 WPForms(Lite と Pro)
WPForms は最もよく使われるフォームビルダーの 1 つです。プラグインは WPForms が検証した後に送信内容を読み取るため、WPForms のアドオンは不要です。
プラグインは function_exists('wpforms') で WPForms を検出し、検証済みのフィールドを受け取る wpforms_process_complete アクション(優先度 10)を待ち受けます。
WPForms はフィールドを番号で識別します。ビルダーでフィールドを選び、フィールドオプションの上部にある ID(例: Field ID #2)を確認して、その番号を対応付けに入力します。姓と名に分かれた名前フィールドは 1 つの名前に結合されます。
1. Email フィールドと、あれば Name フィールドの ID を控えます。2. Settings → MarbleSend Integrations を開き、WPForms を探します。3. Enabled にチェックし、ID と必要なタグを入力します。4. 保存します。
WPForms からのコンタクトには、自分で付けたタグに加えて source:wpforms のタグが付くため、そのグループだけに Campaign を送れます。
add_action('wpforms_process_complete', function($fields, $entry, $form_data, $entry_id) {
$email = $fields[1]['value'] ?? ''; // Numeric Field ID #1
$name = $fields[0]['value'] ?? ''; // Numeric Field ID #0
MarbleSend_Integration_Base::dispatch('wpforms', $form_data['id'], $email, $name);
}, 10, 4);
8.5 Contact Form 7(CF7)
Contact Form 7 は、フィールドをテキストテンプレート内のタグとして定義します。プラグインは、フォームのメールが送信された後に処理を行います。
プラグインは class_exists('WPCF7_ContactForm') で CF7 を検出し、wpcf7_mail_sent(優先度 10)を待ち受けます。lead が転送されるのは、フォームがスパム対策と検証を通過し、Contact Form 7 が自身のメールを送信した後だけです。お使いのホスティングでメール送信に失敗する場合、何も転送されません。
CF7 はフォームタグでフィールドに名前を付けます。例: [email* your-email] と [text your-name]。その名前(your-email、your-name)を Email Field と Name Field の欄に入力します。
プラグインは WPCF7_Submission::get_instance()->get_posted_data() で送信データを読み取ります。CF7 の AJAX 送信でも動作します。
1. Contact → Contact Forms でフォームを開き、タグ名を控えます。2. Settings → MarbleSend Integrations で Contact Form 7 を探します。3. Enabled にチェックし、your-email と、あれば your-name を入力して、必要ならタグを追加します。4. 保存します。
add_action('wpcf7_mail_sent', function($contact_form) {
$submission = WPCF7_Submission::get_instance();
$data = $submission ? $submission->get_posted_data() : [];
$email = $data['your-email'] ?? '';
$name = $data['your-name'] ?? '';
MarbleSend_Integration_Base::dispatch('cf7', $contact_form->id(), $email, $name);
}, 10, 1);
8.6 Fluent Forms(Free と Pro)
プラグインは、Fluent Forms がエントリーを保存した後に発行するアクションを待ち受けます。
プラグインは function_exists('wpFluent') で Fluent Forms を検出し、$entry_id、$form_data、$form を受け取る fluentform/submission_inserted(優先度 10)を待ち受けます。
Fluent Forms はフィールドを Name Attribute で識別します。例: メールは email、名前フィールドは names(姓と名は結合されます)。フィールド設定の Advanced Options にあります。
Integrations ページは Fluent Forms 自身のフォームテーブルを読んでフォームを一覧表示するため、フォーム ID を調べる必要はありません。
1. メールと名前のフィールドの Name Attribute を確認します。2. Settings → MarbleSend Integrations で、そのフォームの Enabled にチェックし、両方を入力します。3. タグを追加して保存します。新しいコンタクトにはタグ source:fluentforms が付きます。
add_action('fluentform/submission_inserted', function($entryId, $formData, $form) {
$email = $formData['email'] ?? '';
$name = is_array($formData['names'] ?? null) ? implode(' ', $formData['names']) : ($formData['first_name'] ?? '');
MarbleSend_Integration_Base::dispatch('fluentforms', $form->id, $email, $name);
}, 10, 3);
8.7 Formidable Forms(Lite と Pro)
プラグインは、Formidable Forms がエントリーを保存した直後にそれを読み取ります。
プラグインは class_exists('FrmForm') で Formidable を検出し、$entry_id と $form_id を受け取る frm_after_create_entry(優先度 30)を待ち受けます。
Formidable はすべてのフィールドに数値の Field ID(例: 12)を割り当てます。これをマッピングに入力してください。フィールドキーはサポートされません。データは FrmEntry::getOne($entry_id)->metas で取得されます。
プラグインはエントリーが作成された後に動くため、Formidable の検証を通過した送信だけが転送されます。
1. Formidable のビルダーでメールフィールドをクリックし、Field ID を控えます。 2. Settings → MarbleSend Integrations でフォームを有効にし、Field ID を入力します。 3. マッピングを保存します。取り込まれた lead にはタグ source:formidable が付きます。
add_action('frm_after_create_entry', function($entryId, $formId) {
$entry = FrmEntry::getOne($entryId, true);
$email = $entry->metas[12] ?? $entry->metas['email-address'] ?? '';
$name = $entry->metas[11] ?? $entry->metas['full-name'] ?? '';
MarbleSend_Integration_Base::dispatch('formidable', $formId, $email, $name);
}, 30, 2);
8.8 Forminator(Free と Pro)
プラグインは、Forminator が送信を処理するときに発行する hook を待ち受けます。
プラグインは class_exists('Forminator_API') で Forminator を検出し、$entry、$form_id、$field_data を受け取る forminator_custom_form_submit_before_set_fields(優先度 10)を待ち受けます。
Forminator は各フィールドに email-1、name-1、text-1 のような element ID を割り当てます。これらの ID を対応付けに入力します。フォームエディターで確認できます。
Integrations ページは、Forminator_API::get_forms() で読み取った Forminator のフォームを名前付きで一覧表示します。
1. Forminator を開き、element ID(email-1、name-1)を控えます。2. Settings → MarbleSend Integrations で Forminator を探し、ID を入力します。3. タグを追加して保存します。4. テスト送信を行い、コンタクトにタグ source:forminator が付いていることを確認します。
add_action('forminator_custom_form_submit_before_set_fields', function($formId, $response, $fieldData) {
$fields = array_column($fieldData, 'value', 'name');
$email = $fields['email-1'] ?? '';
$name = $fields['name-1'] ?? '';
MarbleSend_Integration_Base::dispatch('forminator', $formId, $email, $name);
}, 10, 3);
8.9 タグ、セグメント、自動返信
WordPress プラグインからの連絡先は、Settings → MarbleSend Forms(Default Group)またはフォームで選んだグループに入り、何も選ばなければ General に入ります。タグで分類するか、Contacts からグループへ移動できます。
メールアドレスを集めるのは最初の一歩にすぎません。その後にコンタクトに何が起きるかは、タグが決めます。
自分で付けたタグに加えて、すべてのコンタクトに source:<slug> が付きます。source:wp-form、source:wpforms、source:cf7、source:fluentforms、source:formidable、source:forminator のいずれかです。1 つのフォームプラグインの購読者だけに Campaign を送るときに使えます。
/contacts → Autoresponders で、WordPress のフォームに割り当てたタグ用のルールを作成します。コンタクトが有効になると(送信直後、または double opt-in の確認後)、MarbleSend は選択したテンプレートと SMTP プロファイルでウェルカムメールをキューに入れます。
プラグインは lead をご自身の MarbleSend に直接送ります。Zapier や Make のようなサービスは経路に含まれません。
double opt-in が有効な場合、新しいコンタクトは consent_source = 'api' の pending として保存されます。MarbleSend は確認リンク({{confirm_link}})をメールで送ります。コンタクトがリンクをクリックするとステータスが active になり、GDPR 対応のため日時と IP アドレスが記録されます。
{
"email": "lead@agency.com",
"name": "Jane Smith",
"tags": ["source:wpforms", "ebook-download", "vip-inbound"],
"consent_source": "api"
}
8.10 トラブルシューティング
WordPress のフォームを接続するときのよくある問題を、原因、確認方法、対処とともにまとめています。
送信が MarbleSend に遅れて表示される、または表示されないのはなぜですか?
WP-Cron はサイトが訪問されたときにだけ実行されます。アクセスの少ないサイトや staging サイトでは、キューにある送信が次の訪問まで待たされます。キューの送信は 1 時間だけ保持されます。その間に WP-Cron が実行されないと送信は失われ、marblesend_forms_log には 1 件が期限切れになったことが記録されます(保存されていたデータも期限切れのため、訪問者は特定できません)。
wp-admin で Settings → MarbleSend Forms を開きます。保留数は marblesend_forms_process_queue を待っている項目を示します。キューの送信が期限切れになったというログがあれば、WP-Cron が 1 時間以上実行されなかったことを意味します。
https://your-site.com/wp-cron.php?doing_wp_cron を開いて 1 回実行するか、サーバーで本物の cron ジョブを設定します(* * * * * wget -q -O - https://your-site.com/wp-cron.php >/dev/null 2>&1)。
ログに「Skipped: no valid email in form submission」と出るのはなぜですか?
対応付けのメールフィールドに誤字があるか、訪問者が空または無効なアドレスを送信し、sanitize_email() に拒否されました。
有効にしたフォームから有効なメールが得られないたびに、MarbleSend_Integration_Base::log_skip() が marblesend_forms_log に記録します。
フォームビルダーが使う識別子を確認してください。WPForms と Formidable Forms は数字(例: 2)、Contact Form 7 はタグ名(your-email)、Fluent Forms は Name Attribute(email)、Forminator は element ID(email-1)です。
WordPress が API key の無効、または scope 不足と表示するのはなぜですか?
WordPress の key が失効した、期限切れになった、MarbleSend で削除された、または contacts:write scope なしで作成されました。
Test Connection は GET /api/verify-key を呼び出します。HTTP 401 または 403 が返れば、認証に失敗しています。
MarbleSend で Settings → API・Webhook を開き、contacts:write scope(または admin)の新しい key を作成します。ms_ で始まるトークンを、WordPress の Settings → MarbleSend Forms にコピーします。
フォームにエラーが出ると Contact Form 7 の lead が消えるのはなぜですか?
プラグインは Contact Form 7 が自身のメールを送信した後にだけ lead を転送します。メールが失敗すると CF7 はエラーメッセージを表示し、lead は転送されません。
自分でフォームを送信してみてください。「There was an error trying to send your message」と表示されれば、CF7 はメールを送信できていません。
SMTP プラグインなどで、WordPress サイトのメール送信を直してください。CF7 がメールを送信できるようになれば、lead は MarbleSend に届きます。
コンタクトの名前がメールアドレスになっているのはなぜですか?
フォームに名前フィールドがないか、名前フィールドが対応付けられていません。MarbleSend の API は名前を必要とするため、新しいコンタクトにはメールの @ より前の部分が使われます。
Settings → MarbleSend Integrations でフォームの行を確認してください。Name Field の欄が空です。すでに存在するコンタクトには影響しません。名前をそのまま保つためです。
フォームに名前フィールドを追加し、対応付けに入力します。すでに存在するコンタクトは現在の名前を保ちます。必要なら /contacts で変更してください。