pindo 4.6.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/bin/pindo +35 -0
  3. data/lib/pindo/base/aeshelper.rb +31 -0
  4. data/lib/pindo/base/deviceinfo.rb +90 -0
  5. data/lib/pindo/base/executable.rb +224 -0
  6. data/lib/pindo/base/githelper.rb +489 -0
  7. data/lib/pindo/base/hashhelper.rb +134 -0
  8. data/lib/pindo/base/plaininformative.rb +15 -0
  9. data/lib/pindo/base/plistbuddyexecutable.rb +121 -0
  10. data/lib/pindo/base/standarderror.rb +14 -0
  11. data/lib/pindo/client/applovinclient.rb +156 -0
  12. data/lib/pindo/client/aws3sclient.rb +183 -0
  13. data/lib/pindo/client/bossclient.rb +229 -0
  14. data/lib/pindo/client/bossconfigclient.rb +175 -0
  15. data/lib/pindo/client/giteeclient.rb +65 -0
  16. data/lib/pindo/client/httpclient.rb +40 -0
  17. data/lib/pindo/client/pgyerclient.rb +439 -0
  18. data/lib/pindo/client/tgateclient.rb +103 -0
  19. data/lib/pindo/command.rb +101 -0
  20. data/lib/pindo/config/pindoconfig.rb +439 -0
  21. data/lib/pindo/config/pindouserlocalconfig.rb +81 -0
  22. data/lib/pindo/deploy/Fastfile +233 -0
  23. data/lib/pindo/deploy/build.rb +167 -0
  24. data/lib/pindo/deploy/bundleid.rb +245 -0
  25. data/lib/pindo/deploy/cert.rb +508 -0
  26. data/lib/pindo/deploy/check.rb +79 -0
  27. data/lib/pindo/deploy/configproj.rb +89 -0
  28. data/lib/pindo/deploy/confusecode.rb +248 -0
  29. data/lib/pindo/deploy/confuseproj.rb +112 -0
  30. data/lib/pindo/deploy/fabric.rb +58 -0
  31. data/lib/pindo/deploy/getitcinfo.rb +248 -0
  32. data/lib/pindo/deploy/iap.rb +796 -0
  33. data/lib/pindo/deploy/initconfig.rb +128 -0
  34. data/lib/pindo/deploy/itcapp.rb +147 -0
  35. data/lib/pindo/deploy/itcinfo.rb +369 -0
  36. data/lib/pindo/deploy/pem.rb +55 -0
  37. data/lib/pindo/deploy/pullconfig.rb +46 -0
  38. data/lib/pindo/deploy/pushconfig.rb +83 -0
  39. data/lib/pindo/deploy/quswark.rb +146 -0
  40. data/lib/pindo/deploy/quswauth.rb +67 -0
  41. data/lib/pindo/deploy/reportbug.rb +135 -0
  42. data/lib/pindo/deploy/resign.rb +338 -0
  43. data/lib/pindo/deploy/tag.rb +108 -0
  44. data/lib/pindo/deploy/updateconfig.rb +129 -0
  45. data/lib/pindo/deploy/uploadipa.rb +63 -0
  46. data/lib/pindo/deploy.rb +44 -0
  47. data/lib/pindo/dev/autobuild.rb +204 -0
  48. data/lib/pindo/dev/autoresign.rb +186 -0
  49. data/lib/pindo/dev/confusecode.rb +127 -0
  50. data/lib/pindo/dev/confuseproj.rb +111 -0
  51. data/lib/pindo/dev/createbuild.rb +159 -0
  52. data/lib/pindo/dev/debug.rb +141 -0
  53. data/lib/pindo/dev/pub.rb +171 -0
  54. data/lib/pindo/dev/renewcert.rb +142 -0
  55. data/lib/pindo/dev.rb +23 -0
  56. data/lib/pindo/env/dreamstudio.rb +53 -0
  57. data/lib/pindo/env/flutter.rb +59 -0
  58. data/lib/pindo/env/flutter.sh +116 -0
  59. data/lib/pindo/env/quarkenv.rb +58 -0
  60. data/lib/pindo/env/swarkenv.rb +62 -0
  61. data/lib/pindo/env/workhard.rb +56 -0
  62. data/lib/pindo/env.rb +17 -0
  63. data/lib/pindo/ipa/autoresign.rb +188 -0
  64. data/lib/pindo/ipa/import.rb +261 -0
  65. data/lib/pindo/ipa/output.rb +396 -0
  66. data/lib/pindo/ipa.rb +22 -0
  67. data/lib/pindo/lib/forcepush.rb +159 -0
  68. data/lib/pindo/lib/lint.rb +115 -0
  69. data/lib/pindo/lib/push.rb +143 -0
  70. data/lib/pindo/lib/update.rb +75 -0
  71. data/lib/pindo/lib.rb +18 -0
  72. data/lib/pindo/module/appselect.rb +200 -0
  73. data/lib/pindo/module/appstore_in_app_purchase.rb +1803 -0
  74. data/lib/pindo/module/appstore_metadata_connect_api_helper.rb +12 -0
  75. data/lib/pindo/module/appstore_metadata_fastlane_helper.rb +922 -0
  76. data/lib/pindo/module/buildconfighelper.rb +13 -0
  77. data/lib/pindo/module/buildhelper.rb +76 -0
  78. data/lib/pindo/module/commonconfuseproj.rb +271 -0
  79. data/lib/pindo/module/config_project.sh +143 -0
  80. data/lib/pindo/module/configprojhelper.rb +631 -0
  81. data/lib/pindo/module/iap_tier.json +813 -0
  82. data/lib/pindo/module/icon_contents.json +116 -0
  83. data/lib/pindo/module/imessage_icon.json +91 -0
  84. data/lib/pindo/module/imgset_contents.json +21 -0
  85. data/lib/pindo/module/launchimg_contents.json +21 -0
  86. data/lib/pindo/module/pemcreate.rb +63 -0
  87. data/lib/pindo/module/pgyerhelper.rb +339 -0
  88. data/lib/pindo/module/xcodebuildpre.rb +258 -0
  89. data/lib/pindo/module/xcodehelper.rb +521 -0
  90. data/lib/pindo/options/appconfigoptions.rb +23 -0
  91. data/lib/pindo/options/deployoptions.rb +363 -0
  92. data/lib/pindo/pgyer/apptest.rb +104 -0
  93. data/lib/pindo/pgyer/comment.rb +95 -0
  94. data/lib/pindo/pgyer/download.rb +105 -0
  95. data/lib/pindo/pgyer/login.rb +61 -0
  96. data/lib/pindo/pgyer/upload.rb +234 -0
  97. data/lib/pindo/pgyer.rb +17 -0
  98. data/lib/pindo/repo/clone.rb +78 -0
  99. data/lib/pindo/repo/create.rb +55 -0
  100. data/lib/pindo/repo/login.rb +64 -0
  101. data/lib/pindo/repo/search.rb +60 -0
  102. data/lib/pindo/repo.rb +16 -0
  103. data/lib/pindo/setup.rb +60 -0
  104. data/lib/pindo/upgrade.rb +56 -0
  105. data/lib/pindo/utils/applovin.rb +213 -0
  106. data/lib/pindo/utils/boss.rb +209 -0
  107. data/lib/pindo/utils/clearcert.rb +60 -0
  108. data/lib/pindo/utils/device.rb +279 -0
  109. data/lib/pindo/utils/icon.rb +91 -0
  110. data/lib/pindo/utils/icon.sh +133 -0
  111. data/lib/pindo/utils/podindex.rb +56 -0
  112. data/lib/pindo/utils/podindex.sh +30 -0
  113. data/lib/pindo/utils/renewproj.rb +146 -0
  114. data/lib/pindo/utils/tgate.rb +159 -0
  115. data/lib/pindo/utils/xcassets.rb +46 -0
  116. data/lib/pindo/utils/xcassets.sh +88 -0
  117. data/lib/pindo/utils.rb +29 -0
  118. data/lib/pindo/version.rb +110 -0
  119. data/lib/pindo.rb +34 -0
  120. metadata +364 -0
@@ -0,0 +1,1803 @@
1
+
2
+ require 'fileutils'
3
+ require 'faraday'
4
+ require 'spaceship'
5
+
6
+ module Pindo
7
+
8
+ module AppStoreInAppPurchase
9
+
10
+ def get_price_tier_dict
11
+
12
+ iap_tier_file = File.join(File.expand_path('./', __dir__), 'iap_tier.json')
13
+ iap_tier_json = JSON.parse(File.read(iap_tier_file))
14
+
15
+ return iap_tier_json
16
+
17
+ end
18
+
19
+ def get_consumable_iap_items(appstore_client:nil, app_id:nil, in_app_purchase_type:nil)
20
+
21
+ in_app_purchases_response = appstore_client.list_all_in_app_purchases_for_app(id: app_id, include:"appStoreReviewScreenshot,inAppPurchaseLocalizations,content", filter:{
22
+ inAppPurchaseType:in_app_purchase_type
23
+ }, limit:50)
24
+ # puts JSON.pretty_generate(in_app_purchases_response)
25
+
26
+ in_app_purchase_items = []
27
+
28
+ if !in_app_purchases_response.nil? && !in_app_purchases_response[:data].nil?
29
+ in_app_purchases_response[:data].each do |purchase_item|
30
+ iap_item = {}
31
+
32
+ puts "product_id: #{purchase_item[:attributes][:product_id]}"
33
+
34
+ iap_item["reference_name"] = purchase_item[:attributes][:name]
35
+ iap_item["product_id"] = purchase_item[:attributes][:product_id]
36
+ # iap_item["state"] = purchase_item[:attributes][:state]
37
+ iap_item["review_note"] = purchase_item[:attributes][:review_note]
38
+ iap_item["in_app_purchase_type"] = purchase_item[:attributes][:in_app_purchase_type]
39
+ if !purchase_item[:relationships].nil? && !purchase_item[:relationships][:in_app_purchase_localizations].nil? && !purchase_item[:relationships][:in_app_purchase_localizations][:data].nil? && purchase_item[:relationships][:in_app_purchase_localizations][:data].size > 0
40
+ temp_item = purchase_item[:relationships][:in_app_purchase_localizations][:data].first
41
+ iap_item["localizations_id"] = temp_item[:id]
42
+ end
43
+ if !purchase_item[:relationships][:app_store_review_screenshot].nil? && !purchase_item[:relationships][:app_store_review_screenshot][:data].nil? && !purchase_item[:relationships][:app_store_review_screenshot][:data][:id].nil?
44
+ iap_item["review_screenshot_id"] = purchase_item[:relationships][:app_store_review_screenshot][:data][:id]
45
+ end
46
+
47
+ if !iap_item["localizations_id"].nil? && !in_app_purchases_response.nil? && !in_app_purchases_response[:included].nil?
48
+ localizations_item = in_app_purchases_response[:included].find { |item| item[:type].eql?("inAppPurchaseLocalizations") && item[:id].eql?(iap_item["localizations_id"])}
49
+
50
+ iap_item["display_name"] = localizations_item[:attributes][:name]
51
+ iap_item["description"] = localizations_item[:attributes][:description]
52
+ end
53
+
54
+ iap_item["review_screenshot"] = nil
55
+
56
+ iap_item["price"] = nil
57
+ # if !iap_item["review_screenshot_id"].nil? && !in_app_purchases_response.nil? && !in_app_purchases_response[:included].nil?
58
+ # iap_item = in_app_purchases_response[:included].find { |item| item[:type].eql?("inAppPurchaseAppStoreReviewScreenshots") && item[:id].eql?(iap_item["review_screenshot_id"])}
59
+ # end
60
+
61
+ iap_item["price"] = get_purchase_item_price(appstore_client:appstore_client, in_app_purchase_id:purchase_item[:id])
62
+
63
+ iap_item.delete("localizations_id")
64
+ iap_item.delete("review_screenshot_id")
65
+ in_app_purchase_items << iap_item
66
+ end
67
+ end
68
+
69
+ in_app_purchase_items.sort! { | itema, itemb | itema["product_id"] <=> itemb["product_id"]}
70
+
71
+ return in_app_purchase_items
72
+ end
73
+
74
+ def get_app_share_secrets(app_id:nil, need_create:true)
75
+
76
+ puts "获取App Shared Secret ..."
77
+ scecrets_id = nil
78
+ begin
79
+ client = Spaceship::ConnectAPI
80
+ app_sharedsecrets_item = nil
81
+ response = client.tunes_request_client.get("apps/#{app_id}/appSharedSecrets")
82
+ # puts JSON.pretty_generate(response.body)
83
+ result_data = response.body
84
+
85
+ if !result_data.nil? && !result_data["data"].nil? && result_data["data"].size > 0
86
+ app_sharedsecrets_item = result_data["data"].first
87
+ # puts JSON.pretty_generate(app_sharedsecrets_item)
88
+ else
89
+ puts "从app store 未获取到App Shared Secret."
90
+ end
91
+
92
+ if app_sharedsecrets_item.nil? && need_create
93
+ answer = agree("请确认是否要创建App Shared Secret? (Y/n):")
94
+ # answer = false
95
+ if answer
96
+ body = {
97
+ data: {
98
+ type: "appSharedSecrets",
99
+ relationships: {
100
+ app:{
101
+ data:{
102
+ type:"apps",
103
+ id:app_id
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+ response = client.tunes_request_client.post("appSharedSecrets", body)
110
+ post_result_data = response.body
111
+ if !post_result_data.nil? && !post_result_data["data"].nil? && !post_result_data["data"]["attributes"].nil?
112
+ app_sharedsecrets_item = post_result_data["data"]
113
+ # puts JSON.pretty_generate(app_sharedsecrets_item)
114
+ end
115
+ end
116
+ end
117
+
118
+ if !app_sharedsecrets_item.nil?
119
+ # puts JSON.pretty_generate(app_sharedsecrets_item)
120
+ scecrets_id = app_sharedsecrets_item["attributes"]["secret"]
121
+ end
122
+
123
+ rescue => err
124
+ puts err
125
+ puts "获取App Shared Secret失败!"
126
+ end
127
+ return scecrets_id
128
+ end
129
+
130
+ def create_consumable_iap_items(appstore_client:nil, app_id:nil, in_app_purchase_items:nil)
131
+
132
+ in_app_purchase_items = in_app_purchase_items || []
133
+ in_app_purchase_items.sort! { | itema, itemb | itema["product_id"] <=> itemb["product_id"]}
134
+
135
+ in_app_purchases_response = appstore_client.list_all_in_app_purchases_for_app(id: app_id, limit:50)
136
+ # puts JSON.pretty_generate(in_app_purchases_response)
137
+
138
+ if !in_app_purchases_response.nil? && !in_app_purchases_response[:data].nil?
139
+ in_app_purchase_items.each do |purchase_item|
140
+
141
+ in_app_purchases_response[:data].each do |iap_item|
142
+
143
+ if iap_item[:attributes][:product_id].to_s.eql?(purchase_item["product_id"])
144
+ purchase_item["purchase_id"] = iap_item[:id]
145
+ purchase_item["state"] = iap_item[:attributes][:state]
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+
152
+ in_app_purchase_items.each do |purchase_item|
153
+
154
+ puts "购买项:" + purchase_item["product_id"]
155
+ if purchase_item["purchase_id"].nil?
156
+ create_purchase_item(appstore_client:appstore_client, app_id:app_id, purchase_item:purchase_item)
157
+ end
158
+
159
+ if !purchase_item["purchase_id"].nil?
160
+ in_app_purchase_id = purchase_item["purchase_id"]
161
+
162
+ if !purchase_item["state"].nil? && purchase_item["state"].to_s.eql?("APPROVED")
163
+ puts " 购买项已经上线, 只能修改价格"
164
+ create_purchase_item_price(appstore_client:appstore_client, in_app_purchase_id:in_app_purchase_id, purchase_item:purchase_item)
165
+ else
166
+ sleep(1)
167
+ update_purchase_item_name(appstore_client:appstore_client, in_app_purchase_id:in_app_purchase_id, purchase_item:purchase_item)
168
+ create_purchase_item_price(appstore_client:appstore_client, in_app_purchase_id:in_app_purchase_id, purchase_item:purchase_item)
169
+ upload_purchase_item_screenshots(appstore_client:appstore_client, in_app_purchase_id:in_app_purchase_id, purchase_item:purchase_item)
170
+ create_purchase_item_localization(appstore_client:appstore_client, in_app_purchase_id:in_app_purchase_id, purchase_item:purchase_item)
171
+ update_purchase_item_name(appstore_client:appstore_client, in_app_purchase_id:in_app_purchase_id, purchase_item:purchase_item)
172
+
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ def create_purchase_item(appstore_client:nil, app_id:nil, purchase_item:nil)
179
+ #创建购买项
180
+ puts " 创建iap: " + purchase_item["product_id"]
181
+
182
+ appstore_app_id = app_id.to_s
183
+ purchase_id = nil
184
+
185
+ begin
186
+ response = appstore_client.create_in_app_purchase(
187
+ name:purchase_item["reference_name"],
188
+ product_id:purchase_item["product_id"],
189
+ in_app_purchase_type:purchase_item["in_app_purchase_type"],
190
+ available_in_all_territories:true,
191
+ review_note:purchase_item["review_note"],
192
+ relationships: {
193
+ app:{
194
+ data:{
195
+ id: appstore_app_id,
196
+ type: 'apps'
197
+ }
198
+ }
199
+ }
200
+ )
201
+
202
+ if !response.nil? && !response[:data].nil? && !response[:data][:id].nil?
203
+
204
+ purchase_id = !response[:data][:id]
205
+ purchase_item["purchase_id"] = response[:data][:id]
206
+ return purchase_id
207
+ else !response.nil? && !response[:errors].nil?
208
+ # puts JSON.pretty_generate(response)
209
+ response[:errors].each do |error_item|
210
+ if error_item[:status].to_s.eql?("409") && error_item[:code].to_s.eql?("ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE") && error_item[:source][:pointer].to_s.eql?("/data/attributes/name")
211
+ err_msg = " !!!!!" + purchase_item["product_id"] + " 购买项创建失败!!!, Reference Name重复!!!"
212
+ raise Informative, err_msg
213
+ end
214
+ end
215
+ err_msg = purchase_item["product_id"] + " 购买项创建失败!!!"
216
+ # puts JSON.pretty_generate(response)
217
+ end
218
+ rescue => err
219
+ puts err
220
+ err_msg = purchase_item["product_id"] + " 购买项创建失败!!!"
221
+ raise Informative, err_msg
222
+ end
223
+ end
224
+
225
+ def update_purchase_item_name(appstore_client:nil, in_app_purchase_id:nil, purchase_item:nil)
226
+
227
+ puts " 更新Reference Name"
228
+ begin
229
+ response = appstore_client.update_in_app_purchase(
230
+ name:purchase_item["reference_name"],
231
+ available_in_all_territories:true,
232
+ review_note:purchase_item["review_note"],
233
+ id:in_app_purchase_id
234
+ )
235
+ rescue => err
236
+ puts err
237
+ puts " 更新Reference Name失败!!!"
238
+ end
239
+ end
240
+
241
+
242
+ def create_purchase_item_localization(appstore_client:nil, in_app_purchase_id:nil, purchase_item:nil)
243
+
244
+ puts " 更新Display Name"
245
+ begin
246
+
247
+ response = appstore_client.list_in_app_purchase_all_localizations(
248
+ id:in_app_purchase_id,
249
+ limit:200
250
+ )
251
+ # puts JSON.pretty_generate(response)
252
+ if !response[:data].nil?
253
+
254
+ response[:data].each do |localization_item|
255
+ locale = localization_item[:attributes][:locale]
256
+ locale_id = localization_item[:id]
257
+ display_name = localization_item[:name]
258
+ description = localization_item[:description]
259
+ purchase_item["localization"][locale] = purchase_item["localization"][locale] || {}
260
+ purchase_item["localization"][locale]["locale"] = locale
261
+ purchase_item["localization"][locale]["locale_id"] = locale_id
262
+ purchase_item["localization"][locale]["display_name"] = purchase_item["localization"][locale]["display_name"] || display_name
263
+ purchase_item["localization"][locale]["description"] = purchase_item["localization"][locale]["description"] || description
264
+ end
265
+
266
+ end
267
+
268
+
269
+
270
+ purchase_item["localization"].each do |locale, locale_item|
271
+
272
+ if !locale_item.nil? && !locale_item["locale_id"].nil?
273
+
274
+ response = appstore_client.update_in_app_purchase_localization(
275
+ id:locale_item["locale_id"],
276
+ name:locale_item["display_name"],
277
+ description:locale_item["description"]
278
+ )
279
+ # puts JSON.pretty_generate(response)
280
+
281
+ else
282
+
283
+ response = appstore_client.create_in_app_purchase_localization(
284
+ name:locale_item["display_name"],
285
+ description:locale_item["description"],
286
+ locale:locale,
287
+ relationships: {
288
+ inAppPurchaseV2:{
289
+ data:{
290
+ id: in_app_purchase_id,
291
+ type: 'inAppPurchases'
292
+ }
293
+ }
294
+ }
295
+ )
296
+
297
+ # puts JSON.pretty_generate(response)
298
+
299
+ end
300
+
301
+ end
302
+
303
+
304
+ rescue => err
305
+ puts err
306
+ puts " 更新Display Name失败!!!"
307
+ end
308
+ end
309
+
310
+ def get_purchase_item_price(appstore_client:nil, in_app_purchase_id:nil)
311
+
312
+ price = 0
313
+ respose_price = appstore_client.read_in_app_purchase_price_info(
314
+ id:in_app_purchase_id,
315
+ include:'inAppPurchasePricePoint',
316
+ filter:{
317
+ territory:'USA'
318
+ }
319
+
320
+ )
321
+ # puts JSON.pretty_generate(respose_price)
322
+
323
+ price_id = nil
324
+ if !respose_price[:data].nil? && respose_price[:data].size > 0
325
+ price_item = respose_price[:data].first
326
+ price_id = price_item[:relationships][:in_app_purchase_price_point][:data][:id]
327
+ end
328
+ if !price_id.nil?
329
+ item = respose_price[:included].find { |e| e[:id].eql?(price_id) }
330
+ if !item.nil?
331
+ price = item[:attributes][:customer_price]
332
+ end
333
+ end
334
+
335
+ return price
336
+ end
337
+
338
+ def create_purchase_item_price(appstore_client:nil, in_app_purchase_id:nil, purchase_item:nil)
339
+ puts " 更新价格"
340
+ begin
341
+ respose_price = appstore_client.list_in_app_purchase_all_price_points(
342
+ id:in_app_purchase_id,
343
+ include: 'territory',
344
+ filter: {
345
+ territory: 'USA',
346
+ price_tier: purchase_item["price_tier"]
347
+ },
348
+ limit:100
349
+ )
350
+ # puts JSON.pretty_generate(respose_price)
351
+
352
+
353
+ price_id = nil
354
+
355
+
356
+ respose_price[:data].each do |price_item|
357
+ if price_item[:attributes][:customer_price].to_s.eql?(purchase_item["price"].to_s)
358
+ price_id = price_item[:id]
359
+ purchase_item["price_id"] = price_item[:id]
360
+ puts " 更新价格 :" + purchase_item["price"] +"$"
361
+ end
362
+ end
363
+ if !price_id.nil?
364
+ in_app_purchase = appstore_client.create_in_app_purchase_price_schedule(
365
+ relationships: {
366
+ manual_prices: {
367
+ data: [
368
+ {
369
+ type: 'inAppPurchasePrices',
370
+ id: '${price1}'
371
+ }
372
+ ]
373
+ },
374
+ in_app_purchase: {
375
+ data: {
376
+ type: 'inAppPurchases',
377
+ id: in_app_purchase_id
378
+ }
379
+ }
380
+ },
381
+ included: [
382
+ {
383
+ type: 'inAppPurchasePrices',
384
+ id: '${price1}',
385
+ attributes: {
386
+ startDate: nil
387
+ },
388
+ relationships: {
389
+ inAppPurchaseV2: {
390
+ data: {
391
+ type: 'inAppPurchases',
392
+ id: in_app_purchase_id
393
+ }
394
+ },
395
+ inAppPurchasePricePoint: {
396
+ data: {
397
+ type: 'inAppPurchasePricePoints',
398
+ id: price_id
399
+ }
400
+ }
401
+ }
402
+ }
403
+ ]
404
+ )
405
+ end
406
+
407
+ rescue => err
408
+ puts "创建价格失败: " + purchase_item["product_id"]
409
+ puts err
410
+ end
411
+ end
412
+
413
+ def upload_purchase_item_screenshots(appstore_client:nil, in_app_purchase_id:nil, purchase_item:nil)
414
+ puts " 更新截屏"
415
+ begin
416
+ # upload screenshots
417
+ response_iap_screenshot = appstore_client.read_review_screenshot_for_in_app_purchase(id:in_app_purchase_id)
418
+
419
+ path = purchase_item["review_screenshot_fullpath"]
420
+ filename = File.basename(path)
421
+ filesize = File.size(path)
422
+ bytes = File.binread(path)
423
+
424
+ checksum = Digest::MD5.hexdigest(bytes)
425
+
426
+
427
+ need_upload_screenshot = true
428
+
429
+ if !response_iap_screenshot[:data].nil? && !response_iap_screenshot[:data][:attributes].nil? && !response_iap_screenshot[:data][:attributes][:asset_delivery_state].nil? && !response_iap_screenshot[:data][:attributes][:asset_delivery_state][:state].nil?
430
+
431
+ if response_iap_screenshot[:data][:attributes][:asset_delivery_state][:state].to_s.eql?("COMPLETE")
432
+
433
+ if !response_iap_screenshot[:data].nil? && !response_iap_screenshot[:data][:attributes].nil? && !response_iap_screenshot[:data][:attributes][:source_file_checksum].nil?
434
+
435
+ if checksum.to_s.eql?(response_iap_screenshot[:data][:attributes][:source_file_checksum].to_s)
436
+
437
+ puts " 有截屏,截屏未修改,无需重新上传"
438
+ need_upload_screenshot = false
439
+
440
+ end
441
+ end
442
+ end
443
+ end
444
+
445
+
446
+ # puts JSON.pretty_generate(response_iap_screenshot)
447
+ if need_upload_screenshot && !response_iap_screenshot[:data].nil? && !response_iap_screenshot[:data][:attributes].nil? && !response_iap_screenshot[:data][:attributes][:file_name].nil?
448
+ puts " 有截屏,先删除再更新"
449
+ # puts JSON.pretty_generate(response_iap_screenshot)
450
+ appstore_client.delete_in_app_purchase_review_screenshot(id:response_iap_screenshot[:data][:id])
451
+ end
452
+
453
+
454
+ if need_upload_screenshot
455
+
456
+ puts " 正在上传...."
457
+ response_iap_screenshot = appstore_client.create_in_app_purchase_review_screenshot(
458
+ file_name:filename,
459
+ file_size: filesize,
460
+ relationships: {
461
+ inAppPurchaseV2:{
462
+ data:{
463
+ id: in_app_purchase_id,
464
+ type: 'inAppPurchases'
465
+ }
466
+ }
467
+ }
468
+ )
469
+
470
+ # puts JSON.pretty_generate(response_iap_screenshot)
471
+ upload_id = response_iap_screenshot[:data][:id]
472
+ upload_operations = response_iap_screenshot[:data][:attributes][:upload_operations]
473
+ upload_operations.each_with_index do |upload_operation, index|
474
+ headers = {}
475
+ upload_operation[:request_headers].each do |item|
476
+ headers[item[:name]] = item[:value]
477
+ end
478
+ offset = upload_operation[:offset]
479
+ length = upload_operation[:length]
480
+ conn = Faraday.new
481
+ res = conn.put(upload_operation[:url], bytes[offset, length], headers)
482
+ end
483
+
484
+
485
+
486
+ in_app_purchase = appstore_client.update_in_app_purchase_app_store_review_screenshot(
487
+ id:upload_id,
488
+ uploaded: true,
489
+ source_file_checksum:checksum
490
+ )
491
+ puts " 上传完成!!"
492
+
493
+
494
+ else
495
+ puts " 存在图片,无需上传...."
496
+ end
497
+
498
+
499
+
500
+ rescue => err
501
+ puts err
502
+ puts " 更新截屏失败!!!"
503
+ end
504
+ end
505
+
506
+ def get_subscriptions_groups(appstore_client:nil, app_id:nil)
507
+
508
+ subscription_group_items = []
509
+
510
+ #查询是否存在group
511
+ subscription_groups_response = appstore_client.list_all_subscription_groups_for_app(id: app_id, include:'subscriptionGroupLocalizations', limit:50)
512
+ # puts JSON.pretty_generate(subscription_groups_response)
513
+ #如果存在group,则更新,不存在则创建
514
+ if !subscription_groups_response.nil? && !subscription_groups_response[:data].nil?
515
+
516
+
517
+ subscription_groups_response[:data].each do |old_subscription_group_item|
518
+ subscription_group_item = { }
519
+
520
+ subscription_group_item["group_reference_name"] = old_subscription_group_item[:attributes][:reference_name]
521
+ if !old_subscription_group_item[:relationships][:subscription_group_localizations][:data].nil? && old_subscription_group_item[:relationships][:subscription_group_localizations][:data].size > 0
522
+ group_localization_item = old_subscription_group_item[:relationships][:subscription_group_localizations][:data].first
523
+ subscription_group_item["group_localizations_id"] = group_localization_item[:id]
524
+ end
525
+
526
+ if !subscription_group_item["group_localizations_id"].nil? && !subscription_groups_response[:included].nil?
527
+ group_localization_item = subscription_groups_response[:included].find { |item| item[:type].eql?("subscriptionGroupLocalizations") && item[:id].eql?(subscription_group_item["group_localizations_id"])}
528
+ if !group_localization_item.nil?
529
+ subscription_group_item["group_display_name"] = group_localization_item[:attributes][:name]
530
+ subscription_group_item["custom_app_name"] = group_localization_item[:attributes][:custom_app_name]
531
+ end
532
+ end
533
+
534
+ subscription_group_item["subscription_items"] = get_subscription_items(appstore_client:appstore_client, subscription_group_id:old_subscription_group_item[:id])
535
+ subscription_group_item.delete("group_localizations_id")
536
+ subscription_group_items << subscription_group_item
537
+ end
538
+ end
539
+
540
+
541
+ return subscription_group_items
542
+
543
+ end
544
+
545
+
546
+
547
+ def create_subscriptions_groups(appstore_client:nil, app_id:nil, subscription_group_items:nil)
548
+
549
+ subscription_group_items = subscription_group_items || []
550
+
551
+ #查询是否存在group
552
+ subscription_groups_response = appstore_client.list_all_subscription_groups_for_app(id: app_id, limit:50)
553
+ # puts JSON.pretty_generate(subscription_groups_response)
554
+ #如果存在group,则更新,不存在则创建
555
+ if !subscription_groups_response.nil? && !subscription_groups_response[:data].nil?
556
+
557
+ puts
558
+ puts "**已存在订阅组的数目** : #{subscription_groups_response[:data].size}"
559
+ puts
560
+
561
+ subscription_groups_response[:data].each do |old_subscription_group_item|
562
+ subscription_group_items.each do |new_subscription_group_item|
563
+ if !old_subscription_group_item[:attributes].nil? && old_subscription_group_item[:attributes][:reference_name].to_s.eql?(new_subscription_group_item["group_reference_name"])
564
+ new_subscription_group_item["group_id"] = old_subscription_group_item[:id]
565
+ end
566
+ end
567
+ end
568
+ end
569
+
570
+ subscription_group_items.each do |new_subscription_group_item|
571
+
572
+ if new_subscription_group_item["group_id"].nil?
573
+ if subscription_groups_response[:data].size > 0
574
+ puts
575
+ answer = agree("请确认要创建新的Subscription Group(Y/n):")
576
+ unless answer
577
+ raise Informative, "修改iap.json文件 !!! group_reference_name不一致会创建新的Subscription Group !!!"
578
+ end
579
+ end
580
+ create_subscription_group_item(appstore_client:appstore_client, app_id:app_id, subscription_group_item:new_subscription_group_item)
581
+ end
582
+
583
+ if !new_subscription_group_item["group_id"].nil?
584
+
585
+ subscription_group_id = new_subscription_group_item["group_id"]
586
+
587
+ create_subscription_group_localization(appstore_client:appstore_client, subscription_group_id:new_subscription_group_item["group_id"], subscription_group_item:new_subscription_group_item)
588
+ sleep(1)
589
+ subscription_items = new_subscription_group_item["subscription_items"]
590
+ create_subscription_items(appstore_client:appstore_client, subscription_group_id:subscription_group_id, subscription_items:subscription_items)
591
+
592
+ end
593
+ end
594
+
595
+
596
+ end
597
+
598
+ def create_subscription_group_item(appstore_client:nil, app_id:nil, subscription_group_item:nil)
599
+
600
+ begin
601
+ group_response = appstore_client.create_subscription_group(
602
+ reference_name:subscription_group_item["group_reference_name"],
603
+ relationships: {
604
+ app:{
605
+ data:{
606
+ id: app_id,
607
+ type: 'apps'
608
+ }
609
+ }
610
+ })
611
+ # puts JSON.pretty_generate(group_response)
612
+ rescue => err
613
+ puts err
614
+ end
615
+
616
+ end
617
+
618
+ def create_subscription_group_localization(appstore_client:nil, subscription_group_id:nil, subscription_group_item:nil)
619
+ begin
620
+
621
+
622
+ response = appstore_client.list_all_subscription_group_localizations(
623
+ id:subscription_group_id,
624
+ limit:200
625
+ )
626
+ # puts JSON.pretty_generate(response)
627
+
628
+ if !response[:data].nil?
629
+
630
+ response[:data].each do |localization_item|
631
+ locale = localization_item[:attributes][:locale]
632
+ locale_id = localization_item[:id]
633
+ group_display_name = localization_item[:name]
634
+ custom_app_name = localization_item[:custom_app_name]
635
+ subscription_group_item["localization"][locale] = subscription_group_item["localization"][locale] || {}
636
+ subscription_group_item["localization"][locale]["locale"] = locale
637
+ subscription_group_item["localization"][locale]["locale_id"] = locale_id
638
+ subscription_group_item["localization"][locale]["group_display_name"] = subscription_group_item["localization"][locale]["group_display_name"] || group_display_name
639
+ subscription_group_item["localization"][locale]["custom_app_name"] = subscription_group_item["localization"][locale]["custom_app_name"] || custom_app_name
640
+ end
641
+
642
+ end
643
+
644
+
645
+
646
+ subscription_group_item["localization"].each do |locale, locale_item|
647
+
648
+
649
+ if !locale_item.nil? && !locale_item["locale_id"].nil?
650
+
651
+ response = appstore_client.update_subscription_group_localization(
652
+ id:locale_item["locale_id"],
653
+ name:locale_item["group_display_name"],
654
+ custom_app_name:locale_item["custom_app_name"]
655
+ )
656
+ # puts JSON.pretty_generate(response)
657
+
658
+ else
659
+
660
+ response = appstore_client.create_subscription_group_localization(
661
+ name:locale_item["group_display_name"],
662
+ locale:locale,
663
+ custom_app_name:locale_item["custom_app_name"],
664
+ relationships: {
665
+ subscriptionGroup:{
666
+ data:{
667
+ id: subscription_group_id,
668
+ type: 'subscriptionGroups'
669
+ }
670
+ }
671
+ }
672
+ )
673
+ # puts JSON.pretty_generate(response)
674
+
675
+ end
676
+
677
+
678
+
679
+ end
680
+
681
+
682
+
683
+ rescue => err
684
+ puts err
685
+ puts " 更新Group Display Name 失败!!"
686
+ end
687
+
688
+ end
689
+
690
+
691
+ def get_subscription_items(appstore_client:nil, subscription_group_id:nil)
692
+ subscription_items = []
693
+
694
+ tier_json = get_price_tier_dict
695
+ items_dict = tier_json["subscription_duration"]
696
+ subscription_period_dict = items_dict.invert
697
+
698
+ subscription_response = appstore_client.list_all_subscription_for_subscription_group(id: subscription_group_id, include:'subscriptionLocalizations,introductoryOffers', limit:50)
699
+ # puts JSON.pretty_generate(subscription_response)
700
+ if !subscription_response.nil? && !subscription_response[:data].nil?
701
+ subscription_response[:data].each do |old_subscription_item|
702
+
703
+ puts "product_id: #{old_subscription_item[:attributes][:product_id]}"
704
+
705
+ new_subscription_item = {}
706
+
707
+ new_subscription_item["reference_name"] = old_subscription_item[:attributes][:name]
708
+ new_subscription_item["product_id"] = old_subscription_item[:attributes][:product_id]
709
+ new_subscription_item["subscription_duration"] = subscription_period_dict[old_subscription_item[:attributes][:subscription_period]]
710
+ # new_subscription_item["state"] = old_subscription_item[:attributes][:state]
711
+ new_subscription_item["reference_name"] = old_subscription_item[:attributes][:name]
712
+ new_subscription_item["review_note"] = old_subscription_item[:attributes][:review_note]
713
+
714
+ new_subscription_item["display_name"] = nil
715
+ new_subscription_item["description"] = nil
716
+ new_subscription_item["price"] = nil
717
+ new_subscription_item["review_screenshot"] = nil
718
+ new_subscription_item["subscription_free_trial"] = nil
719
+
720
+
721
+
722
+ if !old_subscription_item[:relationships].nil? && !old_subscription_item[:relationships][:subscription_localizations].nil? && !old_subscription_item[:relationships][:subscription_localizations][:data].nil? && old_subscription_item[:relationships][:subscription_localizations][:data].size > 0
723
+ subscription_localization_item = old_subscription_item[:relationships][:subscription_localizations][:data].first
724
+ new_subscription_item["localizations_id"] = subscription_localization_item[:id]
725
+ end
726
+
727
+ if !new_subscription_item["localizations_id"].nil? && !subscription_response[:included].nil?
728
+ localizations_item = subscription_response[:included].find { |item| item[:type].eql?("subscriptionLocalizations") && item[:id].eql?(new_subscription_item["localizations_id"])}
729
+
730
+ new_subscription_item["display_name"] = localizations_item[:attributes][:name]
731
+ new_subscription_item["description"] = localizations_item[:attributes][:description]
732
+ end
733
+
734
+
735
+ if !old_subscription_item[:relationships].nil? && !old_subscription_item[:relationships][:introductory_offers].nil? && !old_subscription_item[:relationships][:introductory_offers][:data].nil? && old_subscription_item[:relationships][:introductory_offers][:data].size > 0
736
+ new_subscription_item["subscription_free_trial"] = "3d"
737
+ else
738
+ new_subscription_item.delete("subscription_free_trial")
739
+ end
740
+
741
+ new_subscription_item["price"] = get_subscription_item_price(appstore_client:appstore_client, subscription_id:old_subscription_item[:id])
742
+ new_subscription_item.delete("localizations_id")
743
+
744
+
745
+ subscription_items << new_subscription_item
746
+
747
+ end
748
+ end
749
+
750
+ subscription_items.sort! { | itema, itemb | itema["product_id"] <=> itemb["product_id"]}
751
+ return subscription_items
752
+
753
+ end
754
+
755
+ def create_subscription_items(appstore_client:nil, subscription_group_id:nil, subscription_items:nil)
756
+
757
+
758
+ subscription_items = subscription_items || []
759
+ subscription_items.sort! { | itema, itemb | itema["product_id"] <=> itemb["product_id"]}
760
+
761
+ #查询是否存在group
762
+ subscription_response = appstore_client.list_all_subscription_for_subscription_group(id: subscription_group_id, limit:50)
763
+ # puts JSON.pretty_generate(subscription_response)
764
+ #subscription,则更新,不存在则创建
765
+ if !subscription_response.nil? && !subscription_response[:data].nil?
766
+ subscription_response[:data].each do |old_subscription_item|
767
+ subscription_items.each do |new_subscription_item|
768
+ if !old_subscription_item[:attributes].nil? && old_subscription_item[:attributes][:product_id].to_s.eql?(new_subscription_item["product_id"])
769
+ new_subscription_item["subscription_id"] = old_subscription_item[:id]
770
+ new_subscription_item["state"] = old_subscription_item[:attributes][:state]
771
+ end
772
+ end
773
+ end
774
+ end
775
+
776
+ subscription_items.each do |new_subscription_item|
777
+ puts " 订阅项:" + new_subscription_item["product_id"]
778
+ if new_subscription_item["subscription_id"].nil?
779
+ create_subscription_item(appstore_client:appstore_client, subscription_group_id:subscription_group_id, subscription_item:new_subscription_item)
780
+ end
781
+
782
+ if !new_subscription_item["subscription_id"].nil?
783
+ subscription_id = new_subscription_item["subscription_id"]
784
+ puts " 订阅项id: #{subscription_id}"
785
+
786
+ sleep(1)
787
+ if !new_subscription_item["state"].nil? && new_subscription_item["state"].to_s.eql?("APPROVED")
788
+ puts " 订阅项已经上线, 只能修改价格"
789
+ create_subscription_item_price(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
790
+ update_subscription_item_introductory_offer(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
791
+ else
792
+
793
+ update_subscription_item_attributes(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
794
+ create_subscription_item_localization(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
795
+ update_subscription_item_screenshots(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
796
+
797
+ create_subscription_item_price(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
798
+ delete_subscription_item_introductory_offer(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
799
+ update_subscription_item_period(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
800
+ update_subscription_item_introductory_offer(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
801
+ end
802
+
803
+
804
+
805
+ end
806
+ end
807
+
808
+
809
+ # subscription_items.each do |new_subscription_item|
810
+ # puts " 订阅项:" + new_subscription_item["product_id"]
811
+
812
+ # if !new_subscription_item["subscription_id"].nil?
813
+ # subscription_id = new_subscription_item["subscription_id"]
814
+
815
+ # create_subscription_item_price_with_singlefunc(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
816
+ # if new_subscription_item["subscription_free_trial"].nil?
817
+ # delete_subscription_item_introductory_offer_with_singlefunc(appstore_client:appstore_client, subscription_id:subscription_id)
818
+ # end
819
+
820
+ # end
821
+ # end
822
+
823
+ #再更新一次Display Name , 状态变成yRead to Submit
824
+ subscription_items.each do |new_subscription_item|
825
+
826
+ if !new_subscription_item["subscription_id"].nil?
827
+
828
+ if !new_subscription_item["state"].nil? && new_subscription_item["state"].to_s.eql?("APPROVED")
829
+
830
+ else
831
+ subscription_id = new_subscription_item["subscription_id"]
832
+ create_subscription_item_localization(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:new_subscription_item)
833
+ end
834
+
835
+ end
836
+ end
837
+
838
+
839
+
840
+
841
+ end
842
+
843
+
844
+
845
+ def create_subscription_item(appstore_client:nil, subscription_group_id:nil, subscription_item:nil)
846
+ #创建购买项
847
+ begin
848
+ response = appstore_client.create_subscription(
849
+ name:subscription_item["reference_name"],
850
+ product_id:subscription_item["product_id"],
851
+ available_in_all_territories:true,
852
+ family_sharable:false,
853
+ review_note:subscription_item["review_note"],
854
+ subscription_period:subscription_item["subscription_duration"],
855
+ group_level:1,
856
+ relationships: {
857
+ group:{
858
+ data:{
859
+ id: subscription_group_id,
860
+ type: 'subscriptionGroups'
861
+ }
862
+ }
863
+ }
864
+ )
865
+
866
+ # puts JSON.pretty_generate(response)
867
+
868
+ if !response.nil? && !response[:data].nil? && !response[:data][:id].nil?
869
+
870
+ purchase_id = !response[:data][:id]
871
+ subscription_item["subscription_id"] = response[:data][:id]
872
+ return purchase_id
873
+ else !response.nil? && !response[:errors].nil?
874
+ # puts JSON.pretty_generate(response)
875
+ response[:errors].each do |error_item|
876
+ if error_item[:status].to_s.eql?("409") && error_item[:code].to_s.eql?("ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE") && error_item[:source][:pointer].to_s.eql?("/data/attributes/name")
877
+ err_msg = " !!!!!" + subscription_item["product_id"] + " 购买项创建失败!!! Reference Name重复!!!"
878
+ raise Informative, err_msg
879
+ end
880
+ end
881
+ err_msg = subscription_item["product_id"] + " 购买项创建失败!!!"
882
+ # puts JSON.pretty_generate(response)
883
+ end
884
+ rescue => err
885
+ puts err
886
+ err_msg = subscription_item["product_id"] + " 购买项创建失败!!!"
887
+ raise Informative, err_msg
888
+ end
889
+ end
890
+
891
+ def update_subscription_item_attributes(appstore_client:nil, subscription_id:nil, subscription_item:nil)
892
+ puts " 更新Reference Name"
893
+
894
+ begin
895
+ response = appstore_client.update_subscription(
896
+ id:subscription_id,
897
+ name:subscription_item["reference_name"],
898
+ available_in_all_territories:true,
899
+ family_sharable:false,
900
+ review_note:subscription_item["review_note"],
901
+ group_level:1
902
+ )
903
+ # puts JSON.pretty_generate(response)
904
+
905
+ if !response.nil? && !response[:data].nil? && !response[:data][:id].nil?
906
+
907
+ purchase_id = !response[:data][:id]
908
+ subscription_item["subscription_id"] = response[:data][:id]
909
+ return purchase_id
910
+ else !response.nil? && !response[:errors].nil?
911
+ # puts JSON.pretty_generate(response)
912
+ response[:errors].each do |error_item|
913
+ if error_item[:status].to_s.eql?("409") && error_item[:code].to_s.eql?("ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE") && error_item[:source][:pointer].to_s.eql?("/data/attributes/name")
914
+ err_msg = " !!!!!" + subscription_item["product_id"] + " 购买项更新失败!!! Reference Name重复!!!"
915
+ raise Informative, err_msg
916
+ end
917
+ end
918
+ err_msg = subscription_item["product_id"] + " 购买项更新失败!!!"
919
+ # puts JSON.pretty_generate(response)
920
+ end
921
+
922
+ rescue => err
923
+ puts err
924
+ end
925
+ end
926
+
927
+ def update_subscription_item_period(appstore_client:nil, subscription_id:nil, subscription_item:nil)
928
+
929
+ begin
930
+ puts " 设置订阅的周期: #{subscription_item["subscription_duration"]}"
931
+ response = appstore_client.update_subscription(
932
+ id:subscription_id,
933
+ subscription_period:subscription_item["subscription_duration"]
934
+ )
935
+ # puts JSON.pretty_generate(response)
936
+
937
+ if !response.nil? && !response[:data].nil? && !response[:data][:id].nil?
938
+
939
+ purchase_id = !response[:data][:id]
940
+ subscription_item["subscription_id"] = response[:data][:id]
941
+ return purchase_id
942
+ else !response.nil? && !response[:errors].nil?
943
+ puts " !!!! 设置订阅的周期失败 !!!!"
944
+ end
945
+
946
+ rescue => err
947
+ puts err
948
+ puts " !!!! 设置订阅的周期失败 !!!!"
949
+ end
950
+ end
951
+
952
+ def create_subscription_item_localization(appstore_client:nil, subscription_id:nil, subscription_item:nil)
953
+ puts " 更新Display Name"
954
+ begin
955
+ # 更新购买项描述多语言
956
+ response = appstore_client.list_subscription_all_localizations(
957
+ id:subscription_id,
958
+ limit:200
959
+ )
960
+ if !response[:data].nil?
961
+
962
+ response[:data].each do |localization_item|
963
+ locale = localization_item[:attributes][:locale]
964
+ locale_id = localization_item[:id]
965
+ display_name = localization_item[:name]
966
+ description = localization_item[:description]
967
+ subscription_item["localization"][locale] = subscription_item["localization"][locale] || {}
968
+ subscription_item["localization"][locale]["locale"] = locale
969
+ subscription_item["localization"][locale]["locale_id"] = locale_id
970
+ subscription_item["localization"][locale]["display_name"] = subscription_item["localization"][locale]["display_name"] || display_name
971
+ subscription_item["localization"][locale]["description"] = subscription_item["localization"][locale]["description"] || description
972
+ end
973
+
974
+ end
975
+
976
+ # puts JSON.pretty_generate(response)
977
+
978
+ subscription_item["localization"].each do |locale, locale_item|
979
+
980
+
981
+ if !locale_item.nil? && !locale_item["locale_id"].nil?
982
+
983
+ response = appstore_client.update_subscription_localizations(
984
+ id:locale_item["locale_id"],
985
+ name:locale_item["display_name"],
986
+ description:locale_item["description"]
987
+ )
988
+ # puts JSON.pretty_generate(response)
989
+
990
+ else
991
+
992
+ response = appstore_client.create_subscription_localizations(
993
+ name:locale_item["display_name"],
994
+ description:locale_item["description"],
995
+ locale:locale,
996
+ relationships: {
997
+ subscription:{
998
+ data:{
999
+ id: subscription_id,
1000
+ type: 'subscriptions'
1001
+ }
1002
+ }
1003
+ }
1004
+ )
1005
+
1006
+ # puts JSON.pretty_generate(response)
1007
+
1008
+ end
1009
+
1010
+
1011
+
1012
+ end
1013
+
1014
+
1015
+
1016
+ rescue => err
1017
+ puts err
1018
+ end
1019
+ end
1020
+
1021
+
1022
+ def get_subscription_item_price(appstore_client:nil, subscription_id:nil)
1023
+
1024
+ itc_usa_latest_price = 0
1025
+
1026
+ respose_price = appstore_client.list_subscription_all_price(
1027
+ id:subscription_id,
1028
+ include:"subscriptionPricePoint",
1029
+ filter: {
1030
+ territory: 'USA'
1031
+ },
1032
+ limit:200
1033
+ )
1034
+ # puts JSON.pretty_generate(respose_price)
1035
+
1036
+ if !respose_price[:included].nil?
1037
+ # respose_price[:included].each do |include_item|
1038
+ # if include_item[:type].to_s.eql?("subscriptionPricePoints")
1039
+ # itc_usa_latest_price = include_item[:attributes][:customer_price]
1040
+ # end
1041
+ # end
1042
+
1043
+ #get the latest price
1044
+ include_item = respose_price[:included].last
1045
+ if !include_item.nil? && !include_item[:type].nil? && include_item[:type].to_s.eql?("subscriptionPricePoints")
1046
+ itc_usa_latest_price = include_item[:attributes][:customer_price]
1047
+ end
1048
+ end
1049
+ return itc_usa_latest_price
1050
+
1051
+ end
1052
+
1053
+ def create_subscription_item_price(appstore_client:nil, subscription_id:nil, subscription_item:nil)
1054
+
1055
+ puts " 更新价格 "
1056
+ begin
1057
+
1058
+
1059
+ #在线订阅修改价格
1060
+
1061
+ itc_usa_latest_price = nil
1062
+ itc_usa_latest_start_date = nil
1063
+ need_modify_price = true
1064
+
1065
+ if subscription_item["state"].to_s.eql?("APPROVED")
1066
+
1067
+ respose_price = appstore_client.list_subscription_all_price(
1068
+ id:subscription_id,
1069
+ include:"subscriptionPricePoint",
1070
+ filter: {
1071
+ territory: 'USA'
1072
+ },
1073
+ limit:200
1074
+ )
1075
+ # puts JSON.pretty_generate(respose_price)
1076
+
1077
+
1078
+ if !respose_price[:data].nil?
1079
+ respose_price[:data].each_with_index do |data_item, data_index|
1080
+ if data_item[:type].to_s.eql?("subscriptionPrices")
1081
+ temp_id = data_item[:id]
1082
+ temp_price_point_id = data_item[:relationships][:subscription_price_point][:data][:id]
1083
+ price_point_item = respose_price[:included].find { |e| e[:id].eql?(temp_price_point_id) }
1084
+
1085
+ itc_usa_price = price_point_item[:attributes][:customer_price]
1086
+ data_string = data_item[:attributes][:start_date].nil? ? "无" : data_item[:attributes][:start_date]
1087
+ puts " 线上价格#{data_index} :" + itc_usa_price +"$" + " 生效日期 : " + data_string
1088
+ end
1089
+ end
1090
+
1091
+ #get the latest price
1092
+ data_item = respose_price[:data].last
1093
+ if data_item[:type].to_s.eql?("subscriptionPrices")
1094
+ itc_usa_latest_start_date = data_item[:attributes][:start_date]
1095
+ end
1096
+ end
1097
+
1098
+
1099
+ if !respose_price[:included].nil?
1100
+ include_item = respose_price[:included].last
1101
+ if include_item[:type].to_s.eql?("subscriptionPricePoints")
1102
+ itc_usa_latest_price = include_item[:attributes][:customer_price]
1103
+ puts " 最新线上价格:" + itc_usa_latest_price +"$"
1104
+ end
1105
+ end
1106
+
1107
+
1108
+ if !itc_usa_latest_price.nil? && itc_usa_latest_price.to_s.eql?(subscription_item["price"].to_s)
1109
+ need_modify_price = false
1110
+ end
1111
+
1112
+ end
1113
+
1114
+
1115
+
1116
+ if !need_modify_price
1117
+ puts " 与最新线上价格相同, 无需修改价格 !"
1118
+ return
1119
+ end
1120
+
1121
+
1122
+ respose_usa_price_points = appstore_client.list_subscription_price_points(
1123
+ id:subscription_id,
1124
+ include: 'territory',
1125
+ filter: {
1126
+ territory: 'USA'
1127
+ },
1128
+ limit:800
1129
+ )
1130
+
1131
+ price_point_id = nil
1132
+ respose_usa_price_points[:data].each do |price_item|
1133
+ if price_item[:attributes][:customer_price].to_s.eql?(subscription_item["price"].to_s)
1134
+ price_point_id = price_item[:id]
1135
+ puts " 创建价格:" + subscription_item["price"] +"$"
1136
+ # puts price_point_id
1137
+ break;
1138
+ end
1139
+ end
1140
+
1141
+ # itc_latest_price_point_id = nil
1142
+ # if subscription_item["state"].to_s.eql?("APPROVED") && !itc_usa_latest_price.nil?
1143
+ # respose_usa_price_points[:data].each do |price_item|
1144
+ # if price_item[:attributes][:customer_price].to_s.eql?(itc_usa_latest_price.to_s)
1145
+ # itc_latest_price_point_id = price_item[:id]
1146
+ # break;
1147
+ # end
1148
+ # end
1149
+ # end
1150
+
1151
+
1152
+
1153
+ if !price_point_id.nil?
1154
+
1155
+ attributes = {}
1156
+ time_tomo = Time.now + 1.day
1157
+ date_str_tomo = time_tomo.strftime('%Y-%m-%d')
1158
+ date_str_now = Time.now.strftime('%Y-%m-%d')
1159
+ if subscription_item["state"].to_s.eql?("APPROVED")
1160
+ attributes = {
1161
+ startDate:date_str_tomo,
1162
+ preserveCurrentPrice:true
1163
+ }
1164
+ end
1165
+
1166
+ respose_equalizations_id = appstore_client.list_subscription_price_points_equalizations(
1167
+ id:price_point_id,
1168
+ include:'territory',
1169
+ limit:200
1170
+ )
1171
+ # puts JSON.pretty_generate(respose_equalizations_id)
1172
+
1173
+ price_change_relationships_data = {
1174
+ newSubscriptionPricePoints:{
1175
+ data:[]
1176
+ },
1177
+ currentSubscriptionPricePoints:{
1178
+ data:[]
1179
+ }
1180
+
1181
+ }
1182
+
1183
+ relationships_data = {
1184
+ prices:{
1185
+ data:[]
1186
+ }
1187
+ }
1188
+
1189
+ included_data = []
1190
+
1191
+ if !respose_equalizations_id[:data].nil?
1192
+
1193
+ index_num = 0
1194
+
1195
+ relationships_data[:prices][:data] << {
1196
+ type: "subscriptionPrices",
1197
+ id: "${newprice-#{index_num}}"
1198
+ }
1199
+
1200
+
1201
+ included_data << {
1202
+ type: "subscriptionPrices",
1203
+ id: "${newprice-#{index_num}}",
1204
+ attributes: attributes,
1205
+ relationships:{
1206
+ subscriptionPricePoint:{
1207
+ data:{
1208
+ type:"subscriptionPricePoints",
1209
+ id: price_point_id
1210
+ }
1211
+ }
1212
+ }
1213
+ }
1214
+
1215
+ price_change_relationships_data[:newSubscriptionPricePoints][:data] << {
1216
+ type:"subscriptionPricePoints",
1217
+ id: price_point_id
1218
+ }
1219
+
1220
+ index_num = index_num +1
1221
+
1222
+ respose_equalizations_id[:data].each do |price_local_item|
1223
+
1224
+ local_price_point_id = price_local_item[:id]
1225
+ relationships_data[:prices][:data] << {
1226
+ type: "subscriptionPrices",
1227
+ id: "${newprice-#{index_num}}"
1228
+ }
1229
+ included_data << {
1230
+ type: "subscriptionPrices",
1231
+ id: "${newprice-#{index_num}}",
1232
+ attributes: attributes,
1233
+ relationships:{
1234
+ subscriptionPricePoint:{
1235
+ data:{
1236
+ type:"subscriptionPricePoints",
1237
+ id: local_price_point_id
1238
+ }
1239
+ }
1240
+ }
1241
+ }
1242
+
1243
+
1244
+ price_change_relationships_data[:newSubscriptionPricePoints][:data] << {
1245
+ type:"subscriptionPricePoints",
1246
+ id: local_price_point_id
1247
+ }
1248
+
1249
+ index_num = index_num +1
1250
+ end
1251
+
1252
+ # puts JSON.pretty_generate(relationships_data)
1253
+ # puts JSON.pretty_generate(included_data)
1254
+
1255
+
1256
+
1257
+ if subscription_item["state"].to_s.eql?("APPROVED")
1258
+
1259
+
1260
+
1261
+ respose_response = appstore_client.list_subscription_all_price(
1262
+ id:subscription_id,
1263
+ include:"subscriptionPricePoint",
1264
+ limit:200
1265
+ )
1266
+
1267
+ all_price_data = []
1268
+
1269
+
1270
+ next_respose_response = respose_response
1271
+ all_price_data = all_price_data + respose_response[:data]
1272
+ while !next_respose_response.nil? && !next_respose_response[:links].nil? && !next_respose_response[:links][:next].nil?
1273
+
1274
+ cursor = nil
1275
+ # puts next_respose_response[:links][:next]
1276
+ url_parse = URI.parse(next_respose_response[:links][:next])
1277
+ url_param_string = url_parse.query.split('&')
1278
+ cursor_string = url_param_string.find {|e| e.include?('cursor=')}
1279
+ cursor = cursor_string.split('=')[1]
1280
+
1281
+ next_respose_response = appstore_client.list_subscription_all_price(
1282
+ id:subscription_id,
1283
+ include:"subscriptionPricePoint",
1284
+ cursor:cursor,
1285
+ limit:200
1286
+ )
1287
+ all_price_data = all_price_data + next_respose_response[:data]
1288
+ end
1289
+
1290
+ # puts JSON.pretty_generate(all_price_data)
1291
+ # puts "all_price_data.size: #{all_price_data.size}"
1292
+
1293
+ # puts "respose_response[:included].size : #{respose_response[:included].size }"
1294
+ if !itc_usa_latest_start_date.nil? && !respose_response.nil? && !respose_response[:links].nil? && !respose_response[:links][:next].nil?
1295
+ last_data_items = all_price_data.select { |e| e[:attributes][:start_date].eql?(itc_usa_latest_start_date)}
1296
+ else
1297
+ last_data_items = all_price_data
1298
+ end
1299
+
1300
+
1301
+ if last_data_items.size > 0
1302
+ last_data_items.each do |last_data_item|
1303
+ if last_data_item[:type].to_s.eql?("subscriptionPrices")
1304
+ price_change_relationships_data[:currentSubscriptionPricePoints][:data] << {
1305
+ type:"subscriptionPricePoints",
1306
+ id: last_data_item[:relationships][:subscription_price_point][:data][:id]
1307
+ }
1308
+ end
1309
+ end
1310
+ end
1311
+
1312
+
1313
+ # puts JSON.pretty_generate(price_change_relationships_data)
1314
+ # puts "price_change_relationships_data[:currentSubscriptionPricePoints][:data].size #{price_change_relationships_data[:currentSubscriptionPricePoints][:data].size}"
1315
+ # puts "price_change_relationships_data[:newSubscriptionPricePoints][:data]..size #{price_change_relationships_data[:newSubscriptionPricePoints][:data].size}"
1316
+ body = {
1317
+ data: {
1318
+ type: "subscriptionPriceChangeConsentReasons",
1319
+ relationships: price_change_relationships_data
1320
+ }
1321
+ }
1322
+
1323
+ client = Spaceship::ConnectAPI
1324
+
1325
+ begin
1326
+
1327
+ respose_price = client.tunes_request_client.post("subscriptionPriceChangeConsentReasons", body)
1328
+
1329
+ # puts JSON.pretty_generate(respose_price)
1330
+ rescue => err
1331
+ # puts err
1332
+ # puts "subscriptionPriceChangeConsentReasons errors"
1333
+ end
1334
+ # respose_price = appstore_client.create_subscription_price_change_consent_reason(
1335
+ # relationships: price_change_relationships_data
1336
+ # )
1337
+ # puts JSON.pretty_generate(respose_price)
1338
+
1339
+
1340
+
1341
+ body = {
1342
+ data: {
1343
+ type: "subscriptions",
1344
+ id:subscription_id,
1345
+ relationships: relationships_data
1346
+ },
1347
+ included: included_data
1348
+ }
1349
+ # puts "relationships_data[:prices][:data].size #{relationships_data[:prices][:data].size}"
1350
+ # puts "included_data.size: #{included_data.size}"
1351
+ # puts JSON.pretty_generate(body)
1352
+
1353
+ respose_price = client.tunes_request_client.patch("subscriptions/#{subscription_id}", body)
1354
+ # respose_price = appstore_client.update_subscription(
1355
+ # id:subscription_id,
1356
+ # relationships: relationships_data,
1357
+ # included: included_data
1358
+ # )
1359
+ # puts JSON.pretty_generate(respose_price)
1360
+ puts " 更新订阅价格成功!!! 生效日期 : #{date_str_tomo}"
1361
+
1362
+ else
1363
+
1364
+ response = appstore_client.update_subscription(
1365
+ id:subscription_id,
1366
+ relationships: relationships_data,
1367
+ included: included_data
1368
+ )
1369
+
1370
+ puts " 创建订阅价格成功 !"
1371
+ # puts JSON.pretty_generate(response)
1372
+
1373
+ end
1374
+
1375
+
1376
+
1377
+ end
1378
+
1379
+ else
1380
+ puts "!!!! 更新价格错误!!! 价格:" + + subscription_item["price"] +"$"
1381
+ end
1382
+
1383
+ rescue => err
1384
+ puts "!!!! 更新价格错误!!! 价格:" + + subscription_item["price"] +"$"
1385
+ puts err
1386
+ end
1387
+
1388
+ end
1389
+
1390
+
1391
+ def update_subscription_item_introductory_offer(appstore_client:nil, subscription_id:nil, subscription_item:nil)
1392
+ puts " 设置Introductory Offer : "
1393
+ if !subscription_item["subscription_free_trial"].nil? && subscription_item["subscription_free_trial"].to_s.eql?("3d")
1394
+ puts " 3天 试用"
1395
+ create_subscription_item_introductory_offer(appstore_client:appstore_client, subscription_id:subscription_id, subscription_item:subscription_item)
1396
+ else
1397
+ puts " 无试用"
1398
+ end
1399
+
1400
+ end
1401
+
1402
+ def create_subscription_item_introductory_offer(appstore_client:nil, subscription_id:nil, subscription_item:nil)
1403
+
1404
+
1405
+ begin
1406
+
1407
+ territory_response = appstore_client.list_subscription_territory_availability(
1408
+ id:subscription_id,
1409
+ limit:200
1410
+ )
1411
+
1412
+ # puts JSON.pretty_generate(territory_response)
1413
+
1414
+ relationships_data = {
1415
+ introductoryOffers:{
1416
+ data:[]
1417
+ }
1418
+ }
1419
+
1420
+ included_data = []
1421
+
1422
+ if !territory_response[:data].nil?
1423
+ index_num = 0
1424
+ territory_response[:data].each do |territory_item|
1425
+ local_territory_id = territory_item[:id]
1426
+ relationships_data[:introductoryOffers][:data] << {
1427
+ type: "subscriptionIntroductoryOffers",
1428
+ id: "${newIntroOffer-#{index_num}}"
1429
+ }
1430
+
1431
+ included_data << {
1432
+ type: "subscriptionIntroductoryOffers",
1433
+ id: "${newIntroOffer-#{index_num}}",
1434
+ attributes: {
1435
+ duration:"THREE_DAYS",
1436
+ offerMode:"FREE_TRIAL",
1437
+ numberOfPeriods:1
1438
+ },
1439
+ relationships:{
1440
+ territory:{
1441
+ data:{
1442
+ type:"territories",
1443
+ id: local_territory_id
1444
+ }
1445
+ }
1446
+ }
1447
+ }
1448
+
1449
+ index_num = index_num +1
1450
+
1451
+ end
1452
+
1453
+ response = appstore_client.update_subscription(
1454
+ id:subscription_id,
1455
+ relationships: relationships_data,
1456
+ included: included_data
1457
+ )
1458
+ puts " 3天 试用 设置成功!"
1459
+ # puts JSON.pretty_generate(response)
1460
+ end
1461
+
1462
+ rescue => err
1463
+ puts " !!!! 设置Introductory Offer 失败 !!! "
1464
+ puts err
1465
+ end
1466
+
1467
+
1468
+ end
1469
+
1470
+
1471
+ def delete_subscription_item_introductory_offer(appstore_client:nil, subscription_id:nil, subscription_item:nil)
1472
+
1473
+ begin
1474
+
1475
+ introductory_response = appstore_client.list_all_introductory_offers_ids_for_subscription(
1476
+ id:subscription_id,
1477
+ limit:200
1478
+ )
1479
+
1480
+ # puts JSON.pretty_generate(introductory_response)
1481
+
1482
+ if !introductory_response[:data].nil? && introductory_response[:data].size > 0
1483
+
1484
+ # puts JSON.pretty_generate(introductory_response[:data])
1485
+ puts " 线上有试用,先删除"
1486
+ temp_data = [];
1487
+
1488
+ introductory_response[:data].each do |introductory_item|
1489
+ temp_data << {id: introductory_item[:id]}
1490
+ end
1491
+
1492
+
1493
+ introductory_response = appstore_client.delete_introductory_offers_for_subscription(
1494
+ id:subscription_id,
1495
+ data:temp_data
1496
+ )
1497
+
1498
+ puts " 线上试用删除成功!!!"
1499
+ # puts JSON.pretty_generate(introductory_response)
1500
+ else
1501
+ puts " 线上无试用, 无需删除!!!"
1502
+ end
1503
+
1504
+ rescue => err
1505
+ puts " !!!! 删除 试用 失败 !!!!"
1506
+ puts err
1507
+ end
1508
+
1509
+ end
1510
+
1511
+
1512
+
1513
+ def delete_subscription_item_introductory_offer_with_singlefunc(appstore_client:nil, subscription_id:nil)
1514
+
1515
+
1516
+ begin
1517
+
1518
+ response = appstore_client.list_subscription_introductory_offer_resoure_ids(
1519
+ id:subscription_id,
1520
+ limit:200
1521
+ )
1522
+ # puts JSON.pretty_generate(response)
1523
+
1524
+ index_item = 0
1525
+ if !response[:data].nil?
1526
+
1527
+ response[:data].each do |price_point_item|
1528
+
1529
+ index_item = index_item +1
1530
+
1531
+
1532
+ puts " 删除" + index_item.to_s+ "地区的Introductory Offer"
1533
+
1534
+ ret = appstore_client.delete_subscription_introductory_offer(id:price_point_item[:id])
1535
+ # puts JSON.pretty_generate(ret)
1536
+
1537
+ end
1538
+
1539
+ end
1540
+
1541
+
1542
+ rescue => err
1543
+
1544
+ puts err
1545
+ end
1546
+
1547
+ end
1548
+
1549
+
1550
+ def create_subscription_item_introductory_offer_with_singlefunc(appstore_client:nil, subscription_id:nil, price_point_id:nil, territory:nil)
1551
+
1552
+ puts " 设置Introductory Offer"
1553
+ begin
1554
+
1555
+ response = appstore_client.create_subscription_introductory_offer(
1556
+ duration:"THREE_DAYS",
1557
+ number_of_periods:1,
1558
+ offer_mode:'FREE_TRIAL',
1559
+ relationships: {
1560
+ subscription: {
1561
+ data: {
1562
+ type: 'subscriptions',
1563
+ id: subscription_id
1564
+ }
1565
+ },
1566
+ subscriptionPricePoint: {
1567
+ data: {
1568
+ type: 'subscriptionPricePoints',
1569
+ id: price_point_id
1570
+ }
1571
+ },
1572
+ territory: {
1573
+ data: {
1574
+ type: 'territories',
1575
+ id: territory
1576
+ }
1577
+ }
1578
+
1579
+ },
1580
+ included:[{
1581
+ type: "subscriptionPrices",
1582
+ id: price_point_id
1583
+ }]
1584
+ )
1585
+ # puts JSON.pretty_generate(response)
1586
+
1587
+ rescue => err
1588
+
1589
+ puts err
1590
+ end
1591
+ end
1592
+
1593
+
1594
+
1595
+ def create_subscription_item_price_with_singlefunc(appstore_client:nil, subscription_id:nil, subscription_item:nil)
1596
+ puts " 更新价格"
1597
+ begin
1598
+
1599
+ respose_price = appstore_client.list_subscription_price_points(
1600
+ id:subscription_id,
1601
+ include: 'territory',
1602
+ filter: {
1603
+ territory: 'USA'
1604
+ },
1605
+ limit:800
1606
+ )
1607
+
1608
+ price_point_id = nil
1609
+
1610
+ respose_price[:data].each do |price_item|
1611
+ if price_item[:attributes][:customer_price].to_s.eql?(subscription_item["price"].to_s)
1612
+ price_point_id = price_item[:id]
1613
+ puts " 1.更新价格 地区: USA 货币:USD 价格:" + + subscription_item["price"] +"$"
1614
+ break;
1615
+ end
1616
+ end
1617
+
1618
+ if !price_point_id.nil?
1619
+
1620
+ respose_price = appstore_client.create_subscription_price(
1621
+ preserve_current_price:true,
1622
+ relationships: {
1623
+ subscription: {
1624
+ data: {
1625
+ type: 'subscriptions',
1626
+ id: subscription_id
1627
+ }
1628
+ },
1629
+ subscriptionPricePoint: {
1630
+ data: {
1631
+ type: 'subscriptionPricePoints',
1632
+ id: price_point_id
1633
+ }
1634
+ }
1635
+ }
1636
+ )
1637
+
1638
+
1639
+
1640
+ if !subscription_item["subscription_free_trial"].nil? && subscription_item["subscription_free_trial"].to_s.eql?("3d")
1641
+
1642
+ create_subscription_item_introductory_offer_with_singlefunc(appstore_client:appstore_client, subscription_id:subscription_id, price_point_id:price_point_id, territory:'USA')
1643
+ end
1644
+
1645
+
1646
+
1647
+
1648
+ respose_price = appstore_client.list_subscription_price_points_equalizations(
1649
+ id:price_point_id,
1650
+ include:'territory',
1651
+ limit:200
1652
+ )
1653
+ # puts JSON.pretty_generate(respose_price)
1654
+
1655
+ index_item = 1
1656
+ if !respose_price[:data].nil?
1657
+
1658
+ respose_price[:data].each do |price_local_item|
1659
+ index_item = index_item +1
1660
+
1661
+ price_point_id = price_local_item[:id]
1662
+ territory_id = price_local_item[:relationships][:territory][:data][:id]
1663
+ puts " " + index_item.to_s + ".更新价格 地区:" + territory_id+ " 价格:" + price_local_item[:attributes][:customer_price]
1664
+
1665
+ respose_price = appstore_client.create_subscription_price(
1666
+ preserve_current_price:true,
1667
+ relationships: {
1668
+ subscription: {
1669
+ data: {
1670
+ type: 'subscriptions',
1671
+ id: subscription_id
1672
+ }
1673
+ },
1674
+ subscriptionPricePoint: {
1675
+ data: {
1676
+ type: 'subscriptionPricePoints',
1677
+ id: price_point_id
1678
+ }
1679
+ }
1680
+ }
1681
+ )
1682
+
1683
+ # puts JSON.pretty_generate(respose_price)
1684
+
1685
+ if !subscription_item["subscription_free_trial"].nil? && subscription_item["subscription_free_trial"].to_s.eql?("3d")
1686
+
1687
+ create_subscription_item_introductory_offer_with_singlefunc(appstore_client:appstore_client, subscription_id:subscription_id, price_point_id:price_point_id, territory:territory_id)
1688
+ end
1689
+
1690
+ end
1691
+
1692
+ end
1693
+
1694
+
1695
+ end
1696
+
1697
+ rescue => err
1698
+ puts "创建价格失败: " + subscription_item["product_id"]
1699
+ puts err
1700
+ end
1701
+ end
1702
+
1703
+ def update_subscription_item_screenshots(appstore_client:nil, subscription_id:nil, subscription_item:nil)
1704
+ puts " 更新截屏"
1705
+ begin
1706
+ response_iap_screenshot = appstore_client.read_review_screenshot_for_subscription(id:subscription_id)
1707
+
1708
+
1709
+ path = subscription_item["review_screenshot_fullpath"]
1710
+ filename = File.basename(path)
1711
+ filesize = File.size(path)
1712
+ bytes = File.binread(path)
1713
+
1714
+ checksum = Digest::MD5.hexdigest(bytes)
1715
+
1716
+ # puts JSON.pretty_generate(response_iap_screenshot)
1717
+
1718
+ need_upload_screenshot = true
1719
+
1720
+ if !response_iap_screenshot[:data].nil? && !response_iap_screenshot[:data][:attributes].nil? && !response_iap_screenshot[:data][:attributes][:asset_delivery_state].nil? && !response_iap_screenshot[:data][:attributes][:asset_delivery_state][:state].nil?
1721
+
1722
+ if response_iap_screenshot[:data][:attributes][:asset_delivery_state][:state].to_s.eql?("COMPLETE")
1723
+
1724
+ if !response_iap_screenshot[:data].nil? && !response_iap_screenshot[:data][:attributes].nil? && !response_iap_screenshot[:data][:attributes][:source_file_checksum].nil?
1725
+
1726
+ if checksum.to_s.eql?(response_iap_screenshot[:data][:attributes][:source_file_checksum].to_s)
1727
+ puts " 有截屏,截屏未修改,无需重新上传"
1728
+ need_upload_screenshot = false
1729
+
1730
+ end
1731
+ end
1732
+ end
1733
+ end
1734
+
1735
+
1736
+ if need_upload_screenshot && !response_iap_screenshot[:data].nil? && !response_iap_screenshot[:data][:attributes].nil? && !response_iap_screenshot[:data][:attributes][:file_name].nil?
1737
+ puts " 有截屏,先删除再更新"
1738
+ # puts JSON.pretty_generate(response_iap_screenshot)
1739
+ appstore_client.delete_subscription_review_screenshot(id:response_iap_screenshot[:data][:id])
1740
+ end
1741
+
1742
+
1743
+ if need_upload_screenshot
1744
+
1745
+ puts " 正在上传...."
1746
+ response_iap_screenshot = appstore_client.create_subscription_review_screenshot(
1747
+ file_name:filename,
1748
+ file_size: filesize,
1749
+ relationships: {
1750
+ subscription:{
1751
+ data:{
1752
+ id: subscription_id,
1753
+ type: 'subscriptions'
1754
+ }
1755
+ }
1756
+ }
1757
+ )
1758
+
1759
+ # puts JSON.pretty_generate(response_iap_screenshot)
1760
+
1761
+ if !response_iap_screenshot[:data].nil? && !response_iap_screenshot[:data][:id].nil?
1762
+
1763
+ upload_id = response_iap_screenshot[:data][:id]
1764
+ upload_operations = response_iap_screenshot[:data][:attributes][:upload_operations]
1765
+ upload_operations.each_with_index do |upload_operation, index|
1766
+ headers = {}
1767
+ upload_operation[:request_headers].each do |item|
1768
+ headers[item[:name]] = item[:value]
1769
+ end
1770
+ offset = upload_operation[:offset]
1771
+ length = upload_operation[:length]
1772
+ conn = Faraday.new
1773
+ res = conn.put(upload_operation[:url], bytes[offset, length], headers)
1774
+ end
1775
+
1776
+
1777
+
1778
+ in_app_purchase = appstore_client.update_subscription_review_screenshot(
1779
+ id:upload_id,
1780
+ uploaded: true,
1781
+ source_file_checksum:checksum
1782
+ )
1783
+ puts " 上传完成!!"
1784
+ # puts JSON.pretty_generate(in_app_purchase)
1785
+ end
1786
+
1787
+ else
1788
+
1789
+ puts " 存在图片,无需上传...."
1790
+ end
1791
+
1792
+
1793
+
1794
+
1795
+ rescue => err
1796
+ puts err
1797
+ puts " 更新截屏失败!!!"
1798
+ end
1799
+ end
1800
+
1801
+ end
1802
+
1803
+ end