GASでAPIキーや設定値を
PropertiesServiceに安全に保存する方法
APIキーやWebhook URLをコードに直接書くと、共有した瞬間に漏れる恐れがあります。PropertiesService(設定値をキーと値で保存するGASの標準機能)を使い、機密値をコードから切り離す方法を解説します。
Table of Contents
APIキーを直書きしてはいけない理由
GASからClaude APIやSlackなどの外部サービスを呼ぶとき、APIキーやWebhook URLが必要になります。 これらをコードに直接書く(ハードコードする)と、次のような場面で漏れる危険があります。
スクリプトの共有
編集権限を渡した相手に、キーの文字列がそのまま見えてしまう
コードのコピー
質問サイトやチャットにコードを貼るとき、キーごと貼ってしまう
リポジトリへの流出
claspなどでコードをGitHubに上げると、キーが公開されてしまう
退職・引き継ぎ
キーがコードに埋まっていると、差し替えの範囲がわからなくなる
PropertiesServiceにキーを預けておけば、コード本体には値が残りません。 値の閲覧にはスクリプトの権限が必要になるため、共有時のリスクを大きく下げられます。
PropertiesServiceの基本(保存と取得)
まずは一番よく使う「スクリプトプロパティ」からAPIキーを取り出す例です。 値はgetProperty()で取得します。未設定のときにわかりやすいエラーを出しておくと、後々のトラブルを防げます。
// スクリプトプロパティからAPIキーを取り出す
function getApiKey() {
const props = PropertiesService.getScriptProperties();
const apiKey = props.getProperty("CLAUDE_API_KEY");
if (!apiKey) {
throw new Error(
"CLAUDE_API_KEY が未設定です。プロジェクトの設定から登録してください。"
);
}
return apiKey;
}
// 使う側は関数を呼ぶだけ。コードにキーの文字列が残らない
function callApiExample() {
const apiKey = getApiKey();
const res = UrlFetchApp.fetch("https://api.example.com/v1/messages", {
method: "post",
headers: { "x-api-key": apiKey },
muteHttpExceptions: true,
});
Logger.log(res.getResponseCode());
}APIキーそのものは、スクリプトエディタの「プロジェクトの設定」→「スクリプト プロパティ」から手入力で登録します。 こうすればコード上にキーの文字列が一切残りません。
コードから設定値を一括登録する
機密ではない設定(スプレッドシートIDや実行時刻など)は、setProperties()でまとめて登録すると楽です。初期セットアップ用の関数を作り、一度だけ実行します。
// 一度だけ実行して設定値をまとめて登録する
// (APIキーのような機密値は「プロジェクトの設定」画面から
// 手入力するほうが、コードに値が残らず安全)
function setupProperties() {
const props = PropertiesService.getScriptProperties();
props.setProperties({
SLACK_WEBHOOK_URL: "https://hooks.slack.com/services/xxx/yyy/zzz",
SPREADSHEET_ID: "1AbcDefGhijkLmnOpqrStuvWxyz",
NOTIFY_HOUR: "9",
});
Logger.log("設定値を登録しました");
}
// 登録済みの全キーを確認する
function showAllProperties() {
const props = PropertiesService.getScriptProperties();
Logger.log(JSON.stringify(props.getProperties(), null, 2));
}値はすべて文字列として保存される点に注意してください。数値やフラグは取り出したあとにNumber()や比較で変換します。APIキーのような機密値はこの関数には書かず、画面から手入力しましょう。
3つのストアの使い分け
PropertiesServiceには保存先が3種類あります。誰と値を共有するかで選びます。
スクリプトプロパティ
スクリプト全体で共通。誰が実行しても同じ値。APIキー・共通設定に最適。
ユーザープロパティ
実行したユーザーごとに別々に保存され、本人にしか見えない。個人トークンや個人設定向け。
ドキュメントプロパティ
紐づいたスプレッドシート/ドキュメント単位で保存。コンテナ(対象ファイル)ごとの設定向け。
// スクリプトプロパティ: スクリプト全体で共通。誰が実行しても同じ
const scriptProps = PropertiesService.getScriptProperties();
// ユーザープロパティ: 実行したユーザーごとに別々。本人にしか見えない
const userProps = PropertiesService.getUserProperties();
// ドキュメントプロパティ: 紐づいたシート/ドキュメント単位で保存
const docProps = PropertiesService.getDocumentProperties();
// 例: 個人ごとの通知先はユーザープロパティに保存する
function saveMyNotifyEmail(email) {
PropertiesService.getUserProperties()
.setProperty("MY_NOTIFY_EMAIL", email);
}
function getMyNotifyEmail() {
return PropertiesService.getUserProperties()
.getProperty("MY_NOTIFY_EMAIL");
}複数の設定をJSONでまとめて管理する
設定項目が増えてくると、キーが散らかりがちです。関連する設定を1つのオブジェクトにまとめ、JSON.stringify()で文字列化して1キーに保存すると管理が楽になります。初期値とマージすれば、項目が増えても既存データを壊しません。
const DEFAULT_CONFIG = {
notifyHour: 9,
batchSize: 20,
enableSlack: true,
targetSheet: "受付データ",
};
// 設定をJSONでまとめて保存・取得する
function saveConfig(config) {
PropertiesService.getScriptProperties()
.setProperty("APP_CONFIG", JSON.stringify(config));
}
function loadConfig() {
const raw = PropertiesService.getScriptProperties()
.getProperty("APP_CONFIG");
// 未設定なら初期値、あれば初期値に上書きマージ
if (!raw) return { ...DEFAULT_CONFIG };
return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
}
// 使用例: 足りない項目は初期値で補われる
function job() {
const config = loadConfig();
Logger.log(config.batchSize); // 未保存でも 20 が返る
}設定用シートと同期する
非エンジニアの担当者が設定を変えたい場合は、スプレッドシートに「設定」シートを用意し、 その内容をスクリプトプロパティへ反映する方法が便利です。 コードを触らずに値を変更できます。
// 「設定」シートのA列=キー / B列=値 を
// スクリプトプロパティに反映する。非エンジニアでも編集しやすい
function syncConfigFromSheet() {
const sheet = SpreadsheetApp.getActive().getSheetByName("設定");
const rows = sheet.getDataRange().getValues().slice(1); // ヘッダー除く
const map = {};
rows.forEach(([key, value]) => {
if (key) map[String(key).trim()] = String(value);
});
PropertiesService.getScriptProperties().setProperties(map, true);
Logger.log(Object.keys(map).length + " 件の設定を反映しました");
}setProperties(map, true)の第2引数をtrueにすると、シートに無いキーは削除され、シートの内容と完全に一致させられます。ただしAPIキーは シートに書かず、画面から登録した値を消さないよう、機密値は別キーで管理するのが安全です。
ハードコードからの移行と注意点
既存のスクリプトに直書きされたキーは、PropertiesServiceへ移すだけで安全性が上がります。 移行のBefore/Afterと、使わなくなった値の削除は次のとおりです。
// Before: キーがコードに直書きされている(危険)
function badExample() {
const apiKey = "sk-ant-xxxxxxxxxxxxxxxx"; // 共有すると漏れる
// ...
}
// After: PropertiesServiceから取得する
function goodExample() {
const apiKey = PropertiesService.getScriptProperties()
.getProperty("CLAUDE_API_KEY");
if (!apiKey) throw new Error("APIキーが未設定です");
// ...
}
// 不要になった値を削除する
function deleteOldKey() {
PropertiesService.getScriptProperties().deleteProperty("OLD_TOKEN");
}1. 保存できる容量に上限がある
値1つあたり最大9KB、ストア全体で最大500KBです。設定値の保管には十分ですが、 大量データやログの保存には使わず、スプレッドシートやDriveを使ってください。
2. 値はすべて文字列になる
数値や真偽値もそのままでは保存できません。保存時は文字列化し、取得時は Number()やJSON.parse()で元の型に戻す前提でコードを書きます。
3. 「完全な暗号化」ではない点を理解する
スクリプトプロパティは、そのスクリプトの編集権限を持つ人には見えます。 閲覧権限の管理と併せて運用し、キーが漏れたと分かったらすぐに再発行しましょう。
まとめ
PropertiesServiceを使えば、APIキーや設定値をコードから切り離して安全に管理できます。 機密値は画面から手入力し、機密でない設定はコードやシートから登録・同期する。 3つのストアを共有範囲で使い分け、複数設定はJSONでまとめる——この基本を押さえれば、 共有や引き継ぎに強い、実務レベルのGASスクリプトになります。
よくある質問
スクリプトを他の人と共有したり、コードをGitHubなどに貼り付けたりしたときに、APIキーがそのまま第三者に見えてしまうためです。PropertiesService(設定値をキーと値で保存するGASの標準機能)に入れておけば、コード本体にはキーの文字列が残らず、閲覧権限を持つ人にしか見えません。
スクリプトプロパティはスクリプト全体で共通の値で、誰が実行しても同じ内容が読めます。APIキーや共通設定に向いています。ユーザープロパティは実行したユーザーごとに別々に保存され、他の人からは見えません。個人ごとのトークンや個人設定に向いています。
スクリプトエディタの「プロジェクトの設定」画面にある「スクリプト プロパティ」から、キーと値を手動で追加・編集できます。コードから setProperty() で登録することもできますが、APIキーのような機密値は画面から手入力するほうが、コードに値が残らず安全です。
関連する設定をJavaScriptオブジェクトにまとめ、JSON.stringify() で文字列にして1つのキーに保存する方法が便利です。読み出すときは JSON.parse() で元のオブジェクトに戻します。設定項目が増えてもキーが散らからず、初期値とのマージもしやすくなります。
あります。値1つあたり最大9KB、プロパティストア全体で最大500KBという上限があります。APIキーや設定フラグの保存には十分ですが、大量のデータやログの保管には向きません。大きなデータはスプレッドシートやDriveに保存してください。
GAS開発・API連携を
相談する。
APIキーの安全な管理を含め、外部サービス連携・帳票出力・Gmail自動化など、 日々の業務を自動化するGAS開発をご相談いただけます。