阅读 423

如何自动化获取AppStore的销售和趋势报告

我在上一篇文章 《App Store Connect API》中介绍了App Store Connect API的常用功能,这一篇文章重点聊聊”销售和趋势报告“。

需求:
自动化地从苹果后台获取App的每日销售记录(下载量),方便分析和统计。

App Store Connect里的销售记录

我们先看看如何通过App Store Connect网页查看和下载App的销售记录。
”App分析“和”销售和趋势“里都能看到每日销售明细,且可以下载对应的数据(图中红圈处)。

App分析

销售和趋势

可惜的是,苹果并没有开放这些明细API,仅仅开放了下载”销售和趋势报告“的API,这是一个销售总报告,没有每日明细,而且报告内容的格式有些”糟糕“。

下载”销售和趋势报告“

“销售和趋势报告”长什么样?

月”销售和趋势报告“示例

看完上面的月报告示例(下载下来的销售报告是.gz格式的,解压后是.txt格式的,你可以用Excel打开),你的内心是否是崩溃的😂。咋一看以为每一行是每天的销售明细,实际上不同的行是苹果按国家代码、货币代码、同一开发者下不同App来等指标来分的不同指标下的销售总量,只要指标有一条不一样,报告里就会单独列一行,你想知道10月份各个App的总的销售量,还得先按App分组后在对Units指标求和...

日报告,和上面格式一样。如果你想知道一个月的每日销量明细,官方API下,只能一天一天的下载每天的销售报告了
报告里各字段含义

难道我们就这样坐以待毙了吗,当然不是!
非官方API下,Fastlane - Spaceship 通过抓取App Store Connect - ”App分析“模块的网页数据,提供了获取到每日销量明细的API,后文详细介绍。

获取”销售和趋势报告“的三种方式

本文将介绍三种方式获取销售和趋势报告:

  • 【苹果官方】App Store Connect API:REST API,下载销售和趋势报告(.txt文件)
  • 【苹果官方】Reporter 命令行工具:.jar包,跨平台,下载销售和趋势报告(.txt文件)
  • 【第三方开源】Fastlane - Spaceship:需要Ruby环境,获取每日销售明细(json数据)

App Store Connect API

App Store Connect API 是苹果官方提供的REST API,其中的下载销售和趋势报告API,可以下载每日、每周、每月、每年的销售和趋势汇总报告,这个和手动在网页上下载报告是一样的效果。
请求头需要带上token,如何生成token请参考我上一篇文章 《App Store Connect API》

下载销售和趋势报告
GET https://api.appstoreconnect.apple.com/v1/salesReports
请求参数
filter[reportType]:报告类型,SALES, PRE_ORDER, NEWSSTAND, SUBSCRIPTION, SUBSCRIPTION_EVENT, SUBSCRIBER
filter[reportSubType]:报告子类型,SUMMARY, DETAILED, OPT_IN
filter[frequency]:报告周期,DAILY, WEEKLY, MONTHLY, YEARLY
filter[reportDate]:报告时间,传你想获取的报告时间,格式:YYYY-MM-DD(日报;周报,周一到周天,只能传周天的时间,否则报错),YYYY-MM(月报),YYYY(年报),例如 2019-10
filter[vendorNumber]:供应商号,App Store Connect - 付款和财务报告,左上角那串数字
filter[version]:接口版本号,可不传。
成功返回200,返回数据为文件流,.gz(压缩文件)类型的文件,解压后为 .txt。
失败返回json,会有很详细的错误提示,根据错误提示修改即可。

月报 请求示例
curl 'https://api.appstoreconnect.apple.com/v1/salesReports?filter[reportSubType]=SUMMARY&filter[reportType]=SALES&filter[vendorNumber]=88xxxxx&filter[frequency]=MONTHLY&filter[reportDate]=2019-10' -H 'Authorization: Bearer eyJhbGci...h5T-JUcdCP_CVuKMWgm3g' -g > /Users/Cocoakier/Movies/a.gzip
(-g 是因为token中包含特殊字符)

周报 请求参数示例:
curl 'https://api.appstoreconnect.apple.com/v1/salesReports?filter[reportSubType]=SUMMARY&filter[reportType]=SALES&filter[vendorNumber]=88xxxxx&filter[frequency]=WEEKLY&filter[reportDate]=2019-11-17' -H 'Authorization: Bearer eyJhbGci...h5T-JUcdCP_CVuKMWgm3g' -g > /Users/Cocoakier/Movies/a.gzip

注意事项(必看):

  • 参数关联组合
    reportType、reportSubType、frequency、reportDate这四个参数的组合必须遵循下面这张表,否则会报错。
    注意:周报,filter[frequency]=WEEKLY,是从周一到周天,reportDate只能传周天的日期,传其它日期会报错。

    参数关联组合

    我们最常用的是第一行的组合,其它组合可以看这里

  • 报告可用性
    销售报告可用性是有严格时间限制的,传入还未可用的报告reportDate,会报错。下面是苹果文档上的描述:

“销售和趋势”报告在以下时间可供下载:
- 每日报告可于次日获取
- 每周报告可在每周一获取
- 每月报告可在该月月末的五天后获取
- 年度报告可以在该年年末的六天后获取
报告通常在太平洋标准时间(PST)早上 8 点(楼主注:北京时间00:00)提供。
【注】每日报告、每周报告和每月报告在提供后保留一年。年度报告无限期保留。到期后,我们不再存储或重新生成报告以供下载。

但是,由于北京时间比太平洋时间快了16小时,今天我们这边11月21日了,美国那边才11月20日,根据报告次日可用,所以报告只能看到11月19日的。这就导致了,报告实际延迟了两天!即,今天只能看到前天的报告,这对运营来说恐怕是灾难的。

报告实际上延迟了2天

  • token无效或没有授权。
    我测试的时候发现,有时候会报token无效或没有授权,重新生成一个token仍然报错,实际上token没有问题,其它GET接口可以成功,是请求参数传的有问题,比如报告不可用,或者参数组合有问题,自己注意检查!

Reporter 命令行工具

下载销售和趋势报告,苹果还专门提供了一个.jar的命令行工具——Reporter,这个东西只干能一件事,就是下载报告。Reporter官方文档
别看文档是java的就望而却步了,楼主最开始也有这种感觉,后来静下心来把官方文档看完了,发现这个工具虽然是java开发的,但是使用起来很简单,用来下载报告比App Store Connect API“更专业”。

下载Reporter

下载,解压后有两个文件:(请确保两个文件在同一目录下)

  • Reporter.jar,命令行工具
  • Reporter.properties,属性文件,用于存放配置参数(访问令牌等)

访问令牌

Reporter需要在属性文件中配置访问令牌才能使用。访问令牌是App Store Connect 后台生成的一串字符串。

生成访问令牌,有两种生成方式:

  • 去网页手动生成。App Store Connect后台 - 销售和趋势 - (左边)销售和趋势报告 - (右上角)关于报告 - 生成Reporter令牌
  • 通过命令生成,需要输入苹果账号和密码。(详见下文API部分)。注意:开通双重认证的账号无法使用命令生成访问令牌,只能通过网页手动生成
    手动生成访问令牌

注意事项

  • 访问令牌有效期180天。每个 Apple ID 每次仅可生成一个访问令牌。如果您生成了新的访问令牌,先前的访问令牌将立即过期。
  • 您只需生成一个访问令牌即可访问销售和财务应用程序。无需生成单独的访问令牌。

属性文件

下载的文件中有个Reporter.properties文件,这是属性文件,用于存放Reporter的默认配置参数。

  • 每个属性单独成行,包括一个 Key 和其对应的值,值不需要加引号
  • 如果命令行中传入的属性参数,则会覆盖属性文件中的属性
  • 属性文件中的Account,并不是苹果开发者账号的值,这个值是苹果账号的隐式id,需要通过命令(见下文)获取。

属性文件

下面是属性文件的全部key-value,官方文档

属性 属性文件格式 命令行格式 含义
AccessToken AccessToken=d21xxx-xxxx-xxxx-xx0a 访问令牌
Account Account=119xxxxxx a=119xxxxxx 苹果账号account num(不是苹果账号);如果您的 Apple ID 具有多个帐户的访问权限,您需要指定您要使用的帐号。
Mode Mode=Normal Mode=Robot.XML m=Normal m=Robot.XML 模式
普通模式:返回纯文本
机器人模式:返回XML
SalesUrl 不用管,用默认值就行 销售报告版本ur
FinanceUrl 不用管,用默认值就行 收入报告版本url

常用命令

打开终端,cd 到.jar包的目录,执行下列命名。

命令通用格式
java -jar Reporter.jar p=[properties file name] a=[account number] m=[mode] Sales.[command]
java -jar Reporter.jar p=[properties file name] a=[account number] m=[mode] Finance.[command]

生成访问令牌(根据提示输入苹果账号和密码。注意,开通了双重认证的账号无法使用该命令)

java -jar Reporter.jar p=Reporter.properties Sales.generateToken

返回结果
Please type in your username: ********
Please type in your password: ********

Your access token has been generated.
AccessToken:d21xxx-xxxx-xxxx-xx0a
Expiration Date:2020-06-07
复制代码
查看访问令牌(根据提示输入苹果账号和密码)

java -jar Reporter.jar p=Reporter.properties Sales.viewToken

删除访问令牌

java -jar Reporter.jar p=Reporter.properties Sales.deleteToken

检查可用状态(校验token,返回0表示有效)

java -jar Reporter.jar p=Reporter.properties m=Robot.XML Sales.getStatus

返回结果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Status>
    <Message>Sales and Trends Reporter is currently available.</Message>
    <Code>0</Code>
</Status>
复制代码
获取Reporter版本(始终返回纯文本)

java -jar Reporter.jar getVersion

返回结果
1.0
复制代码
获取账号列表(account num)

一般模式(每个账号一行,用户名和ID用逗号分开)
java -jar Reporter.jar p=Reporter.properties Sales.getAccounts

返回结果
Jane Appleseed Inc, 12345
John Appleseed Inc, 67890
复制代码

机器人模式
java -jar Reporter.jar p=Reporter.properties m=Robot.XML Sales.getAccounts

返回结果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Accounts>
    <Account>
        <Name>Jane Appleseed Inc</Name>
        <Number>12345</Number>
    </Account>
    <Account>
        <Name>John Appleseed Inc</Name>
        <Number>67890</Number>
    </Account>
</Accounts>
复制代码
获取Vendor 编号(供应商号,下载报告需要传)

一般模式(每个 Vendor 编号都单独成行)
java -jar Reporter.jar p=Reporter.properties Sales.getVendors

返回结果
800xxxxx
801xxxxx
复制代码

机器人模式
java -jar Reporter.jar p=Reporter.properties m=Robot.XML Sales.getVendors

返回结果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Vendors>
    <Vendor>800xxxxx</Vendor>
    <Vendor>801xxxxx</Vendor>
</Vendors>
复制代码
下载销售和趋势报告

命令格式
java -jar Reporter.jar p=[properties file] Sales.getReport [vendor number], [report type], [report subtype], [date type], [date], [version]* (if applicable)
参数:
[vendor number]:供应商号,App Store Connect后台-付款和财务报告,左上角那串数字;或者使用上面介绍的getVendors命令获取。
[report Type]:报告类型,SALES, PRE_ORDER, NEWSSTAND, SUBSCRIPTION, SUBSCRIPTION_EVENT, SUBSCRIBER
[report SubType]:SUMMARY, DETAILED, OPT_IN
[date type]:日期类型,DAILY, WEEKLY, MONTHLY, YEARLY
[date]:日期,YYYYMMDD,YYYYMM,YYYY

使用示例(更多示例见官方文档
java -jar Reporter.jar p=Reporter.properties m=Robot.XML Sales.getReport 800xxxxx, SALES, SUMMARY, DAILY, 20191005

返回结果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Output>
    <Message>Successfully downloaded S_D_800xxxxx_20150201.txt.gz.</Message>
</Output>
复制代码

注意事项:

  1. Reporter下载报告的参数和App Store Connect API下载报告的参数基本一致,注意事项请参看App Store Connect API部分。
  2. 官方文档请求参数传的是首字母大写的单词,比如 Sales,经我测试,参数和App Store Connect API一样全部大写也是没有问题的,比如 SALES。
  3. 如果请求成功,报告会下载到当前目录下。

Fastlane - Spaceship

Fastlane是一套用Ruby开发的,开源的,用于解决iOS和Android自动化编译打包、上传、发布等工作的命令行工具集。其中,Spaceship提供了一套Apple Developer CenterApp Store Connect 的API。我在上一篇文章《App Store Connect API》中介绍了Spaceship的原理和优缺点。下面来介绍,如何通过Spaceship获取App的每日销售量。

与上面两个方案不同的是,Spaceship可以直接获取到每日销售量明细,而不是下载销售报告。我们可以通过Spaceship - App Analytics模块的API来实现。下面是一个返回示例。

{
	"size": 1,
	"results": [{
		"adamId": "147xxxxxx",
		"meetsThreshold": true,
		"group": null,
		"data": [{
			"date": "2019-10-01T00:00:00Z",
			"units": 1.0
		}, {
			"date": "2019-10-02T00:00:00Z",
			"units": 1.0
		}, {
			"date": "2019-10-03T00:00:00Z",
			"units": 0.0
		},
        ...
        ],
		"totals": {
			"value": 2.0,
			"type": "COUNT",
			"key": "units"
		}
	}]
}
复制代码

安装Fastlane
sudo gem install fastlane

你可以参考Spaceship文档一步一步操作,体验一下Spaceship的功能。

Spaceship文档上提到的获取销售量的的方法,只能获取到最近7天的销量,不够灵活。
sales = analytics.app_sales

我阅读了app_analytics.rb源码,写了一段Ruby代码,执行下面代码即可获取到指定时间范围内某个App的销售量了。(如果你开启了双重认证,请先把下列代码保存到文件a.rb后,打开终端执行ruby a.rb,双重认证需要根据提示输入验证码)

require "spaceship"
require "JSON"

APPLE_ACCOUNT = "xxxxxx@xxxx.com"			#苹果开发者账号
APPLE_ACCOUNT_PWD = "xxxxxxxxxxxxxxxx"		#苹果开发者密码
APP_ITUNES_ID = 148xxxxxxxx					#APP ID
start_t = "2019-11-01T00:00:00Z"			#查询开始时间
end_t = "2019-11-015T00:00:00Z"				#查询结束时间
# end_t = Time.now.strftime("%Y-%m-%dT00:00:00Z") #查询结束时间取当天

Spaceship::Tunes.login(APPLE_ACCOUNT, APPLE_ACCOUNT_PWD) #登录App Store Connect后台
# puts all_apps = Spaceship::Tunes::Application.all           #获取所有app信息,可以帮助你获取APP ID
app = Spaceship::Tunes::Application.find(APP_ITUNES_ID)  #获取App对象
sales = app.analytics.app_units_interval(start_t,end_t)         #获取 App分析-销售 信息
puts JSON.generate(sales)    #ruby对象转JSON,并打印
复制代码

注意事项:

  • 数据同样有两天延迟。Spaceship的原理是模拟网页请求,抓取网页数据。App Store Connect后台 - App 分析,显示的数据也遵循我上文说的延迟两天的规则。因此,Spaceship返回的销售数据最多只能返回前天的数据,如果查询不可用时间内销售数据,Spaceship并不会报错,只是返回的销售量为0,这点注意一下!
  • 双重认证。因为Spaceship需要登录苹果开发者账号,如果开启了双重认证,需要输入验证码,session有效期1个月。双重认证暂时没有好的对策,只能尽量用没有开启双重认证的苹果账号。(Tips:如果你是公司账号,你可以邀请一个没开通双重认证的账号加入你们团队,用这个没开启双重认证的账号进行Spaceship操作。)

总结

方法 优点 缺点 适用于
App Store Connect API 官方;REST API;私钥永久有效;不需要登录;不受双重认证限制 token需自行按算法生成;token有效期太短(15分钟);只能下载报告,没法获取明细 服务器后台
Reporter 官方;.jar包,跨平台;不需要登录;访问令牌有效期长(180天) 自动生成令牌受限双重认证;只能下载报告,没法获取明细 服务器后台(推荐)
Spaceship 开源;功能强大;能获取每日明细,返回JSON数据,可读性好 非官方;需要登录;需要双重认证(session有效期30天);需要Ruby环境 个人开发者
  1. 苹果的销售报告有2天的延迟,实时性太差,这也是苹果官方统计在国内不太被重视的一个重要原因吧。
  2. 对于公司开发者,推荐使用Reporter命令行工具,.jar包,跨平台,生成访问令牌简单,访问令牌有效期180天,适合服务器后台定期拉取销售和趋势报告,解析后存入数据库。虽然销售和趋势报告可读性不友好,但是文件里包含了丰富的字段,后台可以按需解析,灵活度更高,可定制化更强。
  3. 对于个人开发者,自动化获取AppStore销售报告的需求恐怕很弱了。苹果官方的Connect App或者直接网页浏览,完全可以满足需求。如果非要选一个的话,推荐使用Spaceship,返回JSON格式数据,可读性好,直接返回明细,不需要解析报告文件。
  4. 下载好销售和趋势报告,如何解析也是一个问题。如果后续有时间,我在研究一下这一块。

如果觉得这篇文章对你有帮助,请点个赞吧。如果有疑问可以关注我的公众号给我留言。
转载请注明出处,谢谢!

参考链接:
App Store Connect API 苹果官方文档
App Store Connect 帮助 - 下载和查看报告
Reporter 苹果官方文档
Spaceship Github

关注下面的标签,发现更多相似文章
评论