はじめに
AI界隈の進化が速すぎて、毎日の情報収集が追いつかないことはありませんか? 特に「AIエージェント」「デザイン」「コーディング」など、自分が関心のある分野に絞って効率よく情報を得たいと思い、寝ている間に勝手にニュースを集め、要約し、PDFレポートにしてLINEに届けてくれる仕組みをGoogle Apps Script (GAS) で自作しました。
今回は、その構築手順と、開発中にハマった「Geminiのモデル指定エラー(404/429)」の解決策も含めて共有します。
※これは全てGemini 3 proで生成したものです。
作ったもの
毎朝7時に自動で実行され、以下のフローで処理を行います。
- 収集: GoogleニュースのRSSから「AI (エージェント OR デザイン OR コーディング)」の記事を収集。
- 思考: Googleの生成AI Gemini が、記事の内容をビジネスパーソン向けに要約・構造化。
- 加工: Googleドキュメント経由でPDFファイルを自動生成。
- 配信: LINE Messaging API を使って、自分のLINEにPDFのリンクをプッシュ通知。
使用した技術スタック
- Google Apps Script (GAS): サーバーレスで無料。今回のハブになります。
- Gemini API: ニュースの要約担当。無料枠で利用可能。
- LINE Messaging API: 通知担当。以前のLINE Notifyが終了予定のため、こちらを使用。
手順1:各APIキーの取得
開発には以下の3つの「鍵」が必要です。
-
LINE Channel Access Token (長期):
- LINE Developers Consoleで「Messaging APIチャネル」を作成し、発行します。
- ※注意:短い「Channel Secret」ではなく、めっちゃ長い「アクセストークン」の方を使います(ここでハマりました)。

LINE公式アカウントを作成するから、必要な情報を入力して公式アカウントを作成します。
その後、管理画面>右上の設定>Messaging APIの有効化します。

その後、LINE Developper Consoleに戻り、アクセストークンを取得します。


一番下までスクロールして、

-
LINE User ID:
-
Gemini API Key:
- Google AI Studioで発行します。
手順2:Google DriveでPDFを保存するフォルダを準備
手順3:GASの実装
Apps Scriptで新規にスクリプトを作成し、以下のコードを記述します。
// --- 設定エリア ---
const LINE_CHANNEL_ACCESS_TOKEN = 'ここにLINEチャンネルアクセストークンを貼り付け';
const USER_ID = 'ここにあなたのLINEユーザーIDを貼り付け';
const GEMINI_API_KEY = 'ここにGemini_APIキーを貼り付け';
const FOLDER_ID = 'PDFを保存するGoogleドライブのフォルダID';
// ------------------------------------------
function main() {
console.log("処理を開始します...");
// 1. ニュースを取得
const newsText = fetchAiNews();
if (!newsText) return;
// 2. Geminiで要約
const summary = summarizeWithGemini(newsText);
if (!summary) return;
// 3. PDF作成
const pdfUrl = createPdf(summary);
// 4. LINE送信
sendToLine(summary, pdfUrl);
}
// RSSからニュースを取得(関心分野に絞り込み)
function fetchAiNews() {
const query = 'AI (エージェント OR デザイン OR コーディング)';
const encodedQuery = encodeURIComponent(query);
const feedUrl = `https://news.google.com/rss/search?q=${encodedQuery}&hl=ja&gl=JP&ceid=JP:ja`;
try {
const xml = UrlFetchApp.fetch(feedUrl).getContentText();
const document = XmlService.parse(xml);
const items = document.getRootElement().getChild('channel').getChildren('item');
let textData = "";
// 上位7件を取得
for (let i = 0; i < Math.min(7, items.length); i++) {
const title = items[i].getChildText('title');
const link = items[i].getChildText('link');
textData += `記事${i+1}: ${title} (${link})\n`;
}
return textData;
} catch (e) {
console.error("RSS取得エラー: " + e);
return null;
}
}
// Gemini APIで要約
function summarizeWithGemini(text) {
// モデル名の指定(ここが重要!)
// バージョン指定エラーを避けるため、最新の安定版へのエイリアスを使用
const model = 'gemini-flash-latest';
const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${GEMINI_API_KEY}`;
const prompt = `
以下のニュース記事リストから、特に「AIエージェント」「デザイン(UI/UXや生成デザイン)」「コーディング・開発」に関連する情報を中心に抽出し、忙しいビジネスパーソン向けに要約してください。
# 制約
- 全体で500文字程度にまとめること。
- 上記の関心分野ごとに見出しを分けて整理すること。
- PDFにするので、読みやすい構成にすること。
# ニュースリスト
${text}
`;
const payload = {
"contents": [{"parts": [{"text": prompt}]}]
};
const options = {
'method': 'post',
'contentType': 'application/json',
'payload': JSON.stringify(payload),
'muteHttpExceptions': true
};
try {
const response = UrlFetchApp.fetch(url, options);
const json = JSON.parse(response.getContentText());
if (json.candidates && json.candidates[0].content) {
return json.candidates[0].content.parts[0].text;
} else {
console.error("生成失敗: " + response.getContentText());
return null;
}
} catch (e) {
console.error("通信エラー: " + e);
return null;
}
}
// Googleドキュメント作成 → PDF化
function createPdf(content) {
const dateStr = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy-MM-dd');
const docName = `AIトレンドまとめ_${dateStr}`;
// 一時ドキュメント作成
const doc = DocumentApp.create(docName);
const body = doc.getBody();
body.appendParagraph(docName).setHeading(DocumentApp.ParagraphHeading.HEADING1);
body.appendParagraph(content);
doc.saveAndClose();
// PDF変換して保存
const folder = DriveApp.getFolderById(FOLDER_ID);
const pdfBlob = doc.getAs('application/pdf');
const file = folder.createFile(pdfBlob);
// ゴミ掃除
DriveApp.getFileById(doc.getId()).setTrashed(true);
return file.getUrl();
}
// LINE Messaging APIでプッシュ通知
function sendToLine(summary, pdfUrl) {
const url = 'https://api.line.me/v2/bot/message/push';
const payload = {
'to': USER_ID,
'messages': [
{
'type': 'text',
'text': `【今日のAIトレンド】\n自動まとめが完了しました。\n\n▼PDFレポートはこちら\n${pdfUrl}`
}
]
};
const options = {
'method': 'post',
'headers': {
'Authorization': 'Bearer ' + LINE_CHANNEL_ACCESS_TOKEN,
'Content-Type': 'application/json'
},
'payload': JSON.stringify(payload),
'muteHttpExceptions': true
};
UrlFetchApp.fetch(url, options);
}
トリガーを設定して、毎朝6時に通知が来るように設定
完成形
開発中にハマったポイント(Troubleshooting)
今回の開発で一番時間を溶かしたのは、Gemini APIのモデル指定とQuota(割り当て)のエラーでした。
- 「404 Not Found」エラー
- 現象: models/gemini-pro や models/gemini-1.5-flash を指定すると 404 Not Found が返ってくる。
- 原因: APIキーを作成したプロジェクトや時期によって、使用可能なモデル名(またはバージョン)が異なる場合があるようです。特に v1 と v1beta のURLの違いも影響します。
- 対策: モデル名を決め打ちせず、gemini-flash-latest というエイリアス(その時点での最新安定版Flashモデルを指す名前)を使うことで解決しました。
- 「429 Resource Exhausted」エラー
- 現象: 最新の gemini-2.0-flash-exp などを使おうとすると、limit: 0 と言われて弾かれる。
- 原因: 発表されたばかりの実験的モデルや特定のモデルは、無料枠(Free Tier)ではアクセス権限が開放されていないことがあります。
- 対策: 素直に安定版のモデル(Flashなど)を使うのが吉です。
さいごに
これで、毎朝7時に自分の関心領域(AIエージェント、デザイン、コーディング)に特化したニュースが、綺麗にPDFにまとまってLINEに届くようになりました。
GASの「トリガー」機能を使えば、完全放置で運用できます。 「情報収集を自動化したい」と考えているエンジニアの方は、ぜひ試してみてください。






