salla-publication-consistency について
Sallaの公開アプリをApp Storeの審査に備えるためのガイドスキルです。下書き、準備状況の確認、検証、パートナーの確認手順を説明し、各公開ステップを担当するSallaスキルへ案内します。
主な機能
- 01公開下書きの読み取りと再開
- 02セクションの準備状況と不足項目の確認
- 03検証と下書きの保存
- 04パートナーによる確認と承認の必須化
- 05各ステップを担当するSallaスキルへ案内
活用シーン
- 01公開アプリをApp Store審査に向けて準備
- 02既存の公開下書きの再開や確認
- 03申請前に未完了のセクションを修正
MCP 対応
`app_publish`などのSallaツールを使う手順を説明しますが、MCPサーバーやプロトコルの実装については記載されていません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sallaapp/ salla-partners-agent-kit --skill salla-publication-consistencyインストール後、Claude Code で/salla-publication-consistencyを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/step-app-config.mdstep-basic-information.mdstep-contact.mdstep-features.mdstep-pricing.mdstep-service-trial.md詳細
Salla 公開の準備
対象:公開アプリ(App Store の掲載情報)。 プライベートアプリではこの段階的なフローは使用しません —
salla_private_apps action=publish で公開します →
salla-app-builder → プライベートアプリ。
公開前の前提条件
まず次の項目を確認してください。セクションにかかわらず、フロー全体の実行条件となります。
以下の3項目はアプリの詳細から確認できます — app_publish action=get(または salla_apps action=get)を実行すると、can_publish、requires_citc、can_have_free_plan が返されます。入力を始める前に確認してください。
- アプリを公開できる状態である必要があります。
can_publishはtrueでなければなりません。falseの場合、アプリを申請できません。 - パートナーのアカウントが認証済みである必要があります。 公開前に、パートナーは https://portal.salla.partners/account でアカウントを認証します。未認証のアカウントでは申請がブロックされます(validate/submit を実行すると
id_verificationエラーが返されます)。 - CITC 認証(SMS 通信アプリ)。
requires_citcがtrueの場合、パートナーは公開前にアカウント認証フォームで CITC 認証をアップロードする必要があります(サウジアラビアの規制要件)→ salla-communication-app。
app_publish(ベースパス /app/{id}/publication)を使って、Salla アプリを審査に備えます。一括呼び出しではなく、準備状況に応じたループで進めます。セクションを1つずつ入力し、ドラフトが準備できたかどうかはサーバーが判断します。
open → get(現在のドラフトを読み取る)→(set <section> → 準備状況の確認) → validate → パートナーが /publish リンクを確認 → send_publish_request*
app_publish action=validate はすべてのセクションの完全性と正確性を検証し、有効な公開情報を返すとともに、ドラフトを保存します。申請は行いません。 Salla の審査にアプリを送るには、厳格な条件があります。 検証が成功したら、パートナーに実際の /publish リンク(id を置き換えたもの)を提示し、ドラフトを確認するよう依頼してください。その後に限り審査へ進みます。パートナーが Portal でワンクリックで申請するか、パートナーが明示的に確認した後にエージェントが confirm: true を指定して app_publish action=send_publish_request を呼び出します。検証が問題なく完了し、パートナーがリンクを確認して、申請を承認するまでは、決してリクエストを送信しないでください。
open と各 set が返す準備状況チェックリストに沿って進めてください。各セクションには complete と表示されるか、未完了の場合は不足しているフィールドが missing に正確に列挙されます。指定されたセクションを修正して再確認し、繰り返してください。validate は同じサーバー側チェックを実行し、不足があれば 422 + 不足セクションを返します。すべてのセクションが完了していれば、ドラフトを保存します。
一連の流れ(app_publish、ベース /app/{id}/publication)
| action | verb | body | 内容 |
|---|---|---|---|
open | POST | — | 下書きを作成し、セクションごとの準備状況チェックリストを返します。開くと、コンテンツを一覧表示するための app_page_builder も利用可能になります。 |
get | GET | — | 読み取り専用:現在の下書き全体(publication_last_save — 保存済みのすべての値)と、スコープ、webhook_config を取得します。再開/レビュー時の入口です。準備状況には不足項目が表示され、get には入力済みの内容が表示されます。 |
readiness | GET | — | チェックリストを再取得します。complete のセクションと、不足しているフィールドを正確に確認できます。読み取りのみです。 |
set | PUT | { section, ...data } | 1 つのセクションを書き込みます。渡したフィールドだけが変更され、更新後の準備状況が返されます。 |
validate | PUT | — | すべてのセクションを検証し、下書きを保存します。有効な公開情報が返されます。不完全な場合は、422 と不足しているセクションが返されます。送信は行いません。 |
send_publish_request | PUT | confirm:true | アプリを Salla の審査に送信します。厳格な条件があります。validate の実行後、パートナーが /publish リンクを確認し、承認した場合に限り送信されます。confirm:true がない場合は送信されず、リンクが返されます。 |
withdraw | PUT | — | 審査中(送信済み/審査中)の公開申請を取り下げます。たとえば、開発環境より古い webhook 設定が含まれている場合に使用します。その後、再度 validate を実行して送信します。パートナーの了承がある場合に限ります。 |
掲載コンテンツ(名前、説明、ロゴ、スクリーンショット、特長)は
app_page_builder → salla-app-ui-builder で作成します。
まず現在の下書きを確認する(再開/レビュー)
入力や修正を行う前に、特に下書きの再開時やレビューを依頼された場合は、
app_publish action=get で内容を確認してください。publication_last_save(保存済みの各セクションの値)に加え、アプリの scopes と webhook_config(開発環境、最新の公開申請、承認済みの webhook 設定、およびパートナーに伝える note)が返されます。readiness では不足している項目を、get ではすでに入力済みの内容を確認できます。下書きにすでに保存されている値をパートナーに再度尋ねたり、確認していないセクションをそのまま上書きしたりしないでください。webhook の判断には publication_last_save.webhook_* ではなく、必ず webhook_config を参照してください。下書き側の値は validate/送信時にのみ更新されます。webhook_config.approved は次の承認まで本番ストアで使用される設定です(step-app-config.md → 各状態の確認方法と、各段階でパートナーに伝える内容)。
検証はステップごとに行います
3 つのレイヤーを順番に実行します。最後にまとめて一括チェックすることにすべてを委ねないでください。
setはセクションごとに形式を検証します(サーバーのPublicationSectionRequest:例として、short_descriptionは 50~200 文字、video_url/URL は適切な形式、プランには数値ルールが適用されます)。422 を返すsetは、このセクションの検証エラーです。ツールがフィールドごとのメッセージを表示するので、修正してから次に進む前にsetを再実行してください。readinessは入力状況を報告します。completeになっているセクションと、正確なmissing(空欄)フィールドを確認できます。入力済みであることと正しいことは別です。フィールドが入力されていても無効ならsetで検出され、空欄ならreadinessで検出されます。validateは、下書き全体を対象にした、フィールド間の整合性と必須項目の最終チェックです。問題がなければ下書きを保存し、問題があれば 422 と、未入力のセクションを返します。
一連の流れ:set <section> → 422 の場合はこのセクションを修正 → readiness → 次へ。フローの最後に validate を一度だけ実行するのではなく、各セクションを記述しながらエラーを検出してください。
ステップ一覧 — このスキルが全体を振り分けます
各公開ステップは、そのモデリングを担当するスキルに振り分けられます。それぞれにリファレンス(データ取得 → 提出スキーマ → 提出方法)があります。
| ステップ(公開セクション) | 担当スキル | リファレンス |
|---|---|---|
| 基本情報 | このスキル | step-basic-information.md |
アプリ設定(スコープ/Webhook — set セクションではありません) | salla-app-auth + salla-webhooks | step-app-config.md |
| 機能(バナー/埋め込み画像、スクリーンショット/メリット) | salla-app-ui-builder | step-features.md |
| 料金 | salla-app-billing | step-pricing.md |
| 連絡先情報 | このスキル | step-contact.md |
| サービストライアル/審査 | このスキル + salla-app-billing | step-service-trial.md |
app_page_builderは App Store の掲載/プロフィールページのビルダーです — 公開アプリのプロフィール(評価、プラン、インストールボタン)を作成します。公開フローと連動しており、下書きから画像/テキスト/プランを取得できます。また、公開の下書きに対して編集でき、画像とコンテンツは公開内容を上書きします。インストール後の埋め込みダッシュボード UI ではありません(→ salla-embedded-app/ salla-embedded-ui)。
5 つのセクションの概要
section と、書き込むフィールドのみを渡します(ローカライズされたフィールドは { ar, en }、画像フィールドは salla_upload の整数 ID、複数値のフィールドは配列を指定します)。各フィールドのスキーマ、サーバー側のルール、set の具体例は各ステップのリファレンス(上記のステップ一覧)に記載されています。書き込む前に確認してください。
| セクション | 設定項目(概要) | リファレンス |
|---|---|---|
basic_information | short_description、main_category_id(App Theme/Impact)、categories、video_url(必須)、demo_url、search_terms、supported_countries | step-basic-information.md |
features | banner、embedded_image(スクリーンショット/メリット → app_page_builder) | step-features.md |
pricing | plan_type と、そのタイプの plan/addon/once フィールド | step-pricing.md → salla-app-billing |
contact_information | contact_method、通知/送信/サポート連絡先、website_url、policy_url、faq_url | step-contact.md |
service_trial | service_link、trial_username、trial_password、trial_description、update_note(更新時のみ) | step-service-trial.md |
別の場所で設定 — app_publish では設定しません
これらは公開セクションの外部にあります。それぞれ専用のツールで確定してから、準備状況を再確認してください。
| 項目 | 設定場所 |
|---|---|
リスティングのコンテンツ:name、description、logo、screenshots、benefits | app_page_builder → salla-app-ui-builder |
| OAuth スコープ(必要最小限をリクエスト) | salla_scopes → salla-app-auth |
| Webhook の URL/署名シークレット/ヘッダー | salla_apps action=connect → salla-webhooks |
ストアイベントのサブスクリプション(order.*、product.*、…) | salla_events action=subscribe → salla-webhooks |
| マーチャント設定 FORM | salla_settings → salla-app-settings |
セキュリティレビューの確認項目は、それぞれを担当するスキルに属します。OAuth スコープの最小化 → salla-app-auth;Webhook 署名の検証と認証済みインターフェース → salla-webhooks;シークレットの取り扱い → 認証情報はテスト専用とし、必ずマスキングして、平文では決して扱わないでください。
ドラフトは validate 時点のスナップショットであり、ライブ状態を常に反映するものではありません。設定はドラフトの保存時にスナップショットとして記録され、ライブ状態と照合されるため、外部の項目をすべて確定してから validate を実行し、設定は最後に行ってください。
- 設定フォーム(
salla_settings)はvalidateの前に確定してください。ドラフトの保存時に有効な設定が、そのままパートナーの提出内容になります。 - Communication apps は
validateの前に、対応機能を宣言する必要があります(salla_settings action=set_features)。宣言しないとゲートでブロックされます。 - Webhook の URL、ストラテジー、シークレット、サブスクライブするイベント、ヘッダーは、
validateと提出の際にドラフトへコピーされ、承認後にのみマーチャントのライブストアに反映されます。これらはwebhook_configから読み取ってください。approved.differs_from_developmentが空でない場合、ライブストアではまだ古い設定が使われています。また、審査中のlatest_publicationが異なる場合は、さらに古い設定が適用されています。 - 外部の項目(スコープ、Webhook、イベント、設定、ビルダーコンテンツ)を変更した後は、引き継ぐ前に
readinessを再実行し(必要に応じてopenを再実行)、validateも再実行してください。
初回公開 — やみくもに項目を埋めず、ガイドに沿って進めます
公開に関する各セクションには、パートナーのビジネス上の決定事項(掲載文、カテゴリ、料金/プラン/トライアル、連絡先、対応国、スクリーンショット/メリット)が含まれます。初回公開では、パートナーがセクションを一つずつ進められるよう案内し、それぞれの項目をパートナーの回答に基づいて入力してください。決して内容を作り出したり、自動入力したりしないでください。各セクションでは、以下のように進めます。
- そのセクションに適した質問をします。例:
basic_information→ 提供価値/短い説明、メインカテゴリとサブカテゴリ、対応国、デモ/動画の URL はありますか?(video_urlは必須です。動画がない場合は、教育用動画ガイドを案内してください:https://salla.dev/tutorial/educational-video-guidelines-apps-ar/)pricing→ 無料ですか、それとも有料ですか?買い切り、サブスクリプションプラン、アドオンのどれですか?トライアルはありますか?contact_information→ サポート用メールアドレス/電話番号、ポリシーと FAQ の URL はありますか?- アプリ情報(
app_page_builder)→ 名前、説明、ロゴ、3 枚以上のスクリーンショット、メリットはありますか?
- Salla に基づく有効な選択肢を提案し、推測ではなく実際の選択肢からパートナーが選べるようにします。実際のカテゴリは
salla_reference action=categoriesから、料金モデルは Salla の課金でサポートされているもの(無料/買い切り/サブスクリプションプラン+アドオン+トライアル → salla-app-billing)から、対応国の選択肢はsalla_reference action=countriesから提示します。 - 回答に基づいて入力し、次に
app_publish action=readinessを実行して不足している項目を確認してから、次のセクションに進みます。
公開時に設定する収益化機能を提案します。 初回公開はこれらを設定するタイミングです。それぞれを根拠のある任意選択として提示し、自動追加はせず、salla-app-billing/salla-addon-purchase に案内します。
- アドオン — どのプランにも追加できる、アプリ内の追加購入項目です。
- トライアル — 無料の
plan_trial(日数単位)、および/またはレビュアーサービスのトライアルです。 - プロモーション — 期間限定のプラン割引(
promotions[])です。 - 比較表 —
plan_features[]を使ってプランを横並びで比較できます。 - おすすめ/ハイライト表示プラン —
recommended、is_compare_includedです。 - 取り消し線付き価格 —
one_time_old_price(買い切りの場合)またはプランのold_priceです。 - 数量調整 —
plan_additional_features(買い切りの場合)/プランごとのadditional_featuresです。 - 解約防止 —
unsubscribe_reward、unsubscribe_email_rewardです。
公開時のみ設定できる項目がどれかを伝えてください。店舗ごとの個別プランは、後からアプリの詳細 → カスタムプランで設定できます。有料の選択肢を選ぶと、課金サイクルの確認ゲート(以下)が適用されます。
この手順は、以下の画像アセットのルールと組み合わせます(画像を依頼し、提供されない場合は明示したプレースホルダーを使い、差し替えが必要であることを伝えます)。
確認ゲート:「各セクションには、掲載文、カテゴリ、料金、連絡先など、パートナーの回答に基づいて入力されていますか?自動的に内容を作り出していませんか?」
掲載画像 — まず依頼し、事前説明をした場合のみプレースホルダーを使用
掲載には実際の画像が必要です。logo と3 枚以上のスクリーンショット(アプリ情報)、banner と embedded_image(アプリの機能)が必要です。これらは salla-app-ui-builder が担当します。各フィールド、寸法、生成してからアップロードする手順を確認してください。ここで守るべきことは次のとおりです。
- 画像がない場合は、必要な画像をすべてユーザーに提供してもらってください。 実物のように見える画像を作り出したり、黙って省略したりしてはいけません。これは、確認してから進め、決して作り出さないという方針です。
- ユーザーがスキップまたは辞退した場合は、明示したデフォルトのプレースホルダーを使って進め、下書きが検証に通る状態にします。 そのうえで、ワンクリックで送信する前に、ポータルでプレースホルダーを差し替えるよう、パートナーに必ず伝えてください。 プレースホルダーを最終版として提示してはいけません。
確認ゲート:「掲載画像はすべてパートナーが実際に用意したアセットですか?それとも、送信前に差し替えるようパートナーに明示したプレースホルダーですか?」
公開前の手順(順番どおり)
- 下書きを開き(
action=open)、最初の準備状況チェックリストを確認します。 - 未完了の各セクションの
dataをsetし、その都度readinessを再確認します。返されたmissingリストに基づき、一度に1セクションずつ進めます。 app_page_builder→ salla-app-ui-builderを使って、ビルダーのコンテンツ(スクリーンショット、メリット、掲載名/説明/ロゴ)を作成し、featuresを完了させます。不足している画像がある場合は、前述の画像アセットのルールに従います。- 設定フォーム(
salla_settings)を最終確定します。コミュニケーションアプリの場合は、salla_settings action=set_featuresを実行します。 readinessを再実行し、5つすべてのセクションがcompleteと表示されることを確認します。- 下書きを検証して保存します(
action=validate)。422が返された場合は、不足しているセクションをsetし、有効な公開データが返されるまでvalidateを再実行します。 6b. 課金サイクルのゲート — 有料料金の場合のみ、送信前に実施。 下書きの料金に定期プランまたはアドオンが含まれている場合、アプリが審査に進む前にサブスクリプションのライフサイクルに対応している必要があります。このライフサイクルはアプリイベント(app.subscription.*/app.trial.*)を介して処理されます。アプリはデフォルトでこれらのイベントを購読しており、Sallaがwebhook_urlに自動配信します。そのため、購読状態を確認するAPI呼び出しはありません。自動チェック:salla_apps action=getでwebhook_urlが設定されていること、およびパートナーのハンドラーがapp.subscription.*/app.trial.*の全イベントに対応していることを確認します(→ salla-app-billing ステップ2)。これで確認できるのは受信側がプラットフォームレベルで接続されていることだけであり、ハンドラーのコードがデプロイされ、動作していることではありません。そのため、実際に往復確認も行います。デモストアでサブスクリプションのテストイベントを発火させ、アプリが正しくプロビジョニング/取り消しを行うことを確認します(→ salla-live-testing)。 次にユーザー確認: パートナーに、ライフサイクル全体を対象とするハンドラーがデプロイ済みでテスト済みであることを確認してもらいます。具体的には、started時のプロビジョニング、renewed時の権限の再設定、expired/canceled時の取り消し(item_typeがプランかアドオンかも確認)、およびexternal_recurringアドオンの更新APIが接続されていることです(→ salla-app-billing)。 整合性が取れていない場合は送信しないでください。保存済みの下書きを維持し、課金サイクルの実装をsalla-app-billing/salla-addon-purchaseに引き継いだうえで、再確認してゲートを再実施します。整合性の取れた課金サイクルが確認できた場合にのみ、このゲートを通過できます。 - パートナーにレビューを依頼してから、公開リクエストを送信します。 アプリの実際のIDを指定したPortalリンクをパートナーに伝えます。プレースホルダーは使用しないでください。
https://portal.salla.partners/apps/{app_id}/publish(例:https://portal.salla.partners/apps/1234567/publish)。そのリンクから下書きをレビューするよう伝えます。レビューに進むには、パートナーがPortalでワンクリックで送信するか、パートナーの明示的な確認を得た後に限り、confirm: trueを指定してapp_publish action=send_publish_requestを呼び出します。厳守事項:validateが問題なく完了し、パートナーにリンクを提示して確認を得るまでは、リクエストを送信しないでください。
ゲート:「すべてのセクションが検証され、下書きとして保存されている。有料料金(定期プランまたはアドオンあり)の場合、課金サイクルが接続され、確認済みである(そうでなければ、対応が完了するまで下書きとして保持されている)。パートナーに実際の/publishリンクを渡してレビューを依頼済みであり、send_publish_requestを実行するのはパートナーの確認後のみ(またはパートナー自身がワンクリックで送信する場合のみ)である。」
(エージェントにとっての)完了とは、validateが有効な公開データを返し、パートナーが実際の/publishリンクを確認済みであることを意味します。アプリが審査に進むのは、パートナーがワンクリックで送信した場合、またはパートナーの明示的な確認を得た後にsend_publish_request confirm=trueを実行した場合のみです。それより前に進めてはいけません。
注意すべき兆候
| ありがちな考え | なぜ間違っているのか |
|---|---|
| 「検証が成功したので、仕上げに公開リクエストを送信します。」 | send_publish_request は厳格なゲートが設けられており、パートナーが /publish リンクでドラフトを確認し、明示的に承認した後(Step 7)にのみ実行できます。検証に問題がなかっただけで送信しないでください。 |
「…/apps/{app_id}/publish のテンプレートをそのまま渡せば、相手が入力してくれます。」 | 実際の app id に置き換えてください(Step 7)。プレースホルダーのリンクではパートナーはどこにも移動できず、申請もできません。 |
| 「画像が提供されていないので、省略する/プレースホルダーを入れて先に進みます。」 | まずユーザーに確認してください。ユーザーが不要と回答した場合は、プレースホルダーであることを明確に示したうえで使用し、申請前にポータルで差し替えるよう伝えてください。 |
| 「公開準備を整えるため、説明文を作成して/カテゴリを選んで/価格を設定します。」 | これらはパートナーが決定するビジネス上の事項です。パートナーに確認し、Salla に基づく選択肢を提案して、その回答をもとに入力してください。ゲートを通過するために、セクションを捏造したり、確認せずに入力したりしないでください。 |
| 「検証に合格し、アプリはサブスクリプション/アドオンを販売するので、申請します。」 | 有料プランの価格設定には、まず課金サイクルの組み込みと確認が必要です(Step 6b)。未対応の場合は、保存済みのドラフトを維持し、申請前に課金サイクル(salla-app-billing / salla-addon-purchase)を実装してください。 |
「webhook_url が設定されているので、レビューに進めます。」 | 受信と処理は別です。app.subscription.* / app.trial.* イベントは webhook_url に自動配信されます(アプリイベントのため、subscribe の呼び出しは不要)。したがって、自動チェックで確認できるのは PLATFORM レベルで受信先が接続されていることだけであり、ハンドラーがデプロイされ、正常に動作していることではありません。申請前に、アプリが started でリソースをプロビジョニングし、renewed で参照先を更新し、expired / canceled で取り消し(item_type を確認)、external_recurring では更新 API を呼び出す必要があります。また、実際のテストイベントで検証する必要があります(salla-live-testing)(Step 6b)。 |
| 「まず、アプリをサブスクリプション/トライアルのイベントに登録する必要があります。」 | その必要はありません。これらはアプリイベントであり、アプリはデフォルトで自身のアプリイベントを購読しているため、webhook_url に自動配信されます。確認すべき subscribe の手順はありません。salla_events action=subscribe はストアイベント(order.*、product.*)用です。課金のゲートで必要なのは、webhook_url が設定されていることと、ハンドラーがイベントファミリー全体を処理することです(Step 6b → salla-app-billing Step 2)。 |
| 「すべてのセクションが完了したので、申請します。」(アプリが公開可能でない/未検証) | まず前提条件を確認してください。can_publish が true であり、パートナーのアカウントが portal.salla.partners/account で検証済みである必要があります(未検証のアカウントで申請すると id_verification で失敗します)。SMS 通信アプリには、検証フォームで CITC 認定を受ける必要があります(salla-communication-app)。 |
「sub_category_id の呼び出しから得た type の結果を、main_category_id にも使います。」 | main_category_id は type に依存しません。常に同じ salla_reference action=categories 呼び出しの main_categories(カテゴリタイプ app_impact。すべてのアプリタイプで共通の「App Theme」/「App Impact」リスト)から取得します。categories 配列は、これとは別の3つ目のリスト(カテゴリタイプ app)です。どちらも、create の sub_category_id に使う sub_categories ツリーではありません(step-basic-information.md)。 |