Googleスプレッドシート×ラッコキーワードAPIでメディア運営を効率化しよう!【初心者向け】

「キーワードの収集を毎回手作業でやるのが面倒・・」
「記事のリライトを行うまでに時間がかかる・・」

自身でメディア運営をしていると、このような悩みを感じることはありませんか?

実はこれらの悩みは、普段お使いの「Googleスプレッドシート」と「ラッコキーワードAPI」を連携させることで解決できます。

この2つを連携させれば、ラッコキーワードの画面操作を一切行わずにキーワードを取得することが可能です。

さらに、取得したキーワードをAIで分析することで、記事のリライトなどの作業を効率化することもできます。

本記事では「Googleスプレッドシート × ラッコキーワードAPI」の連携方法と、メディア運営の効率化における具体的な活用例についてご紹介します。

連携には、Googleが無料で提供するプログラミング環境「GAS(Google Apps Script)」を使用します。
なお、コードはAIに書かせるためプログラミング知識は一切不要です。

普段からスプレッドシートでキーワード管理・記事管理をしている方は特にオススメです!
この記事の前提条件
  • ラッコキーワードのスタンダードプラン以上を契約していること
  • Googleアカウント(Googleスプレッドシート・GAS利用のため)をお持ちであること
  • AI(Gemini・ChatGPT)が利用できる環境であること

そもそも「API」とは?

API(エーピーアイ)とは「Application Programming Interface」の略で、アプリ同士がデータをやり取りするための窓口のことです。

たとえばラッコキーワードを普段使うときは、Webブラウザで画面を開いて検索ボタンをクリックし、結果を目で見て確認します。

一方でAPIを使うと、「画面操作」を一切行わずに別のアプリ(今回はGoogleスプレッドシート)から直接ラッコキーワードのデータを取得できます。

APIのイメージ

レストランで例えると、APIは「注文窓口」のような存在です。

お客様(GoogleスプレッドシートやAI)が「キーワード『ラッコ』の関連キーワードを10件ください」と注文すると、キッチン(ラッコキーワード)が裏で調理して、料理(関連キーワード10件)を提供してくれます。

注文側はキッチンの中の仕組みを知らなくても、決まった形式で注文するだけで欲しいデータを受け取れる、という仕組みです。

ラッコキーワードAPIで取得できる主なデータは以下の通りです。

  • サジェストキーワード
  • 関連キーワード
  • LSI/PAA
  • よくある質問検索
  • 同時ランクインキーワード
  • 一括キーワード調査
  • 獲得キーワード調査
  • 集客コンテンツ検索
  • 見出し抽出
  • 共起語
  • 検索順位チェック

取得できるデータの詳細はAPIドキュメントでご確認いただけます。

ラッコキーワードAPIの利用条件

ラッコキーワードAPIはスタンダードプラン(月額2,475円〜)以上で利用可能です。
※上記以外(フリー(無料)プラン・エントリープラン・ライトプラン・旧プラン)ではご利用いただけません。

「Googleスプレッドシート×ラッコキーワードAPI」を連携すると何ができる?

Googleスプレッドシート・ラッコキーワードAPIを連携させると、さまざまな作業を効率化することができます。

ここでは具体的な例を3つご紹介します。

①複数のキーワード情報をまとめて取得できる

1つ目は、複数のキーワード情報をまとめて一括で取得できるという点です。

ラッコキーワードの画面では、1度に「1つのキーワード × 1つの機能」の単位でしか検索できず、調べたいキーワードや使用する機能が複数ある場合、その分作業を繰り返す必要があります。

しかし、API連携を行うと「複数キーワード × 複数機能」のデータをまとめて取得できるため、作業にかかる時間を短縮することが可能です。

②取得したデータをスプレッドシート上に自動で反映・一括管理できる

2つ目は、取得したデータをスプレッドシート上に自動で反映・データを一括で管理できるという点です。

ラッコキーワードの画面から検索結果をファイル出力すると、スプレッドシートへの取り込み作業が必要になったり、ファイル管理の負担が増えてしまいます。

しかし、API連携を行えばスプレッドシート内に直接データを取得できる(ファイル取り込み作業が不要)ほか、データをまとめて管理することも可能です。

③定期実行による自動データ取得ができる

3つ目は、キーワードデータの取得作業を指定したタイミングで自動実行できるという点です。

例えば、毎週・毎月など定期的に同じキーワードを調査しようとすると、毎回ラッコキーワードの画面を開いて検索→結果を取得する必要があります。

しかし、ラッコキーワードAPIを使うと、Googleスプレッドシート上にある「GASのトリガー機能」から指定したタイミングでキーワードデータを自動取得することが可能です。

「Googleスプレッドシート × ラッコキーワードAPI」の具体的な連携イメージは沸きましたか?
次のステップで、実際の連携手順を見ていきましょう。

Googleスプレッドシート × ラッコキーワードAPIの連携方法

ここからは以下の手順に沿って、Googleスプレッドシート × ラッコキーワードAPIを連携していきます。

今回は、ラッコキーワードAPIとGASを使用して「関連キーワードをGoogleスプレッドシートに取得する」フローを例にご紹介します。

ステップ1:APIキーを準備する

まず最初に、ラッコキーワードの管理画面からAPIキーを発行します。

APIキーとは、GASがラッコキーワードAPIにアクセスする際の「認証用のパスワード」のような役割を持つ文字列です。

注意:APIキーの取り扱いに注意

APIキーは他人に知られないよう厳重に管理してください。誤って公開リポジトリやSNSに投稿すると、第三者に不正利用される恐れがあります。

【発行手順】

※クリックすると画像を拡大できます

ラッコキーワードの契約管理画面でAPIキーを発行
STEP 1契約管理画面にアクセスし、「APIキーを発行」ボタンを押下します。
発行されたAPIキーをコピー
STEP 2APIキーが発行されたのを確認し、コピーして手元に保管しておきます。

ステップ2:GASを実行する

APIキーを取得できたら、実際にGASを実行して「関連キーワード」をGoogleスプレッドシートに取得してみましょう。

【手順】

※クリックすると画像を拡大できます

拡張機能からApps Scriptを開く
STEP 1Googleスプレッドシートを新規作成し、上部メニューから「拡張機能」>「Apps Script」をクリックします。
プロジェクト名を変更
STEP 2無題のプロジェクトが開くので、わかりやすい名前(例:「関連キーワード取得」)に変更します。

Apps Scriptとは?

Apps Scriptとは、Googleスプレッドシートに付属しているコード編集画面(エディタ)のことです。

STEP2完了後、デフォルトで入力されている function myFunction() { ... } をすべて削除し、以下のGASコードをコピー&ペーストします。

JavaScript

// ==========================================
// ラッコキーワードAPI 設定
// ==========================================
// 取得したAPIキーを以下の「YOUR_API_KEY_HERE」に置き換えてください。
const API_KEY = "YOUR_API_KEY_HERE";

/**
 * 関連キーワードを取得し、スプレッドシートに出力するメイン関数
 * (この関数をマクロとしてインポートします)
 */
function fetchRelatedKeywords() {
  const ui = SpreadsheetApp.getUi();

  // 1. キーワード入力のプロンプトを表示
  const promptResponse = ui.prompt(
    'ラッコキーワードAPI',
    '取得したい関連キーワードを入力してください:',
    ui.ButtonSet.OK_CANCEL
  );

  // キャンセルボタンが押された場合や、×ボタンで閉じた場合は終了
  if (promptResponse.getSelectedButton() !== ui.Button.OK) {
    return;
  }

  const inputKeyword = promptResponse.getResponseText().trim();
  if (!inputKeyword) {
    ui.alert('エラー', 'キーワードが入力されていません。', ui.ButtonSet.OK);
    return;
  }

  // 2. APIリクエストの設定
  // エンドポイント: 関連キーワード取得
  const apiUrl = 'https://api.rakkokeyword.com/v1/related-keywords';

  // 検索条件の指定
  const payload = {
    keyword: inputKeyword,
    sortBy: 'searchVolume', // 並び順: 月間検索数
    orderBy: 'desc',        // 並び順: 多い順(降順)
    limit: 100              // 取得件数: 100件
  };

  const options = {
    method: 'post',
    headers: {
      'X-API-Key': API_KEY,
      'Content-Type': 'application/json'
    },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true // エラー時もレスポンスを受け取る設定
  };

  try {
    // 3. API通信の実行
    const response = UrlFetchApp.fetch(apiUrl, options);
    const responseCode = response.getResponseCode();
    const responseBody = JSON.parse(response.getContentText());

    // エラーハンドリング
    if (responseCode !== 200) {
      const errorMessage = responseBody.errors ? responseBody.errors.join(', ') : '不明なエラー';
      ui.alert('APIエラー', `通信に失敗しました。\nステータスコード: ${responseCode}\nエラー詳細: ${errorMessage}`, ui.ButtonSet.OK);
      return;
    }

    // 結果データアイテムの配列を取得
    const items = responseBody.data.items;

    if (!items || items.length === 0) {
      ui.alert('結果', '関連キーワードが見つかりませんでした。', ui.ButtonSet.OK);
      return;
    }

    // 4. スプレッドシートへの書き込み準備
    const outputData = [];
    // 1行目にヘッダーを追加
    outputData.push(['キーワード', '月間検索数']);

    // 取得したデータを配列に格納
    items.forEach(item => {
      const kw = item.keyword;
      // 月間検索数が取得できない場合(nullなど)は未定義表記にする
      const searchVolume = (item.metrics && item.metrics.searchVolume !== null) ? item.metrics.searchVolume : 'データなし';

      outputData.push([kw, searchVolume]);
    });

    // 5. スプレッドシートへの書き込み実行
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    sheet.clearContents(); // 現在のシートのデータをすべて消去(上書き準備)

    // 出力データのサイズに合わせて範囲を指定し、一括で書き込み
    sheet.getRange(1, 1, outputData.length, outputData[0].length).setValues(outputData);

    ui.alert('完了', 'データの取得と書き込みが完了しました!', ui.ButtonSet.OK);

  } catch (error) {
    ui.alert('システムエラー', '処理中にエラーが発生しました:\n' + error.message, ui.ButtonSet.OK);
  }
}

/**
 * スプレッドシートを開いたときに専用メニューを自動追加する関数(おまけ)
 * マクロからだけでなく、メニューバーからも1クリックで実行できるようにしています。
 */
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu('ラッコAPI実行')
    .addItem('関連キーワードを取得', 'fetchRelatedKeywords')
    .addToUi();
}

貼り付け後、以下の手順で実行すると関連キーワードをGoogleスプレッドシートに取得できます。

YOUR_API_KEY_HEREを取得したAPIキーに置き換える
STEP 3YOUR_API_KEY_HERE をSTEP1で取得したラッコキーワードAPIキーと置き換え、「Ctrl + S」で保存します。
マクロをインポート
STEP 4スプレッドシートに戻り、「拡張機能」>「マクロ」>「マクロをインポート」をクリックします。
関数を追加
STEP 5「関数を追加」をクリックします。
マクロから関数を実行
STEP 6「拡張機能」>「マクロ」から、追加した関数をクリックして実行します。
キーワード入力モーダル
STEP 7モーダルが表示されるので、関連キーワードを取得したいキーワードを入力します。
関連キーワードデータが取得された画面
STEP 8GASが実行され、関連キーワードデータが取得できます。

権限の承認について(初回のみ)

マクロを初めて実行する際は「認証が必要です」という画面が表示されます。その場合、以下の手順で認証を進めてください。

  • 「認証が必要です」の下にあるOKをクリック
  • アクセスできる情報の欄ですべて選択にチェック
  • そのまま下にスクロールし続行をクリック
サイドパネルのGeminiを活用しよう!

サイドパネルのGeminiを使うと、Googleスプレッドシート上のデータをAIでシームレスに操作できます

例えば「キーワードデータを検索意図ごとにグルーピング後、このシート上に結果を出力して」と指示するだけで、同シート上にグルーピング結果が出力されます。

※Geminiサイドパネルの利用には、対象となるプランの契約(有料)が必要です。詳しくはこちらをご参照ください。

ステップ3:オリジナルのGASコードを自分で生成してみよう

ステップ2で使用したGASコードは、AI(ChatGPT・Geminiなど)に「APIドキュメント(JSON)+以下プロンプト」を渡すだけで簡単に生成できます。

ご自身の目的に合わせて【データ取得における条件】や【スプレッドシートに出力する項目】を書き換えてみましょう。

プロンプト

ラッコキーワードAPIの仕様に基づき、Google Apps Script(GAS)のコードを作成してください。

【やりたいこと】
ラッコキーワードAPIを使って、関連キーワードを取得し、スプレッドシートに出力したいです。

【データ取得における条件】
・取得件数:100件
・並び順:月間検索数が多い順

【スプレッドシートに出力する項目】
・キーワード
・月間検索数

【期待する動作】
・スクリプトを実行すると、画面にキーワードを入力する枠が表示される
・キーワードを入力するとデータを取得し、現在のシートの内容を上書きして結果を表示する
・1行目の見出し(ヘッダー)はスクリプトで自動的に作ってほしい
・GASはスプレッドシートのメニュー「マクロ」から実行できるようにする

【その他のお願い】
・APIキーを入れる場所は、コードの一番上に「YOUR_API_KEY_HERE」のように分かりやすく定義し、後ほど手動で書き換えやすいようにすること
・関数名や変数名などは、AI側で分かりやすいものにしてください
エラーが出た場合の対処法
GASコードを実行後エラーが出た場合は、以下の方法を試してみましょう。

  • エラー内容をAIに相談する:Apps Scriptエディタの「実行ログ」に表示されたエラー文をそのままコピペするか、エラー画面のスクリーンショットを添付して、生成元のAIに「このエラーを修正してください」と依頼します。
    ※スクリーンショットの添付は、画像入力に対応したAI(Gemini・ChatGPTなど)で利用可能です。
  • APIドキュメントを再度添付する:APIエラー(ステータスコード400・401など)が原因と思われる場合は、APIドキュメント(JSON)を再添付し「仕様に沿って修正してください」と依頼するとスムーズです。

プロンプトの条件を少し変えるだけで、自分の用途にぴったり合ったオリジナルのGASコードを作れます。
まずは取得件数や並び順など、簡単な部分から書き換えて試してみましょう!

Googleスプレッドシート×ラッコキーワードAPI連携後の活用方法

Googleスプレッドシート×ラッコキーワードAPIの連携ができれば、日々のキーワード収集や記事のリライトなど、一連のワークフローを効率化できます。

ここでは、初心者の方でもすぐに実践できる、具体的な活用方法を2つご紹介します。

①サジェストキーワードの自動取得でブルーオーシャンキーワードを発掘

サジェストキーワードでは、検索したキーワードに関連するキーワードを取得できるため、ネタ探しに便利です。

特に「出現時期フィルタ」を使うことで、ラッコキーワード上で出現して間もないブルーオーシャンキーワードを抽出することができます。

ブルーオーシャンキーワードとは、競合がまだ少なく、比較的上位表示を狙いやすいような新しいキーワードのことです。

「出現時期が新しいキーワードの月間検索数」について

「月間検索数」はラッコキーワードに反映されるまで最大1ヶ月ほどのラグが生じます。
そのため、出現時期が新しいキーワードほど未反映(0表示)の可能性が高いです。
実際にそのキーワードが検索されているか確実に確認したい場合は、日別でデータ反映されるGoogleトレンドをご活用ください。

GASのトリガー機能を使用すると、決まったタイミングで自動的にサジェストキーワードを抽出することが可能です。
まずは下記の手順に沿ってサジェストキーワードを自動取得してみましょう!

【手順】

新しいGoogleスプレッドシートを用意し、以下のGASコードを保存します。

JavaScript

// ==========================================
// 設定項目
// ==========================================
// ラッコキーワードのAPIキーを設定してください
const RAKKO_API_KEY = "YOUR_API_KEY_HERE";

// ==========================================
// メイン処理(トリガー設定用)
// ==========================================
function fetchAndAppendSuggestKeywords() {
  try {
    const ss = SpreadsheetApp.getActiveSpreadsheet();

    // 先頭シート(デフォルトシート)を取得
    const inputSheet = ss.getSheets()[0];

    if (!inputSheet) {
      throw new Error("シートが存在しません。");
    }

    // A1セルのキーワードを取得
    const targetKeyword = inputSheet.getRange("A1").getValue();

    if (!targetKeyword) {
      throw new Error(
        `シート「${inputSheet.getName()}」のA1セルにキーワードを入力してください`
      );
    }

    // 「出力シート」を取得(存在しない場合は新規作成)
    let outputSheet = ss.getSheetByName("出力シート");

    if (!outputSheet) {
      outputSheet = ss.insertSheet("出力シート");
    }

    // 出力シートが空の場合はヘッダーを作成
    if (outputSheet.getLastRow() === 0) {
      outputSheet.appendRow([
        "取得日時",
        "検索キーワード",
        "サジェストキーワード",
        "サジェストクラス",
        "SEO難易度",
        "月間検索数",
        "出現時期"
      ]);
    }

    // 既存キーワード取得(C列)
    const lastRow = outputSheet.getLastRow();
    let existingKeywords = new Set();

    if (lastRow > 1) {
      const cValues = outputSheet
        .getRange(2, 3, lastRow - 1, 1)
        .getValues();

      existingKeywords = new Set(
        cValues.flat().filter(String)
      );
    }

    // APIリクエスト
    const payload = {
      keyword: String(targetKeyword),
      increaseKeyword: true,
      filter: {
        firstSeenRange: {
          include: "last_7_days"
        },
        searchVolume: {
          max: 10000
        }
      },
      sortBy: "firstSeenRange",
      orderBy: "desc",
      limit: 100
    };

    const options = {
      method: "post",
      headers: {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "X-API-Key": RAKKO_API_KEY
      },
      payload: JSON.stringify(payload),
      muteHttpExceptions: true
    };

    const url = "https://api.rakkokeyword.com/v1/suggest-keywords";

    const response = UrlFetchApp.fetch(url, options);

    const statusCode = response.getResponseCode();
    const responseText = response.getContentText();

    if (statusCode !== 200) {
      throw new Error(
        `APIエラー: ステータスコード ${statusCode}\n${responseText}`
      );
    }

    const json = JSON.parse(responseText);

    if (!json.result) {
      throw new Error(
        `APIリクエストが失敗しました。\n${JSON.stringify(json.errors)}`
      );
    }

    const items = json?.data?.items || [];

    const rowsToAppend = [];

    const now = Utilities.formatDate(
      new Date(),
      Session.getScriptTimeZone(),
      "yyyy/MM/dd HH:mm:ss"
    );

    items.forEach(item => {
      const suggestKeyword = item.keyword;

      if (!existingKeywords.has(suggestKeyword)) {
        rowsToAppend.push([
          now,
          targetKeyword,
          suggestKeyword,
          item.suggestClass,
          item.metrics?.seoDifficulty ?? "",
          item.metrics?.searchVolume ?? "",
          item.metrics?.firstSeenRange ?? ""
        ]);

        existingKeywords.add(suggestKeyword);
      }
    });

    if (rowsToAppend.length > 0) {
      outputSheet
        .getRange(
          outputSheet.getLastRow() + 1,
          1,
          rowsToAppend.length,
          rowsToAppend[0].length
        )
        .setValues(rowsToAppend);

      Logger.log(
        `${rowsToAppend.length}件のデータを「出力シート」に追記しました。`
      );
    } else {
      Logger.log(
        "新しいサジェストキーワードはありませんでした(すべて重複、または条件に一致する結果が0件)。"
      );
    }

  } catch (e) {
    Logger.log(
      "スクリプトの実行中にエラーが発生しました: " + e.message
    );

    if (e.stack) {
      Logger.log(e.stack);
    }

    // トリガー実行履歴で「失敗」にする
    throw e;
  }
}

その後、以下の手順に沿って実行するとサジェストキーワードを自動取得できます。

※クリックすると画像を拡大できます

STEP 1GoogleスプレッドシートのA1セルに、サジェストキーワードを取得したいキーワード(例:スマホ)を入力します。
STEP 2「拡張機能」>「Apps Script」を開き、左メニューから「トリガー」を選択します。
STEP 3画面右下にある「+ トリガーを追加」ボタンを押下します。
STEP 4設定画面で以下の表に記載がある通りに入力し、「保存」をクリックします。
サジェストキーワードが自動取得された画面
STEP 5指定したタイミングに自動でGASが実行され、スプレッドシート上にサジェストキーワードが取得されます。

項目 設定内容
実行する関数を選択 実行したい関数名(例:fetchAndAppendSuggestKeywords)
実行するデプロイを選択 Head
イベントのソースを選択 時間主導型
時間ベースのトリガーのタイプを選択 日付ベースのタイマー
※GASを実行するタイミングを選択
時刻を選択 午前5時~6時
※GASが実行される時間帯を選択
注意

作成したトリガーを有効のままにしておくと、意図せずクレジットを大量消費してしまう恐れがあります。使用しないトリガーは必ず削除するようにしましょう。

具体的な活用事例
  • 新商品の発売直後に、ユーザーがどんな疑問を持って検索しているかをいち早くキャッチしたいとき
  • 季節商戦やトレンドイベントで急上昇している関連語を見逃したくないとき
  • 競合が手をつけていないニッチなテーマで先行して記事を投入したいとき

新しいニーズやトレンドワードをいち早くキャッチし、効率よく上位表示を狙っていきましょう!

※参考:GASコードを生成したプロンプト

プロンプト

ラッコキーワードAPIの仕様に基づき、Google Apps Script(GAS)のコードを作成してください。

【やりたいこと】
ラッコキーワードAPIを使って「サジェストキーワード」を取得し、Googleスプレッドシートに自動で一括取得・追記する処理を実装したいです。トリガーでの定期実行を想定しています。

【データの取得条件】
・オプション:[キーワード増量オプションを使う]
・フィルタ:[出現時期7日以内]、[月間検索ボリューム10000以下]
・並び順:[出現時期の降順]

【検索キーワード】
・A1セルの値を検索キーワードとして使用してください

【出力結果について】
・別シート(「出力シート」という名前をつけて)に結果を出力してください
・既存のデータを上書きせず、一番最後の行の下に追記していってください
・すでに出力シートに存在するサジェストキーワードは除外し、重複して追記しないようにしてください

【出力する項目】
・A列:取得日時(yyyy/MM/dd HH:mm:ss)
・B列:検索キーワード(シートA1セルの値)
・C列:サジェストキーワード
・[D列:サジェスト区分]
・[E列:SEO難易度]
・[F列:月間検索数]
・[G列:出現時期]

【その他のお願い】
・APIキーを入れる場所は、コードの一番上に「YOUR_API_KEY_HERE」と分かりやすく定義してください

②共起語・LSI/PAA・見出し抽出でコンテンツの網羅性を高める

記事のリライトを行う際は「共起語」「LSI/PAA」「見出し抽出」といった機能の活用がおすすめです。

ユーザーの潜在的な検索意図や疑問、上位表示されている競合のタイトル・見出しを取り入れることで、コンテンツの網羅性を高めることができます。

まずは下記の手順に沿って、実際に記事をリライトしてみましょう。

【手順】

新しいGoogleスプレッドシートを用意し、以下のGASコードを保存します。

JavaScript

const API_KEY = "YOUR_API_KEY_HERE";

function runRewriteInfoFetch() {
  const ui = SpreadsheetApp.getUi();

  // 1. モーダルで入力を受け付ける
  const keywordPrompt = ui.prompt('リライト情報取得', 'キーワードを入力してください', ui.ButtonSet.OK_CANCEL);
  if (keywordPrompt.getSelectedButton() !== ui.Button.OK) return;
  const keyword = keywordPrompt.getResponseText().trim();
  if (!keyword) {
    ui.alert('キーワードが入力されていません。処理を中断します。');
    return;
  }

  const urlPrompt = ui.prompt('リライト情報取得', 'リライト対象記事のURLを入力してください', ui.ButtonSet.OK_CANCEL);
  if (urlPrompt.getSelectedButton() !== ui.Button.OK) return;
  const url = urlPrompt.getResponseText().trim();
  if (!url) {
    ui.alert('URLが入力されていません。処理を中断します。');
    return;
  }

  // 2. シートの準備(存在しなければ作成、存在すればクリア)
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheetNames = ["共起語", "LSI/PAA", "見出し抽出", "リライト対象記事"];
  const sheets = {};

  sheetNames.forEach(name => {
    let sheet = ss.getSheetByName(name);
    if (!sheet) {
      sheet = ss.insertSheet(name);
    } else {
      sheet.clear();
    }
    sheets[name] = sheet;
  });

  // APIリクエストの共通オプション
  const options = {
    method: "post",
    headers: {
      "Content-Type": "application/json",
      "Accept": "application/json",
      "X-API-Key": API_KEY
    },
    muteHttpExceptions: true
  };

  // --- ① 共起語 ---
  try {
    const coOccPayload = { keyword: keyword };
    const coOccRes = UrlFetchApp.fetch("https://api.rakkokeyword.com/v1/co-occurrence", {
      ...options,
      payload: JSON.stringify(coOccPayload)
    });

    sheets["共起語"].getRange("A1").setValue(keyword);
    if (coOccRes.getResponseCode() === 200) {
      const data = JSON.parse(coOccRes.getContentText()).data;
      if (data && data.items && data.items.length > 0) {
        const rows = data.items.map(item => [item.word]);
        sheets["共起語"].getRange(1, 2, rows.length, 1).setValues(rows);
      }
    }
  } catch (e) {
    sheets["共起語"].getRange("A2").setValue("取得エラー: " + e.message);
  }

  // --- ② LSI/PAA ---
  try {
    const otherPayload = { keyword: keyword };
    const otherRes = UrlFetchApp.fetch("https://api.rakkokeyword.com/v1/other-keywords", {
      ...options,
      payload: JSON.stringify(otherPayload)
    });

    sheets["LSI/PAA"].getRange("A1").setValue(keyword);
    if (otherRes.getResponseCode() === 200) {
      const data = JSON.parse(otherRes.getContentText()).data;
      if (data && data.items && data.items.length > 0) {
        const rows = data.items.map(item => {
          const typeLabel = item.type.toUpperCase();
          const text = item.type === "lsi" ? item.keyword : item.question;
          return [typeLabel, text];
        });
        sheets["LSI/PAA"].getRange(1, 2, rows.length, 2).setValues(rows);
      }
    }
  } catch (e) {
    sheets["LSI/PAA"].getRange("A2").setValue("取得エラー: " + e.message);
  }

  // --- ③ 見出し抽出 ---
  try {
    const headlinePayload = {
      keyword: keyword,
      lessCharacters: true, // 文字数1000未満のページを除外
      h1: true,
      h2: true,
      h3: true,
      h4: false, // h4タグを除外
      h5: false, // h5タグを除外
      h6: false, // h6タグを除外
      limit: 10  // 取得件数を上位10件
    };
    const headlineRes = UrlFetchApp.fetch("https://api.rakkokeyword.com/v1/headline", {
      ...options,
      payload: JSON.stringify(headlinePayload)
    });

    sheets["見出し抽出"].getRange("A1").setValue(keyword);
    if (headlineRes.getResponseCode() === 200) {
      const data = JSON.parse(headlineRes.getContentText()).data;
      if (data && data.items && data.items.length > 0) {
        const rows = [];
        data.items.forEach(pageItem => {
          const rank = pageItem.metrics.position + "位";
          const title = pageItem.page.title;
          if (pageItem.headlines && pageItem.headlines.length > 0) {
            pageItem.headlines.forEach(hl => {
              rows.push([rank, title, hl.level.toUpperCase(), hl.text]);
            });
          }
        });
        if (rows.length > 0) {
          sheets["見出し抽出"].getRange(1, 2, rows.length, 4).setValues(rows);
        }
      }
    }
  } catch (e) {
    sheets["見出し抽出"].getRange("A2").setValue("取得エラー: " + e.message);
  }

  // --- ④ リライト対象記事(スクレイピング) ---
  try {
    sheets["リライト対象記事"].getRange("A1").setValue(url);
    const html = UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getContentText();

    // 不要なタグ(script, style)を除去
    let cleanHtml = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "")
                        .replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, "");

    // 見出しタグ(h1~h3)とその中のコンテンツ(次の見出しタグまたは終了タグまで)を抽出する正規表現
    const regex = /<h([1-3])[^>]*>(.*?)<\/h\1>([\s\S]*?)(?=<h[1-6][^>]*>|<\/body>|$)/gi;
    let match;
    const scrapeRows = [];

    while ((match = regex.exec(cleanHtml)) !== null) {
      let level = "h" + match[1];

      // HTMLタグを除去し、特殊文字をデコードしてプレーンテキスト化
      let headingText = decodeHtmlEntities(match[2].replace(/<[^>]+>/g, '').trim());
      // 本文からHTMLタグを除去し、連続する空白・改行を1つのスペースに圧縮
      let contentText = decodeHtmlEntities(match[3].replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim());

      if (headingText || contentText) {
        scrapeRows.push([level, headingText, contentText]);
      }
    }

    if (scrapeRows.length > 0) {
      sheets["リライト対象記事"].getRange(1, 2, scrapeRows.length, 3).setValues(scrapeRows);
    } else {
      sheets["リライト対象記事"].getRange("B1").setValue("見出し(h1~h3)が取得できませんでした。");
    }
  } catch (e) {
    sheets["リライト対象記事"].getRange("A2").setValue("スクレイピングエラー: " + e.message);
  }

  ui.alert('処理が完了しました!各シートをご確認ください。');
}

// 簡単なHTMLエンティティデコード関数
function decodeHtmlEntities(text) {
  if (!text) return "";
  return text.replace(/&amp;/g, '&')
             .replace(/&lt;/g, '<')
             .replace(/&gt;/g, '>')
             .replace(/&quot;/g, '"')
             .replace(/&#39;/g, "'")
             .replace(/&nbsp;/g, ' ');
}

その後、以下の手順に沿って実行すると記事のリライト案が出力されます。

※クリックすると画像を拡大できます

STEP 1GASを実行すると入力モーダルが表示されるので、今回リライトする記事のSEOキーワード(例:ブログ 始め方)と記事URL(例:https://rakkokeyword.com/techo/how-to-start-blog/)を入力します。
共起語・LSI/PAA・見出し抽出が取得された画面
STEP 2Googleスプレッドシートに「共起語」「LSI/PAA」「見出し抽出」「リライト対象記事」の4シートが自動取得されます。
STEP 3Gemini左下の+ボタン>「ドライブから追加」を押下後、STEP2のGoogleスプレッドシートを選択→挿入します。その後以下のリライト指示プロンプトを添付し、実行します。
Geminiがリライト案を出力
STEP 4下記のリライト指示プロンプトを実行すると、Geminiが記事のリライト案を出力してくれます。

プロンプト

添付したGoogleスプレッドシートのデータを分析して、検索上位を狙える「記事のリライト案」を作成してください。

【やりたいこと】
今の記事の自然な流れや良いところは残しつつ、足りない情報を追加して、読者の疑問をしっかり解決できる記事に書き直したいです。

【入力データについて】
添付したGoogleスプレッドシート内にある、以下のデータを使って分析してください。

・現在の記事データ:リライト対象記事シート
・APIで抽出したデータ:共起語、LSI/PAA、見出し抽出シート

【リライトについて】
以下手順で実施してください

①2つのデータを比べて「今の記事に足りないけれど、絶対に書くべき重要なトピック」を見つけ出す
②見つけ出したトピックをもとに見出し(h2、h3)を追加・修正する
③②で追加・修正した見出しの本文を生成する

既存の記事の文章で活かせる部分は残しつつ、新しく追加する情報とスムーズに繋がるよう、全体の文脈や表現を整えてください。

【出力結果について】
以下の順番と形式で出力してください。

①分析まとめ
今の記事に何が足りなかったのか、どのような意図で要素や文章を追加・修正したのかを簡単に解説してください。

②リライト後の記事(構成+文章)
1.新しく追加・修正した見出しについて
・見出し前には必ず(h1~h3)をつけて作成してください
2.既存の文章について
・追加や修正が必要ない場合は全文出力せず、[既存の文章]と出力してください

新しく追加・修正した見出しや文章の箇所が一目でわかるように「✨新規追加」マークをつけてください

【その他のお願い】
・ライバルサイトが書いているトピックや、読者のよくある疑問は必ず網羅し、読者が納得できる丁寧な文章で解説してください。
MEMO

GeminiはGoogleスプレッドシートを直接読み込むことが可能です。
それ以外のAI(ChatGPT・Claudeなど)はスプレッドシートを直接読み込めず、「CSVをダウンロード→貼り付け」という追加手順が発生してしまいます。

STEP3・4は、サイドパネルのGeminiを活用するのもオススメです!
具体的な活用事例
  • 既存記事のPVが伸び悩んでいるとき
  • 競合上位サイトの見出し構成を取り入れて、リライトの方針を立てたいとき
  • 読者からの問い合わせやコメントに、よくある質問セクションを追加して対策したいとき

いずれの活用方法も「取得したデータをそのままAIに渡すだけ」でスムーズに作業できます。
Googleスプレッドシート×ラッコキーワードAPIを上手く活用し、より効率的に作業を進めましょう!

※参考:GASコードを生成したプロンプト

プロンプト

ラッコキーワードAPI仕様に基づき、Google Apps Script(GAS)のコードを作成してください。

【やりたいこと】
記事のリライトに使う情報を、まとめてGoogleスプレッドシートに取得したいです。

【GAS実行時のルール】
実行時は以下をモーダル入力できるようにしてください。
・キーワード
・リライト対象記事のURL
GASを実行する前に必ず既存シートのデータをクリアしてください。

【取得・出力したい内容】
①共起語
②LSI/PAA
③見出し抽出
・オプション:[文字数1000未満のページを除外]、[h4~h6タグの見出しを除外]、[取得件数を上位10件]
④リライト対象記事(URLからスクレイピング)
それぞれ別のシートに出力してください。

【出力する項目】
■「共起語」シート
・A1セル:対象のキーワード
・B列:質問テキスト

■「LSI/PAA」シート
 * A1セル:対象のキーワード
・[B列:種類(LSI または PAA)]
・[C列:キーワードまたは質問テキスト]

■「見出し抽出」シート
・A1セル:対象のキーワード
・[B列:順位(〇位)]
・[C列:ページタイトル]
・[D列:見出しレベル(大文字)]
・[E列:見出しテキスト]

■「リライト対象記事」シート
・A1セル:対象のURL
・[B列:見出しレベル(h1, h2, h3)]
・[C列:見出しテキスト(HTMLタグを除去したプレーンテキスト)]
・[D列:見出し内文章(HTMLタグを除去したプレーンテキスト)]

【その他】
・APIキーはコードの一番上に「YOUR_API_KEY_HERE」として定義してください
・カスタムメニューは作らないでください

よくある質問

APIキーを入力したのにエラーが出ます

APIキーの前後に余分な空白が入っていたり、ダブルクォーテーション(”)を含めてコピーしている可能性があります。

コードの「YOUR_API_KEY_HERE」の部分のみを置き換え、APIキー文字列だけが残るようにしてください。

それでも解決しない場合は、ラッコキーワードの契約管理画面でAPIキーが有効になっているかご確認ください。

GASのトリガー実行が動かない場合はどうすればよいですか?

まずはApps Scriptエディタの「実行ログ」を確認してください。

例えば「入力シートのA1セルにキーワードを入力して再実行してください」というエラーログが出ている場合は、入力シートのシート名やA1セルの内容を再確認します。

MEMO

どうしてもエラーが解消できないという場合は、ご自身が利用しているAIにエラーログを入力して聞くのがオススメです。APIエラーのログが出ている場合は、こちらのAPIドキュメントで仕様をご確認ください。

無料プランでもこの方法は使えますか?

いいえ、ラッコキーワードAPIはスタンダードプラン(月額2,475円〜)以上で利用可能です。

フリープラン・エントリープラン・ライトプラン・旧プランではご利用いただけません。

まとめ

本記事では、GoogleスプレッドシートとラッコキーワードAPIを連携させて、メディア運営作業を効率化する方法を紹介しました。

「API連携」は一見難しそうに感じるかもしれませんが、裏側の仕組み(GASのコード)はAIに生成させるため、コピー&ペーストだけで簡単に連携できます。

さらに、取得したデータをAIに渡せば記事のリライト案を作成してくれるなど、効率的に作業することが可能です。

日々の手作業を効率化し、メディア運営の改善に役立てていきましょう!

ラッコキーワードAPIは、スタンダードプラン(月額2,475円〜)から使えます。まずは気になる活用方法を1つ試すところから始めてみませんか?

ラッコキーワードAPIを使ってみる

お悩みは解決しましたか?
この記事を読んでも解決しなかった場合は、右下の【AIに質問】ボタンからお気軽にご相談ください。