mcpField
A
asc-revenuecat-catalog-sync

asc-revenuecat-catalog-sync

github.com/rorkai开发1.1k6.1k 次安装2 天前更新
代码仓库

关于 asc-revenuecat-catalog-sync

用于核对 App Store Connect 与 RevenueCat 商品目录并按批准方案同步资源的工作流技能。它以只读审计为先,按产品标识映射,并在映射前执行严格校验。

主要功能

  1. 01审计两端目录并生成差异
  2. 02按 productId 建立映射
  3. 03创建及关联 RevenueCat 资源
  4. 04校验 ASC 订阅与 IAP
  5. 05写入前要求明确批准
  6. 06报告失败并保留审计结果

适用场景

  1. 01从现有 ASC 目录初始化 RevenueCat
  2. 02补建缺失订阅或 IAP 并映射
  3. 03发布前检查两端目录偏差

MCP 相关

该技能通过 RevenueCat MCP 服务读取和管理应用、产品、权益、Offering 与 Package,并将其关联至 App Store Connect 商品。MCP 不负责创建 ASC 商品;相关创建使用 asc 命令。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rorkai/app-store-connect-cli-skills --skill asc-revenuecat-catalog-sync

安装后在 Claude Code 中输入/asc-revenuecat-catalog-sync确认已加载。

附带文件examples.mdreferences.md

详细介绍

asc RevenueCat 目录同步

使用此技能保持 App Store Connect(ASC)与 RevenueCat 一致,包括创建缺失的 ASC 项目并将其映射到 RevenueCat 资源。

使用场景

  • 你想从现有 ASC 目录引导配置 RevenueCat。
  • 你想创建缺失的 ASC 订阅/IAP,然后将其映射到 RevenueCat。
  • 你需要在发布前审计差异。
  • 你想根据标识符确定性地映射产品。

前提条件

  • 已配置 asc 身份验证(asc auth login 或 ASC_* 环境变量)。
  • 已配置并完成身份验证的 RevenueCat MCP 服务。
  • 在 Cursor 和 VS Code 中,可通过 OAuth 对 RevenueCat MCP 进行身份验证。也支持 API 密钥身份验证。
  • 你需要知道:
    • ASC 应用 ID(APP_ID)
    • RevenueCat project_id
    • 目标 RevenueCat 应用类型(app_store 或 mac_app_store),以及创建流程所需的 Bundle ID
  • 应用更改时,请使用具有写入权限的 RevenueCat API v2 密钥。

安全默认设置

  • 从审计模式(只读)开始。
  • 写入前必须获得明确确认。
  • 此工作流中绝不删除资源。
  • 遇到单项失败时继续执行,并在最后报告所有失败。

规范标识符

  • 跨系统的主要键:ASC productId == RevenueCat store_identifier。
  • 产品上线后,保持 productId 稳定。
  • 不要使用显示名称作为唯一标识符。

范围边界

  • RevenueCat MCP 用于配置 RevenueCat 资源;它不会直接创建 App Store Connect 产品。
  • 使用 asc 命令创建缺失的 ASC 订阅组、订阅和 IAP,然后再映射到 RevenueCat。

模式

1)审计模式(默认)
  1. 读取 ASC 源目录。
  2. 读取 RevenueCat 目标目录。
  3. 构建差异计划,包含以下操作:
    • ASC 中缺失
    • RevenueCat 中缺失
    • 映射冲突(标识符/类型/应用不匹配)
  4. 呈现计划。仅审计请求在报告发现结果后结束;应用请求必须获得覆盖当前完整差异的批准。如果刷新后的差异未发生变化,则可沿用先前的批准。
2)应用模式(显式)

按以下顺序执行已批准的操作:

  1. 确保 ASC 订阅组/订阅/IAP 均已存在。
  2. 确保 RevenueCat 应用/产品均已存在。
  3. 确保权益和产品关联均已设置。
  4. 确保优惠和套餐及其关联均已设置。
  5. 验证并打印最终对账摘要。

分步工作流

步骤 A - 读取当前 ASC 目录
asc subscriptions groups list --app "APP_ID" --paginate --output json
asc iap list --app "APP_ID" --paginate --output json
# for each subscription group:
asc subscriptions list --group-id "GROUP_ID" --paginate --output json
步骤 B - 读取当前 RevenueCat 目录(MCP)

使用以下 MCP 工具(适用时提供 project_id 并进行分页):

  • mcp_RC_get_project
  • mcp_RC_list_apps
  • mcp_RC_list_products
  • mcp_RC_list_entitlements
  • mcp_RC_list_offerings
  • mcp_RC_list_packages
步骤 C - 制定映射计划

将 ASC 产品类型映射到 RevenueCat 产品类型:

  • ASC 订阅 -> RevenueCat subscription
  • ASC IAP CONSUMABLE -> RevenueCat consumable
  • ASC IAP NON_CONSUMABLE -> RevenueCat non_consumable
  • ASC IAP NON_RENEWING_SUBSCRIPTION -> RevenueCat non_renewing_subscription

建议的权益策略:

  • 订阅:每个订阅组对应一个权益(或使用用户提供的明确映射)
  • 非消耗型 IAP:每个产品对应一个权益
  • 消耗型 IAP:默认不配置权益,除非用户提出要求
步骤 D - 确保补齐缺失的 ASC 项(如有要求)

写入前先解析所有父项和版本。按精确的引用名称匹配分组,按 productId 匹配产品;切勿将显示名称视为标识。若资源已存在,则复用其规范 ID;只有在完整分页读取确认资源缺失后,才运行创建命令。RevenueCat 产品映射不能证明相应的 ASC 订阅已可供审核。

# Resolve GROUP_ID by exact referenceName.
asc subscriptions groups list --app "APP_ID" --paginate --output json
# If and only if the fully paginated list has zero exact matches:
asc subscriptions groups create --app "APP_ID" --reference-name "Premium" --output json
# For one match, reuse its ID. For more than one, stop and require an explicit GROUP_ID.

# Resolve SUB_ID by exact productId within GROUP_ID. Run setup only for a missing
# parent or an explicitly approved reconciliation of that same product ID.
asc subscriptions list --group-id "GROUP_ID" --paginate --output json
# If and only if the fully paginated list has zero exact matches, run setup:
asc subscriptions setup \
  --app "APP_ID" \
  --group-id "GROUP_ID" \
  --reference-name "Monthly" \
  --product-id "com.example.premium.monthly" \
  --subscription-period ONE_MONTH \
  --review-screenshot "./review.png" \
  --price "3.99" \
  --price-territory "USA" \
  --territories "USA" \
  --no-verify \
  --output json
# For one match, reuse its ID. For more than one, stop and require an explicit SUB_ID.
# Re-run setup for an existing SUB_ID only for an explicitly approved reconciliation.

# Resolve the unique mutable group version for this review lifecycle.
asc subscriptions groups versions list --group-id "GROUP_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
# If and only if the list has zero matches:
asc subscriptions groups versions create --group-id "GROUP_ID" --output json
# For one match, reuse .data[0].id. For more than one, stop and require an explicit GROUP_VERSION_ID.

# Resolve the en-US localization on GROUP_VERSION_ID. Create it only when
# missing; update the resolved localization ID when its values differ.
asc subscriptions groups versions localizations list --version-id "GROUP_VERSION_ID" --paginate --output json
asc subscriptions groups versions localizations create --version-id "GROUP_VERSION_ID" --locale "en-US" --name "Premium" --output json
asc subscriptions groups versions localizations update --id "GROUP_LOC_ID" --name "Premium"

# Resolve the unique mutable subscription version for this review lifecycle.
asc subscriptions versions list --subscription-id "SUB_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
# If and only if the list has zero matches:
asc subscriptions versions create --subscription-id "SUB_ID" --output json
# For one match, reuse .data[0].id. For more than one, stop and require an explicit SUBSCRIPTION_VERSION_ID.
asc subscriptions versions localizations list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output json
asc subscriptions versions localizations create --version-id "SUBSCRIPTION_VERSION_ID" --locale "en-US" --name "Premium Monthly" --description "Unlock all premium features." --output json
asc subscriptions versions localizations update --id "SUBSCRIPTION_LOC_ID" --name "Premium Monthly" --description "Unlock all premium features."

# Read back the exact versions selected above, then run the final strict validator.
asc subscriptions groups versions localizations list --version-id "GROUP_VERSION_ID" --paginate --output table
asc subscriptions versions localizations list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output table
asc validate subscriptions --app "APP_ID" --strict --output table

# Resolve IAP_ID by exact productId.
asc iap list --app "APP_ID" --paginate --output json
# If and only if the fully paginated list has zero exact matches:
asc iap create \
  --app "APP_ID" \
  --type NON_CONSUMABLE \
  --ref-name "Lifetime" \
  --product-id "com.example.lifetime" \
  --output json
# For one match, reuse its ID. For more than one, stop and require an explicit IAP_ID.

# Resolve the unique mutable IAP version for this review lifecycle.
asc iap versions list --iap-id "IAP_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
# If and only if the list has zero matches:
asc iap versions create --iap-id "IAP_ID" --output json
# For one match, reuse .data[0].id. For more than one, stop and require an explicit IAP_VERSION_ID.
asc iap versions localizations list --version-id "IAP_VERSION_ID" --paginate --output json
asc iap versions localizations create --version-id "IAP_VERSION_ID" --locale "en-US" --name "Lifetime" --description "Unlock all premium features." --output json
asc iap versions localizations update --localization-id "IAP_LOC_ID" --name "Lifetime" --description "Unlock all premium features."
asc iap versions localizations list --version-id "IAP_VERSION_ID" --paginate --output table

上方每对相邻的创建/更新操作都是有条件的,并非可以盲目依次执行的步骤:列表中没有匹配项时创建,已解析的匹配项值不同时更新,值已匹配时则不执行任何操作。从创建响应中提取 .data.id,或从前序列表中提取 .data[].id,作为后续命令使用的规范 ID。对于每个版本列表,若 PREPARE_FOR_SUBMISSION 匹配项为 0 个,则创建;若为 1 个,则复用该 ID;若超过 1 个,则停止并要求用户明确选择版本 ID。不要为了消除歧义而创建版本:实测中,删除父项并不能可靠地级联删除 IAP 或订阅版本。

subscriptions setup 会完成父项、App Review 截图交付、完整的 App Store 价格矩阵和销售可用性。版本范围内的命令会完成 RevenueCat 无法完成的分组和订阅本地化。销售可用性仅限于请求的地区;定价仍需涵盖 Apple 的完整均衡地区矩阵。在此拆分工作流中,--no-verify 是有意设置的,因为最终验证必须等到版本元数据存在后才能进行;明确的回读和验证器是最终关卡。

如果通过 API 创建的现有订阅仍为 MISSING_METADATA,即使所选基础价格未变,也请使用相同的设置输入重新运行,并加上 --repair。修复会以原子方式重建并重新保存完整的均衡价格矩阵;它不是重复提交单个价格的 POST 请求。

对于每个已解析的 ASC 订阅,在创建或关联其 RevenueCat 产品之前,都必须通过以下最终关卡。即使订阅及其所选版本已复用且没有任何 ASC 写入,也要在最终完成 ASC 对账后运行:

mkdir -p "./audit"
asc validate subscriptions --app "APP_ID" --strict --output json --pretty \
  > "./audit/subscriptions-validation.json"

对于每个已解析的 ASC IAP,在创建或关联其 RevenueCat 产品之前,都必须通过 IAP 关卡。即使 IAP 及其所选版本已复用且没有任何 ASC 写入,也要在最终完成 ASC 对账后运行:

mkdir -p "./audit"
asc validate iap --app "APP_ID" --strict --output json --pretty \
  > "./audit/iap-validation.json"

这两个命令都是严格的映射关卡,而非写入后的冒烟测试。验证报告中存在警告、错误、MISSING_METADATA、未处于 COMPLETE 状态的审核截图,或不完整/未经验证的定价覆盖时,不得映射任何已解析或已复用的订阅。验证器报告警告或错误时,不得映射任何已解析或已复用的 IAP。即使审计或应用运行没有写入操作,也必须执行适用的关卡,并要求其退出状态为 0,然后才能创建或关联 RevenueCat 产品。直接重定向会保留每个验证器的退出状态。将 ./audit/subscriptions-validation.json 和 ./audit/iap-validation.json 保留为最终审计证据。

步骤 E - 确保 RevenueCat 应用和产品

使用 MCP:

  • 缺失时创建应用:mcp_RC_create_app
  • 创建产品:mcp_RC_create_product
    • store_identifier = ASC productId
    • app_id = RevenueCat 应用 ID
    • type 来自上方的映射
步骤 F - 确保权益及关联关系

使用 MCP:

  • 列出/创建权益:mcp_RC_list_entitlements、mcp_RC_create_entitlement
  • 关联产品:mcp_RC_attach_products_to_entitlement
  • 验证关联关系:mcp_RC_get_products_from_entitlement
步骤 G - 确保提供项和套餐(可选)

使用 MCP:

  • 列出/创建/更新提供项:
    • mcp_RC_list_offerings
    • mcp_RC_create_offering
    • mcp_RC_update_offering(仅在请求时设置 is_current=true)
  • 列出/创建套餐:
    • mcp_RC_list_packages
    • mcp_RC_create_package
  • 将产品附加到套餐:
    • 使用 eligibility_criteria: "all" 调用 mcp_RC_attach_products_to_package

建议的套餐键:

  • ONE_WEEK -> $rc_weekly
  • ONE_MONTH -> $rc_monthly
  • TWO_MONTHS -> $rc_two_month
  • THREE_MONTHS -> $rc_three_month
  • SIX_MONTHS -> $rc_six_month
  • ONE_YEAR -> $rc_annual
  • 终身 IAP -> $rc_lifetime
  • 自定义 -> $rc_custom_<name>

预期输出格式

返回最终摘要,包含:

  • ASC 创建数量(组/订阅/IAP)
  • RevenueCat 创建数量(应用/产品/权益/提供项/套餐)
  • 附加数量(权益-产品、套餐-产品)
  • 已跳过的现有项目
  • 失败项目及可操作的错误信息

示例:

ASC: created groups=1 subscriptions=2 iap=1, skipped=14, failed=0
RC: created apps=0 products=3 entitlements=2 offerings=1 packages=2, skipped=27, failed=1
Attachments: entitlement_products=3 package_products=2
Failures:
- com.example.premium.annual: duplicate store_identifier exists on another RC app

Agent 行为

  • 始终先运行审计,即使处于应用模式也是如此。
  • 对创建/更新操作,复用涵盖当前完整差异的审批。仅当缺少审批,或有额外或实质性变更的操作不在审批范围内时,才再次询问。
  • 优先按 store_identifier 匹配。
  • 使用完整分页(ASC 使用 --paginate,RevenueCat 工具使用 starting_after)。
  • 单项失败后继续处理,并汇总报告所有失败。
  • 此技能绝不自动删除 ASC 或 RevenueCat 资源。
  • 对每个已解析的订阅(包括复用但不写入的匹配项),运行 asc validate subscriptions --app "APP_ID" --strict --output json --pretty 并保存其 JSON;除非验证门禁以零状态码退出,且不存在缺失元数据或定价不完整的情况,否则阻止创建或附加 RevenueCat 项目。
  • 对每个已解析的 IAP(包括复用但不写入的匹配项),运行 asc validate iap --app "APP_ID" --strict --output json --pretty 并保存其 JSON;除非验证门禁以零状态码退出,否则阻止创建或附加 RevenueCat 项目。

常见问题

  • RevenueCat project_id 或应用 ID 错误。
  • 在错误的平台应用下创建 RC 产品。
  • 意外将消耗型产品分配给权益。
  • 跳过创建后的 ASC 重新读取步骤。
  • 在 ASC 完成本地化、审核截图交付、完整价格矩阵和可用性设置之前,就映射 RevenueCat 产品。
  • 创建产品后未验证提供项/套餐。

其他资源

评论

支持 Markdown