RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/ビジネス
ビジネス/2026-04-20上級

App Store レビューを AI が自動返信 — App Store Connect API × Gemini でレビュー管理を半自動化する実践ガイド

App Store Connect API・Google Play Developer API・Gemini API を組み合わせ、レビュー返信を AI が下書き、開発者が承認する半自動化システムを構築する実践ガイド。5,000万DL規模での運用知見と Crashlytics 連携・confidence 設計まで踏み込みます。

App Store Connect API4Google Play APIGemini API5レビュー管理Cloudflare Workers24自動化12Rork Max229

プレミアム記事

アプリをリリースしてしばらく経つと、必ずぶつかる作業があります。App Store や Google Play に届くユーザーレビューへの返信です。

「最高のアプリ!毎日使ってます」という嬉しいレビューから、「クラッシュばかりで使えない」という厳しいフィードバックまで、誠実に返信し続けることは個人開発者にとって無視できない時間コストです。複数アプリを運営していた時期に計測したところ、1日あたり平均32分をレビュー確認と返信に費やしていました。月換算で約16時間。決して小さくない数字です。

私は2014年から個人開発で iOS / Android アプリを運営してきました。累計ダウンロードは5,000万を超え、現在でも壁紙アプリや癒し系アプリを複数公開しています。その中で「レビュー返信」だけは、どれだけ自動化を試みても最後まで残り続ける手作業でした。テンプレ返信を貼ると一気に評価が冷えるし、無視すると新規ユーザーへの印象が悪化します。そこで、App Store Connect API・Google Play Developer API・Gemini API を組み合わせ、AI が下書きし、自分は承認ボタンだけ押す半自動パイプラインを組みました。以下、その全体像と、Rork で作ったモバイル管理ダッシュボードと Cloudflare Workers バックエンドのコードを順に共有していきます。

「自動化したら返信が機械的になるのでは?」と思われるかもしれません。実際に動かしてみると、Gemini が生成する返信文はアプリのコンテキストを理解した上で、開発者が書いたようなトーンで出力されます。その精度は、初めて確認したときに驚くほどです。

なぜレビュー返信が評価に直結するのか

Apple と Google どちらも、開発者がレビューに返信すると検索順位に好影響があることを示すデータがあります。App Store では、開発者が返信したレビューの評価点数が平均 0.3〜0.5 上昇するという報告があります(Sensor Tower 調べ)。

より重要なのは、1 つ星の厳しいレビューに丁寧に返信すると、そのユーザーが評価を更新してくれるケースが少なくないということです。「対応してくれた」という体験が、そのまま口コミになります。

一方で、現実問題として返信が滞りがちになる理由もよく分かります。

  • 複数アプリを運営していると、全てのレビューを確認するだけで時間がかかる
  • 似たような質問やバグ報告に毎回同じような文章を書くのが苦痛
  • 英語・韓国語・中国語など、母語でないレビューへの返信が難しい
  • 感情的なレビューに丁寧に返信するのが精神的に疲れる

この問題を解決するために、「AI が草稿を作り、開発者が承認する」というハイブリッドモデルを構築します。完全自動化ではなく、最終チェックは人間が行うことで、問題のある返信が出ていかないセーフティネットも担保します。自信度(confidence)が高い返信は自動送信、不確かなものは手動確認という設計です。

App Store Connect API のセットアップ

API キーの発行

まず App Store Connect で API キーを発行します。https://appstoreconnect.apple.com/access/integrations/api にアクセスし、「チームキー」タブから新しいキーを作成してください。

重要な注意点: キーは作成時に一度しかダウンロードできません。.p8 ファイルを安全な場所に保管してください。発行後は以下の 3 つの値が必要になります。

  • Issuer ID: API キー画面の上部に表示される UUID 形式の文字列
  • Key ID: キー作成後に表示される英数字 10 桁
  • Private Key: ダウンロードした .p8 ファイルの内容

JWT 認証の実装

App Store Connect API は JWT(JSON Web Token)認証を使います。Cloudflare Workers で JWT を生成する実装は以下の通りです。

// src/appstore/auth.ts
// App Store Connect API 用 JWT トークン生成
 
interface AppStoreConnectConfig {
  issuerId: string;
  keyId: string;
  privateKey: string; // .p8 ファイルの内容(ヘッダー/フッター行を除いた本体)
}
 
async function generateAppStoreToken(
  config: AppStoreConnectConfig
): Promise<string> {
  const header = {
    alg: "ES256",
    kid: config.keyId,
    typ: "JWT",
  };
 
  const now = Math.floor(Date.now() / 1000);
  const payload = {
    iss: config.issuerId,
    iat: now,
    exp: now + 19 * 60, // 最大20分(余裕を持って19分に設定)
    aud: "appstoreconnect-v1",
  };
 
  const encodeBase64Url = (obj: object): string =>
    btoa(JSON.stringify(obj))
      .replace(/\+/g, "-")
      .replace(/\//g, "_")
      .replace(/=/g, "");
 
  const headerEncoded = encodeBase64Url(header);
  const payloadEncoded = encodeBase64Url(payload);
  const signingInput = `${headerEncoded}.${payloadEncoded}`;
 
  // ES256 署名(Cloudflare Workers の WebCrypto API を使用)
  const pemKey = `-----BEGIN PRIVATE KEY-----\n${config.privateKey}\n-----END PRIVATE KEY-----`;
  const keyBuffer = pemToBuffer(pemKey);
 
  const cryptoKey = await crypto.subtle.importKey(
    "pkcs8",
    keyBuffer,
    { name: "ECDSA", namedCurve: "P-256" },
    false,
    ["sign"]
  );
 
  const encoder = new TextEncoder();
  const signature = await crypto.subtle.sign(
    { name: "ECDSA", hash: "SHA-256" },
    cryptoKey,
    encoder.encode(signingInput)
  );
 
  const signatureEncoded = btoa(
    String.fromCharCode(...new Uint8Array(signature))
  )
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=/g, "");
 
  return `${signingInput}.${signatureEncoded}`;
}
 
function pemToBuffer(pem: string): ArrayBuffer {
  const base64 = pem
    .replace(/-----BEGIN PRIVATE KEY-----/, "")
    .replace(/-----END PRIVATE KEY-----/, "")
    .replace(/\s/g, "");
 
  const binary = atob(base64);
  const buffer = new ArrayBuffer(binary.length);
  const view = new Uint8Array(buffer);
  for (let i = 0; i < binary.length; i++) {
    view[i] = binary.charCodeAt(i);
  }
  return buffer;
}
 
export { generateAppStoreToken };

レビューの取得

// src/appstore/reviews.ts
// App Store Connect API でレビューを取得
 
interface Review {
  id: string;
  rating: number;
  title: string;
  body: string;
  reviewerNickname: string;
  territory: string;
  createdDate: string;
}
 
async function fetchReviews(
  appId: string,
  token: string,
  limit = 20
): Promise<Review[]> {
  const url = new URL(
    `https://api.appstoreconnect.apple.com/v1/apps/${appId}/customerReviews`
  );
  url.searchParams.set("limit", String(limit));
  url.searchParams.set("sort", "-createdDate"); // 新しい順
  // 返信優先度の高い低評価を優先
  url.searchParams.set("filter[rating]", "1,2,3");
 
  const response = await fetch(url.toString(), {
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
  });
 
  if (\!response.ok) {
    const error = await response.text();
    throw new Error(
      `App Store Connect API error: ${response.status} - ${error}`
    );
  }
 
  const data = (await response.json()) as {
    data: Array<{
      id: string;
      attributes: {
        rating: number;
        title: string | null;
        body: string;
        reviewerNickname: string;
        territory: string;
        createdDate: string;
      };
    }>;
  };
 
  return data.data.map((item) => ({
    id: item.id,
    rating: item.attributes.rating,
    title: item.attributes.title ?? "",
    body: item.attributes.body,
    reviewerNickname: item.attributes.reviewerNickname,
    territory: item.attributes.territory,
    createdDate: item.attributes.createdDate,
  }));
}
 
export { fetchReviews };

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
5,000万DL規模のアプリ運用で実証した、AI が下書き・人間が承認する半自動レビュー返信パイプラインの全体像と実装コード
Crashlytics の最新クラッシュと『クラッシュします』レビューを突合し、ステータスに応じて返信トーンを切り替える運用設計
confidence しきい値・JWT クロックスキュー対策・Google Play API のクォータ実情など、公式ドキュメントに書かれていない3ヶ月運用で得た判断材料
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

ビジネス2026-07-02
Rork Max アプリの広告eCPMを落とさない ATT 許可率の上げ方 — 事前許可プライミングの設計
Rork Max で作った iOS アプリの広告収益は、ATT の許可率で大きく変わります。事前許可プライミング画面の設計・SwiftUI 実装・許可率の計測・AdMob 初期化順序までを、個人開発の実運用視点でまとめました。
ビジネス2026-07-01
Rork Max のアプリで Tap to Pay on iPhone を扱う前に — 資格要件と決済事業者の選び方、現実的な設計
iPhone 単体で対面決済を受ける Tap to Pay を、Rork Max のアプリに組み込めるかを事業目線で見極める実装メモです。組織アカウントと権利(entitlement)の要件、決済事業者(PSP)の必要性、ProximityReader と PSP の役割分担、個人開発者が現実的に取れる進め方まで、率直にまとめます。
ビジネス2026-06-30
App Store のシステムメッセージを「いい瞬間」まで遅らせる設計
値上げ同意やウィンバック、請求エラーといった App Store のシステムメッセージは、既定では起動直後に割り込んできます。StoreKit 2 の Message を握り、オンボーディングや決済を邪魔しない瞬間まで表示を遅らせる設計を、動く Swift コードでまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →