
Google App ScriptでGoogleスライドのプレゼンテーション内の全コメントを削除してみた
Googleスライドのプレゼンテーションのコメントを全て削除したい
こんにちは、のんピ(@non____97)です。
皆さんはGoogleスライドのプレゼンテーションのコメントを全て削除したいなと思ったことはありますか? 私はあります。
テンプレート用のGoogleスライドのプレゼンテーションに適宜修正してほしい箇所についてはコメントをしている場合があります。
それ以外にも内部のやり取りをコメントとして残している場合もあるでしょう。
提出や共有する際はこれらのコメントをまとめて削除したいことがあります。
PDFにエクスポートする際は気にする必要はありませんが、そのまま共有する場合やpptx形式でエクスポートした場合はコメントがそのまま残ってしまいます。
私が確認した限りではGoogleスライドの操作画面上では複数のコメントをまとめて削除することはできませんでした。
ということで、Google App Script(以降GAS)を用いてGoogleスライドのプレゼンテーション内のコメントをまとめて削除します。
コードの紹介
用意するGASでは以下のような処理を行えるようにします。
- GASのコンソールからではなく、Googleスライドのメニューバーから操作を選択して、コメントを削除できるようにする
- 削除対象は以下のいずれかから選択できるようにする
- 全てのコメント
- 指定した文字列から始まるコメント
- 指定した文字列から始まるコメントの削除の検索範囲は親コメントのみ
- スレッド内のコメントについては検索しない
- 指定した文字列から始まるコメントの削除で親コメントが削除対象となった場合は子コメントについても削除する
- 削除したコメントはLoggerでログ出力する
Googleスライドのコメントを削除するにあたってはDrive API v3を使用しています。
実際のコードは以下のとおりです。
/**
* プレゼンテーションを開いたときに実行される関数
* カスタムメニューを追加する
*/
function onOpen() {
SlidesApp.getUi()
.createMenu('コメント管理')
.addItem('全てのコメントを削除', 'deleteAllComments')
.addItem('特定のコメントのみ削除', 'deleteFilteredComments')
.addToUi();
}
/**
* プレゼンテーション内の全てのコメントを削除
*/
function deleteAllComments() {
const ui = SlidesApp.getUi();
// ユーザーに確認
const response = ui.alert(
'コメント削除の確認',
'このプレゼンテーション内の全てのコメントを削除します。\nこの操作は元に戻せません。よろしいですか?',
ui.ButtonSet.OK_CANCEL
);
// キャンセルが押されたらスクリプトを終了する
if (response !== ui.Button.OK) {
return;
}
// フィルターなしで削除を実行
deleteCommentsWithFilter(null);
}
/**
* プレゼンテーション内の特定の文字列から始まるコメントのみを削除
*/
function deleteFilteredComments() {
const ui = SlidesApp.getUi();
// ユーザーに検索文字列の入力を求める
const promptResponse = ui.prompt(
'特定のコメントを削除',
'削除するコメントの先頭文字列を入力してください:\n(例: "TODO:" と入力すると、"TODO: ~"で始まるコメントのみ削除されます)',
ui.ButtonSet.OK_CANCEL
);
// キャンセルが押されたらスクリプトを終了する
if (promptResponse.getSelectedButton() !== ui.Button.OK) {
return;
}
// 入力された検索文字列を取得
const searchString = promptResponse.getResponseText().trim();
// 検索文字列が空の場合は警告を表示して終了
if (searchString === '') {
ui.alert('検索文字列が入力されていません', '検索文字列を入力してください。', ui.ButtonSet.OK);
return;
}
// ユーザーに確認
const confirmResponse = ui.alert(
'コメント削除の確認',
`"${searchString}" で始まるコメントのみを削除します。\nこの操作は元に戻せません。よろしいですか?`,
ui.ButtonSet.OK_CANCEL
);
// キャンセルが押されたらスクリプトを終了する
if (confirmResponse !== ui.Button.OK) {
return;
}
// フィルター付きで削除を実行
deleteCommentsWithFilter(searchString);
}
/**
* フィルター条件に基づいてコメントを削除する
* @param {string|null} filterString - フィルター文字列(nullの場合は全て削除)
*/
function deleteCommentsWithFilter(filterString) {
const ui = SlidesApp.getUi();
try {
// 開いているGoogleスライドのプレゼンテーションのオブジェクトを取得
const presentation = SlidesApp.getActivePresentation();
const presentationId = presentation.getId();
const presentationName = presentation.getName();
// drive.file スコープで動作させるために、
// DriveApp を使用してファイルへのアクセスを明示的に確立する
const file = DriveApp.getFileById(presentationId);
// ファイルが取得できたことを確認
if (!file) {
throw new Error('プレゼンテーションファイルにアクセスできません');
}
Logger.log([
`削除日時: ${new Date().toString()}`,
`プレゼンテーション名: ${presentationName}`,
`プレゼンテーションID: ${presentationId}`,
filterString ? `フィルター文字列: "${filterString}"` : "フィルター: なし(全て削除)"
].join("\n"));
let deletedCommentCount = 0; // 削除したメインコメント数
let deletedReplyCount = 0; // 削除した返信数
let skippedCommentCount = 0; // スキップしたコメント数
let pageToken = null;
let commentIndex = 1;
do {
// コメントを取得するためのオプション
const options = {
pageSize: 100,
fields: "*" // すべてのフィールドを取得
};
if (pageToken) {
options.pageToken = pageToken;
}
// コメントを取得
const response = Drive.Comments.list(presentationId, options);
const comments = response.comments || [];
// コメントを処理
comments.forEach(comment => {
try {
const commentContent = comment.content || "";
// フィルターが指定されている場合、コメントの内容をチェック
if (filterString && !commentContent.startsWith(filterString)) {
// フィルターに一致しないコメントはスキップ
skippedCommentCount++;
Logger.log(`コメント #${commentIndex} はフィルター "${filterString}" に一致しないためスキップします: "${commentContent.substring(0, 50)}${commentContent.length > 50 ? '...' : ''}"`);
commentIndex++;
return;
}
Logger.log(`コメント #${commentIndex}:\n${JSON.stringify(comment, null, 2)}`);
// 返信数をカウント
const replyCount = comment.replies ? comment.replies.length : 0;
// コメントを削除
Drive.Comments.remove(presentationId, comment.id);
deletedCommentCount++;
deletedReplyCount += replyCount;
commentIndex++;
} catch (e) {
Logger.log(`エラー: コメントID ${comment.id} の削除に失敗しました: ${e.message}`);
}
});
// 次のページがあれば取得
pageToken = response.nextPageToken;
} while (pageToken);
Logger.log([
`削除したメインコメント数: ${deletedCommentCount}`,
`削除した返信数: ${deletedReplyCount}`,
`削除したコメント総数: ${deletedCommentCount + deletedReplyCount}`,
`スキップしたコメント数: ${skippedCommentCount}`
].join("\n"));
// 結果をユーザーに表示
let resultMessage = `${deletedCommentCount} 件のメインコメントと ${deletedReplyCount} 件の返信(合計 ${deletedCommentCount + deletedReplyCount} 件)を削除しました。`;
if (filterString) {
resultMessage += `\n\n${skippedCommentCount} 件のコメントはフィルター条件に一致しなかったためスキップされました。`;
}
ui.alert('削除完了', resultMessage, ui.ButtonSet.OK);
} catch (e) {
Logger.log(`致命的なエラー: ${e.message}`);
ui.alert('エラー', `予期せぬエラーが発生しました: ${e.message}`, ui.ButtonSet.OK);
}
}
appsscript.json
は以下のとおりです。
{
"timeZone": "Asia/Tokyo",
"dependencies": {
"enabledAdvancedServices": [
{
"userSymbol": "Drive",
"version": "v3",
"serviceId": "drive"
}
]
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive.metadata",
"https://www.googleapis.com/auth/presentations.currentonly"
]
}
Googleドライブ内の全ファイルの操作権限を付与するhttps://www.googleapis.com/auth/drive
と現在開いているGoogleスライドのプレゼンテーション情報を取得するgetActivePresentation()を実行するためのhttps://www.googleapis.com/auth/presentations.currentonly
が付与されていれば動作はします。
ただし、Googleドライブ内の全ファイルに読み込みだけでなく、書き込みも許可するのはなんだか気が引けたので以下で必要最小限の権限を付与するようにしています。
https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive.file
https://www.googleapis.com/auth/drive.metadata
やってみた
全コメントの削除
実際にやってみましょう。
まずは全コメントの削除です。
メニューのコメント管理
-全てのコメントを削除
をクリックします。
初めての実行だったので認証が要求されました。OK
をクリックします。
使用するアカウントを選択します。
GASに許可する権限を確認して許可
をクリックします。
コメント削除の確認のウィンドウが表示されます。OK
をクリックします。
削除完了したことを確認します。削除されたコメント数はプレゼンテーションに設定されたコメント数と一致していることが確認できます。
Googleスプレッドシートのタブをリロードすると、全てのコメントが削除されたことを確認できました。
コメント削除時のログはGASの実行数
から確認できます。
コメントを間違えて削除してしまった場合はここから確認できます。
指定した文字列から始まるコメントの削除
次に指定した文字列から始まるコメントの削除を試してみます。
メニューのコメント管理
-特定のコメントのみ削除
をクリックします。
テキストボックスに[スライドテンプレートコメント]
を入力して、こちらから始まるコメントのみを削除するようにします。
コメント削除の確認のウィンドウが表示されます。OK
をクリックします。
削除完了したことを確認します。削除されたコメント数は返信を含まない[スライドテンプレートコメント]
から始まるコメント数と一致していることが確認できます。
Googleスプレッドシートのタブをリロードすると、返信を含まない[スライドテンプレートコメント]
から始まるコメントが削除されたことを確認できました。
ログは以下のように出力されます。
面倒な処理にはGoogle App Scriptを使おう
Google App ScriptでGoogleスライドのプレゼンテーション内の全コメントを削除してみました。
面倒な処理にはGoogle App Scriptを使うのがやはり便利ですね。
この記事が誰かの助けになれば幸いです。
以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!