メインコンテンツへスキップ
これらのコピー&ペーストHTMLテンプレートを使用して、OneSignalのカスタムアプリ内メッセージをより速く構築できます。 私たちのアプリ内メッセージHTMLエディターを使用すると、HTML、CSS、JavaScriptを使用してアプリ内メッセージのレイアウトと動作を完全に制御できます。エディターには組み込みテンプレートは含まれていませんが、このページではエディターに貼り付けてカスタマイズできるすぐに使用できるサンプルを提供しています。
これらのテンプレートはアプリ内メッセージのWebview内で実行されます。メッセージを閉じたり、URLを開いたり、ユーザーにタグを付けたり、クリックを取得するには、アプリ内メッセージJS APIを使用してください。

前提条件

開始前に、以下を確認することをお勧めします:
テンプレートコードに秘密情報(APIキー、トークン)を入れないでください。すべてのアプリ内メッセージ入力を信頼できないものとして扱い、アプリまたはバックエンドで検証してください。

テンプレートの使用方法

  1. OneSignalでメッセージ > アプリ内 > 新規アプリ内に移動します。
  2. HTMLエディターを選択します。
  3. 下記のテンプレートを見つけます。
  4. コードブロックから完全なHTMLをコピーしてエディターに貼り付けます。
  5. プレースホルダー(URL、エンドポイント、日付、コピー)を更新します。
  6. 実際のデバイスでテストしてから公開します。

利用可能なテンプレート

email-form

メール収集フォーム

ユーザーのメールアドレスを取得し、クリック名でアプリに送信します。
sms-form

電話番号収集フォーム

SMS送信の同意を求めて取得します。E.164形式の電話番号を含み、クリック名でアプリに送信します。
checklist-survey

チェックリスト調査

バックエンドに送信またはタグに変換できる複数選択調査。
count_down

カウントダウン

時間制限のあるプロモーション用のカウントダウンタイマー。
promo-wheel

プロモホイール

スピン・トゥ・ウィンプロモ体験(プロモの処理をカスタマイズ)。
quiz_modal

クイズモーダル

ユーザーにスコアでタグを付けることができるクイズ体験。
ranking-survey

評価調査

1〜5評価調査(エンドポイントに送信またはユーザーにタグ付け)。
ui-ui

オーディオ/ビデオプレーヤー

直接MP3ファイル用のシンプルなオーディオプレビューUI。
vertical-swiping

縦スワイプ

マルチスライド縦スワイプオンボーディングまたは機能ツアー。

メールフォーム

アプリ内メッセージを通じてメールサブスクリプションを収集します。 このフォームの動作方法:
  1. ユーザーがメールアドレスを入力し、同意ボックスにチェックを入れます。
  2. 送信時に、OneSignalのCreate User APIが呼び出され、アプリでメールサブスクリプションが作成されます。
  3. また、テンプレートはOneSignalIamApi.addClickName(e, email)を呼び出し、メールアドレスをSDKのアプリ内メッセージクリックリスナーに渡します。
  4. アプリ内で、アプリ内メッセージクリックリスナーを追加してクリック名を読み取り、メールをSDKのaddEmailメソッドに渡すことができます。
ステップ2と4の両方がメールサブスクリプションの作成を含むことに気づくかもしれません。
  • ステップ2はアプリに直接コードを追加する必要がありませんが、loginメソッドを呼び出した場合、ユーザーにメールサブスクリプションを追加しません。
  • ステップ4は追加のコード(アプリ内メッセージクリックリスナー)が必要ですが、loginメソッドを呼び出した場合もユーザーにメールサブスクリプションを追加します。
**設定 > キーとIDで見つけたOneSignalアプリIDにYOUR_APP_IDを置き換えてください。
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <!-- iOS入力フォーカス時のズームを防止 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <style>
        /* ===== リセット ===== */
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        /* ===== ベース ===== */
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: transparent;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            padding: 20px;
        }
        
        /* ===== カード ===== */
        .container {
            position: relative;
            background: #ffffff;
            border-radius: 16px;
            padding: 32px 24px;
            max-width: 340px;
            width: 100%;
            box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
            text-align: center;
        }
        
        /* ===== 閉じるボタン ===== */
        .close-btn {
            position: absolute;
            top: 12px;
            right: 12px;
            background: none;
            border: none;
            font-size: 24px;
            color: #999;
            cursor: pointer;
            padding: 4px 8px;
            line-height: 1;
        }
        
        .close-btn:hover {
            color: #333;
        }
        
        /* ===== タイポグラフィ ===== */
        h1 {
            font-size: 22px;
            font-weight: 600;
            color: #333;
            margin-bottom: 8px;
        }
        
        p {
            font-size: 14px;
            color: #666;
            margin-bottom: 24px;
            line-height: 1.5;
        }
        
        /* ===== メール入力 ===== */
        .email-input {
            width: 100%;
            padding: 14px 16px;
            font-size: 16px; /* 16pxでiOS自動ズームを防止 */
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            margin-bottom: 16px;
            outline: none;
            transition: border-color 0.2s;
            touch-action: manipulation;
        }
        
        .email-input:focus {
            border-color: #007AFF;
        }
        
        .email-input::placeholder {
            color: #aaa;
        }
        
        /* ===== 同意チェックボックス ===== */
        .consent-wrapper {
            display: flex;
            align-items: flex-start;
            gap: 10px;
            text-align: left;
            margin-bottom: 16px;
        }
        
        .consent-wrapper input[type="checkbox"] {
            width: 18px;
            height: 18px;
            margin-top: 2px;
            cursor: pointer;
            flex-shrink: 0;
        }
        
        .consent-wrapper label {
            font-size: 13px;
            color: #666;
            line-height: 1.4;
            cursor: pointer;
        }
        
        /* ===== 送信ボタン ===== */
        .submit-btn {
            width: 100%;
            padding: 14px 24px;
            font-size: 16px;
            font-weight: 600;
            color: #fff;
            background: #007AFF;
            border: none;
            border-radius: 10px;
            cursor: pointer;
            transition: background 0.2s, opacity 0.2s;
        }
        
        .submit-btn:hover {
            background: #0056b3;
        }
        
        .submit-btn:disabled {
            background: #ccc;
            cursor: not-allowed;
            opacity: 0.7;
        }
        
        /* ===== ステータスメッセージ ===== */
        .error-msg,
        .success-msg {
            font-size: 12px;
            margin-top: -12px;
            margin-bottom: 12px;
            display: none;
        }
        
        .error-msg {
            color: #e53935;
        }

        .success-msg {
            color: #4CAF50;
            font-size: 14px;
        }
        
        /* ===== ローディング状態 ===== */
        .loading {
            pointer-events: none;
            opacity: 0.7;
        }
    </style>
</head>
<body>
    <div class="container">
        <!-- 閉じるボタン -->
        <button id="close-btn" class="close-btn" data-onesignal-unique-label="close-button">×</button>
        
        <!-- ヘッダー -->
        <h1>つながりを保ちましょう!</h1>
        <p>メールアドレスを入力して、アップデートと特別なオファーを受け取りましょう。いつでも配信停止できます!</p>
        
        <!-- メール入力 -->
        <input 
            type="email" 
            id="email-input" 
            class="email-input" 
            placeholder="メールアドレスを入力" 
            data-onesignal-unique-label="email-input" 
            autocomplete="email" 
            autocapitalize="off"
        >
        
        <!-- ステータスメッセージ -->
        <p id="error-msg" class="error-msg">有効なメールアドレスを入力してください</p>
        <p id="success-msg" class="success-msg">購読ありがとうございます!</p>
        
        <!-- 同意チェックボックス -->
        <div class="consent-wrapper">
            <input type="checkbox" id="consent-checkbox" name="consent">
            <label for="consent-checkbox">マーケティングメールの受信に同意します</label>
        </div>
        
        <!-- 送信ボタン -->
        <button id="submit-btn" class="submit-btn" data-onesignal-unique-label="submit-email" disabled>
            購読する
        </button>
    </div>

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            
            // ===== DOM参照 =====
            var emailInput = document.getElementById("email-input");
            var submitBtn = document.getElementById("submit-btn");
            var closeBtn = document.getElementById("close-btn");
            var errorMsg = document.getElementById("error-msg");
            var successMsg = document.getElementById("success-msg");
            var consentCheckbox = document.getElementById("consent-checkbox");
            
            // ===== ヘルパー関数 =====
            
            // メール形式を検証
            function isValidEmail(email) {
                return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
            }
            
            // メールが有効で同意がチェックされた場合のみ送信ボタンを有効化
            function updateSubmitState() {
                var email = emailInput.value.trim();
                submitBtn.disabled = !(isValidEmail(email) && consentCheckbox.checked);
            }
            
            // OneSignal APIを介してメール購読を作成
            async function createOneSignalUser(email) {
                // ⚠️ OneSignalアプリIDに置き換え
                var appId = "YOUR_APP_ID";
                var url = "https://api.onesignal.com/apps/" + appId + "/users";
                
                var payload = {
                    properties: {
                        tags: { email_created_from: "iam" },
                        language: "ja"
                    },
                    subscriptions: [{
                        type: "Email",
                        token: email,
                        enabled: true
                    }]
                };
                
                var response = await fetch(url, {
                    method: "POST",
                    headers: { "Content-Type": "application/json" },
                    body: JSON.stringify(payload)
                });
                
                if (!response.ok) throw new Error("APIリクエストが失敗しました");
                return response.json();
            }
            
            // ===== イベントリスナー =====
            
            // 閉じるボタン - IAMを閉じる
            closeBtn.addEventListener("click", function(e) {
                OneSignalIamApi.close(e);
            });
            
            // チェックボックス - ボタン状態を更新
            consentCheckbox.addEventListener("change", updateSubmitState);
            
            // メール入力 - ボタン状態を更新してエラーを非表示
            emailInput.addEventListener("input", function() {
                errorMsg.style.display = "none";
                updateSubmitState();
            });
            
            // メール入力 - Enterキーで送信
            emailInput.addEventListener("keypress", function(e) {
                if (e.key === "Enter" && !submitBtn.disabled) {
                    submitBtn.click();
                }
            });
            
            // 送信ボタン - 購読を処理
            submitBtn.addEventListener("click", async function(e) {
                var email = emailInput.value.trim();
                
                if (!isValidEmail(email) || !consentCheckbox.checked) {
                    errorMsg.textContent = "有効なメールアドレスを入力してください";
                    errorMsg.style.display = "block";
                    return;
                }
                
                // OneSignalクリックハンドラーにメールを渡す(同期的に呼び出す必要があります)
                OneSignalIamApi.addClickName(e, email);
                
                // ローディング状態を表示
                errorMsg.style.display = "none";
                submitBtn.textContent = "購読中...";
                submitBtn.classList.add("loading");
                
                try {
                    await createOneSignalUser(email);
                    
                    // 成功 - メッセージを表示して自動的に閉じる
                    successMsg.style.display = "block";
                    submitBtn.textContent = "購読完了!";
                    
                    setTimeout(function() {
                        closeBtn.click();
                    }, 1500);
                    
                } catch (error) {
                    // エラー - リセットしてメッセージを表示
                    submitBtn.textContent = "購読する";
                    submitBtn.classList.remove("loading");
                    errorMsg.textContent = "問題が発生しました。もう一度お試しください。";
                    errorMsg.style.display = "block";
                }
            });
        });
    </script>
</body>
</html>
ステップ4で必要:
  1. HTML送信ハンドラーでaddClickName呼び出しを保持してください。
  2. SDKのアプリ内メッセージクリックリスナーで入力を読み取ります
  3. クリック名がメールのように見える場合、アプリ内メッセージクリックリスナー内でaddEmailメソッドを呼び出します。
アプリ内メッセージクリックリスナーとaddEmailメソッドを使用した例:
// HTMLアプリ内メッセージからメールと電話を取得するアプリ内メッセージクリックハンドラーの例
class InAppMessageClickHandler: NSObject, OSInAppMessageClickListener {
    func onClick(event: OSInAppMessageClickEvent) {
        // イベントからクリック名(アクションID)を取得
        let clickName = event.result.actionId
        print("アプリ内メッセージがクリックされました。actionId: \(clickName ?? "nil")")
        
        guard let value = clickName else { return }
        
        // クリック名がメールアドレスのように見えるかチェック
        if value.contains("@") && value.contains(".") {
            OneSignal.User.addEmail(value)
            print("OneSignalにメールが追加されました: \(value)")
        }
        // クリック名がE.164形式の電話番号のように見えるかチェック(+1XXXXXXXXXX)
        else if value.hasPrefix("+") && value.count >= 11 {
            OneSignal.User.addSms(value)
            print("OneSignalにSMSが追加されました: \(value)")
        }
    }
}

アプリ内メッセージを通じてSMSサブスクリプションを収集します。 このフォームの動作方法:
  1. ユーザーが国コードを選択し、10桁の電話番号を入力し、同意ボックスにチェックを入れます。
  2. 送信時に、OneSignalのCreate User APIが呼び出され、アプリでSMSサブスクリプションが作成されます。
  3. また、テンプレートはOneSignalIamApi.addClickName(e, e164Phone)を呼び出し、電話番号をSDKのアプリ内メッセージクリックリスナーに渡します。
  4. アプリ内で、アプリ内メッセージクリックリスナーを追加してクリック名を読み取り、電話番号をSDKのaddSmsメソッドに渡すことができます。
ステップ2と4の両方がSMSサブスクリプションの作成を含むことに気づくかもしれません。
  • ステップ2はアプリに直接コードを追加する必要がありませんが、loginメソッドを呼び出した場合、ユーザーにSMSサブスクリプションを追加しません。
  • ステップ4は追加のコード(アプリ内メッセージクリックリスナー)が必要ですが、loginメソッドを呼び出した場合もユーザーにSMSサブスクリプションを追加します。
**設定 > キーとIDで見つけたOneSignalアプリIDにYOUR_APP_IDを置き換えてください。
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <style>
        /* スタイルはメールフォームと同様で、電話入力用に調整 */
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: transparent;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            padding: 20px;
        }
        .container {
            position: relative;
            background: #ffffff;
            border-radius: 16px;
            padding: 32px 24px;
            max-width: 340px;
            width: 100%;
            box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
            text-align: center;
        }
        /* その他のスタイル... */
    </style>
</head>
<body>
    <div class="container">
        <button id="close-btn" class="close-btn">×</button>
        <h1>SMSで最新情報を受信!</h1>
        <p>電話番号を入力して、重要なアップデートをSMSで受け取りましょう。</p>
        
        <div class="phone-input-wrapper">
            <select id="country-select" class="country-select">
                <option value="+1">🇺🇸 +1</option>
                <option value="+81">🇯🇵 +81</option>
                <!-- 他の国コード... -->
            </select>
            <input type="tel" id="phone-input" class="phone-input" placeholder="1234567890" maxlength="10">
        </div>
        
        <div class="consent-wrapper">
            <input type="checkbox" id="consent-checkbox">
            <label for="consent-checkbox">SMSマーケティングメッセージの受信に同意します</label>
        </div>
        
        <button id="submit-btn" class="submit-btn" disabled>購読する</button>
    </div>
    
    <script>
        // JavaScriptロジック(メールフォームと同様で、電話番号処理用に調整)
        // 詳細な実装はメールフォームと同様のパターン
    </script>
</body>
</html>

その他のテンプレート

上記のメールとSMSフォームに加えて、以下のテンプレートも利用できます:
  • チェックリスト調査: 複数選択調査
  • カウントダウン: 時間制限付きプロモーション
  • プロモホイール: スピン・トゥ・ウィン体験
  • クイズモーダル: スコア付きクイズ
  • 評価調査: 1〜5評価
  • オーディオ/ビデオプレーヤー: メディアプレビュー
  • 縦スワイプ: マルチスライドツアー
各テンプレートの詳細なHTMLコードと実装手順については、上記のカードリンクから各セクションをご参照ください。

SMSフォーム