App Store Connect API|快速读取与管理 Customer Reviews,提升 iOS App 评价整合效率
针对 iOS 开发者,解决以往透过 RSS 或 Fastlane 爬取 App 评价不稳定、需手动更新 Session 的痛点,利用 App Store Connect API 2.0+ 自动化存取与管理 Customer Reviews,减少维护成本并提升资料完整性与稳定性。
基于 SEO 考量,本文标题与描述经 AI 调整,原始版本请参考内文。
文章目录
App Store Connect API 现已支援 读取和管理 Customer Reviews
App Store Connect API 2.0+ 全面更新,支援 In-app purchases、Subscriptions、Customer Reviews 管理
2022/07/19 News
Upcoming transition from the XML feed to the App Store Connect API
今早收到 Apple 开发者最新消息 ,App Store Connect API 新增支援 In-app purchases、Subscriptions、Customer Reviews 管理三项功能;让开发者可以更弹性的将 Apple 开发流程与 CI/CD 或是商业后台做更密切、有效率的整合!
In-app purchases、Subscriptions 我没碰,Customer Reviews 让我兴奋不已,之前发表过一篇「 AppStore APP’s Reviews Slack Bot 那些事 」探讨 App 评价与工作流程整合的方式。
Slack 评价机器人 — ZReviewsBot
在 App Store Connect API 还没支援之前,只有两种方法能获取 iOS App 评价:
一 是 透过订阅 Public RSS 取得,但是此 RSS 无法让人弹性筛选、给的资讯也少、有数量上限、还有我们偶尔会遇到资料错乱问题,很不稳定
二 是 透过 Fastlane — SpaceShip 帮我们封装复杂的网页操作、Session 管理,去 App Store Connection 网站后台捞取评价资料 (等于是起一个网页模拟器爬虫去后台爬资料)。
好处是资料齐全、稳定,我们串接了一年没有遇到任何资料问题。
坏处是 Session 每个月都会过期,要手动重新登入,而且 Apple ID 目前全面都要绑定 2FA 验证,所以这段也要手动完成,这样才能产出有效的 Session;另外 Session 如果产的跟用的 IP 不一样会马上过期 (因此很难将机器人放上不固定 IP 的网路服务)。
important-note-about-session-duration by Fastlane
- 每个月不定时过期,要不定时去更新,时间久了真的很烦;而且这个 「 Know How 」其实不好交接给其他同事。
但因为没有其他方法,所以也只能这样,直到今天早上收到消息….
⚠️ 注意:官方预计在 2022/11 取消原本的 XML (RSS) 存取方式。
2022/08/10 Update
我已基于新的 App Store Connect API 开发了新的 「 ZReviewTender — 免费开源的 App Reviews 监控机器人 」
App Store Connect API 2.0+ Customer Reviews 试玩
建立 App Store Connect API Key
首先我们要登入 App Store Connect 后台,前往「Users and Access」->「Keys」->「 App Store Connect API 」:
点击「+」,输入名称和权限;权限细则可参考官网说明,为了减少测试问题,这边先选择「App Manager」把权限开到最大。
点击右方「Download API Key」下载保存你的「AuthKey_XXX.p8」Key。
⚠️ 注意:这个 Key 只能下载一次请 妥善保存 ,若遗失只能 Revoke 现有的 & 重新建立。⚠️
⚠️ 切勿外泄 .p8 Key File⚠️
App Store Connect API 存取方式
1
curl -v -H 'Authorization: Bearer [signed token]' "https://api.appstoreconnect.apple.com/v1/apps"
Signed Token (JWT, JSON Web Token) 产生方式
参考 官方文件 。
- JWT Header:
1
{kid:"YOUR_KEY_ID", typ:"JWT", alg:"ES256"}
YOUR_KEY_ID :参考上图。
- JWT Payload:
1
2
3
4
5
6
{
iss: 'YOUR_ISSUE_ID',
iat: TOKEN 建立时间 (UNIX TIMESTAMP e.g 1658326020),
exp: TOKEN 失效时间 (UNIX TIMESTAMP e.g 1658327220),
aud: 'appstoreconnect-v1'
}
YOUR_ISSUE_ID :参考上图。
exp TOKEN 失效时间 :会因为不同存取功能或设定有不同的时间限制,有的可以永久、有的超过 20 分钟即失效,需要重新产生,详细可参考 官方说明 。
使用 JWT.IO 或是以下附的 Ruby 范例产生 JWT
jwt.rb:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
require 'jwt'
require 'time'
keyFile = File.read('./AuthKey_XXXX.p8') # YOUR .p8 private key file path
privateKey = OpenSSL::PKey::EC.new(keyFile)
payload = {
iss: 'YOUR_ISSUE_ID',
iat: Time.now.to_i,
exp: Time.now.to_i + 60*20,
aud: 'appstoreconnect-v1'
}
token = JWT.encode payload, privateKey, 'ES256', header_fields={kid:"YOUR_KEY_ID", typ:"JWT"}
puts token
decoded_token = JWT.decode token, privateKey, true, { algorithm: 'ES256' }
puts decoded_token
- Ruyb JWT 工具在此: https://github.com/jwt/ruby-jwt
最终会得到类似以下的 JWT 结果:
1
4oxjoi8j69rHQ58KqPtrFABBWHX2QH7iGFyjkc5q6AJZrKA3AcZcCFoFMTMHpM.pojTEWQufMTvfZUW1nKz66p3emsy2v5QseJX5UJmfRjpxfjgELUGJraEVtX7tVg6aicmJT96q0snP034MhfgoZAB46MGdtC6kv2Vj6VeL2geuXG87Ys6ADijhT7mfHUcbmLPJPNZNuMttcc.fuFAJZNijRHnCA2BRqq7RZEJBB7TLsm1n4WM1cW0yo67KZp-Bnwx9y45cmH82QPAgKcG-y1UhRUrxybi5b9iNN
打看看?
有了 Token 我们就能来打看看 App Store Connect API!
1
curl -H 'Authorization: Bearer JWT' "https://api.appstoreconnect.apple.com/v1/apps/APPID/customerReviews"
APPID可从 App Store Connect 后台取得:
或是 App 商城页面:
APPID =
557252416
成功!🚀 我们现在可以使用这个方式捞取 App 评价,资料完整且可以完全交给机器执行,不需人工例行维护 (JWT 虽会过期,但是 Private Key 不会,我们每次请求都可借由 Private Key 签名产生 JWT 去存取即可)。
其他筛选参数、操作方法请参考 官方文件 。
⚠️ 您只能存取您有权限的 App 评价资料⚠️
完整 Ruby 测试专案
用一个 Ruby 档案做了以上流程,可直接 Clone 下来填入资料即可测试使用。
首次打开:
1
bundle install
开始使用:
1
bundle exec ruby jwt.rb
Next
同理我们可以透过 API 去存取管理 ( API Overview ):
[New] Customer reviews
[New] Subscriptions
[New] In-App Purchases
[Updated] Improving your App’s Performance
有任何问题及指教欢迎 与我联络 。
本文首次发表于 Medium (点击查看原始版本),由 ZMediumToMarkdown 提供自动转换与同步技术。

{:target="_blank"}](/assets/f1365e51902c/1*igukM7FTLxaX2hpVtFPMjQ.webp)
{:target="_blank"} by Fastlane](/assets/f1365e51902c/0*iMQRza9LN3ljy2k1.webp)




