C#からApp Store Connect APIを叩いて売上レポートを取得する
Google Playはこちら → C#からGoogle Play Consoleの売上レポートを取得する
悩んでググってこの記事に辿り着いた方向けの何の補足もない不親切な記事です。
Pkcs8PrivateBlobとかはWindowsでしか動かないので使ってません。
App Store Connect APIのドキュメント
AppStoreConnect.cs
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
// https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api
var p8FilePath = "~~~~~~~.p8";
var issuerId = "~~~~~~~";
var keyId = "~~~~~~~";
var vendorNumber = "~~~~~~~~";
var privateKeyString = string.Join("", File.ReadAllLines(p8FilePath, Encoding.UTF8).Skip(1).Take(4));
var key = ECDsa.Create();
key.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKeyString), out _);
var utcNow = DateTimeOffset.UtcNow;
// https://developer.apple.com/documentation/appstoreconnectapi/generating_tokens_for_api_requests
var headers = new Dictionary<string, object>
{
{ "kid", keyId },
{ "typ", "JWT" },
};
var payload = new Dictionary<string, object>
{
{ "aud", "appstoreconnect-v1" },
{ "iat", utcNow.ToUnixTimeSeconds() },
{ "exp", utcNow.AddMinutes(10).ToUnixTimeSeconds() },
{ "iss", issuerId },
};
var algorithm = new ES256Algorithm(ECDsa.Create(), key);
var serializer = new JsonNetSerializer();
var urlEncoder = new JwtBase64UrlEncoder();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
var token = encoder.Encode(headers, payload, "");
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/a-gzip"));
var builder = new UriBuilder($"https://api.appstoreconnect.apple.com/v1/salesReports");
var query = HttpUtility.ParseQueryString(builder.Query);
query[HttpUtility.UrlEncode("filter[version]")] = "1_0";
query[HttpUtility.UrlEncode("filter[frequency]")] = "DAILY";
query[HttpUtility.UrlEncode("filter[reportDate]")] = "2022-10-01";
query[HttpUtility.UrlEncode("filter[reportSubType]")] = "SUMMARY";
query[HttpUtility.UrlEncode("filter[reportType]")] = "SALES";
query[HttpUtility.UrlEncode("filter[vendorNumber]")] = vendorNumber;
builder.Query = query.ToString();
var result = await client.GetAsync(builder.ToString());
var bytes = await result.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("a.gzip", bytes);落ちてくるのはtsv(csvじゃないよ!)が1個だけ入ったgzipなので
Decompress.cs
private static string Decompress(byte[] compressed)
{
using var from = new MemoryStream(compressed);
using var to = new MemoryStream();
using var gZipStream = new GZipStream(from, CompressionMode.Decompress);
gZipStream.CopyTo(to);
return Encoding.UTF8.GetString(to.ToArray());
}こんな感じでテキストにしてやって、tabでsplitすると読めます。