kintone Advent Calendar 2025 の 22日目の記事です。
内容
VS Code+Baidu Comateでkintoneのレコード一括削除設定がされているアプリをリストアップするブックマークレットを作ってみます。
kintoneのレコード一括削除設定が有効化されているとすごくこわいですよね。ワンクリックで数年分のデータが消えて、復旧もできません。普段からのバックアップも必要ですが、一番の予防策は設定を無効化しておくことです。
とはいえ、データメンテナンス等で一時的に有効化することもあり、消し忘れて冷や冷やした人も多いのではないでしょうか。
ブックマークレットとは
ブックマークレットは、ブラウザのブックマークにコード埋め込んで、色々できるものです。詳しくはwikipediaを御覧ください。
作ったもの
kintoneのログイン後、ブックマークレットをクリックしたら、そのkintone環境のレコード一括削除設定が有効化されているアプリをリストアップします。ゲストスペースは考慮していません。
Baidu Comate(文心快码)とは
中国の百度が出してるコーディング用のAIです。
私中国に住んでまして、中国だと海外のAIは色々あって使いにくいので、中国のAI使って書いてみます。
Baidu ComateはVS Codeに組み込んで使用可能です。まずは、Baidu Comateにkintone REST APIのお作法を覚えてもらいます。
この知識は、会社のみんなで共有したいので、組織としての知識集的な感じで設定します。自分オリジナルのお作法とかは、個人の知識集にいらられるので面白いですね。
コードも知識として設定できますが、今回はドキュメントなので、txtファイルで読み込ませておきます。
これらの知識は、VS Codeでコードを書いてもらうときに、#マークをつけて、AIに参照させられます。
VS Codeで書いていきます(Baidu Comateが)
プロンプト
* ブックマークレットを作成してください。
* kintone環境の全アプリの中から、レコード一括削除が設定が有効になっているアプリをリスト化、クリックで、該当アプリを開くブックマークレットです。
* デザインはシンプルにして。
* kintoneにログインしている状態で使うので、認証情報等はJS内には記載不要。
* 元となるJS Codeとブックマークレットへ貼り付けるためのJS Codeの2つのファイルを作成してください。
* 仕様は下記
1. kintoneにログインした状態で使用する前提
2. 実行時、該当kintone環境にある全アプリを取得。100件を超える場合は複数回APIを呼び出してページングして。
アプリ一覧取得はREST APIの apps.json を使用
3. 取得したアプリのリストの一般設定を取得。settings.json を使用。
4. レコード一括削除有効(enableBulkDeletion)が有効なアプリのリストを画面表示。表示項目は アプリ名 アプリ番号 URL
5. URLはクリックしたら別タブで該当アプリが開くように。例えばアプリ番号が999の場合、リンクURLは https://各環境のドメイン名/k/999 という感じ。
知識集で渡しているので、APIの詳細はAIに指示していませんが、使用を指示したのは、下記2つのAPIです。
中国のAIなので、中国語で考えるんですが、僕が日本語で指示しているので、途中から日本語になってきました。助かりますね。
結果、途中何度かデバッグはしましたが、ほぼちゃんと書いてくれました。×をクリックしても閉じないバグがありますが、ご愛敬ということでなおしていません。
コードざっと確認して、致命的なセキュリティリスクとかはないと思いますが、コピペして使う場合は自己責任でよろしくお願いします。他のAIとかに読み込ませて、改行いれて、自分の目で確認してもらうと、一番安心です。
javascript:(function(){if(typeof kintone=='undefined'||typeof kintone.api=='undefined'){alert('エラー: kintone環境で実行してください');return}async function checkBulkDeletionSettings(){try{showLoading('アプリ一覧を取得中...');const allApps=await getAllApps();if(!allApps||allApps.length===0){throw new Error('閲覧権限のあるアプリが見つかりませんでした')}showLoading('全'+allApps.length+'アプリの設定を確認中(有効なもののみ表示)...');const enabledApps=[];let checkedCount=0;for(let i=0;i<allApps.length;i++){const app=allApps[i];checkedCount++;updateProgress(checkedCount,allApps.length,app.name);try{const settings=await getAppSettings(app.appId);if(settings.enableBulkDeletion===true){enabledApps.push({appId:app.appId,name:app.name,code:app.code,url:window.location.origin+'/k/'+app.appId})}}catch(error){console.warn('アプリ '+app.name+' ('+app.appId+') の設定取得エラー:',error)}await delay(100)}displayEnabledApps(enabledApps,allApps.length)}catch(error){alert('エラー: '+error.message)}finally{hideLoading()}}async function getAllApps(){const allApps=[];let offset=0;const limit=100;while(true){try{const response=await kintone.api(kintone.api.url('/k/v1/apps',true),'GET',{offset:offset,limit:limit});const apps=response.apps||[];if(apps.length===0){break}allApps.push(...apps);offset+=apps.length;if(apps.length<limit){break}}catch(error){console.error('アプリ一覧取得エラー:',error);throw new Error('アプリ一覧の取得に失敗しました')}}return allApps}async function getAppSettings(appId){try{const response=await kintone.api(kintone.api.url('/k/v1/app/settings',true),'GET',{app:appId,lang:'ja'});return response}catch(error){throw new Error('アプリ設定の取得に失敗しました')}}function createPopup(){const popup=document.createElement('div');popup.id='bulk-deletion-checker-popup';popup.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:90%;max-width:800px;max-height:80vh;background:white;border:2px solid #3498db;border-radius:10px;box-shadow:0 4px 20px rgba(0,0,0,0.3);z-index:10000;font-family:メイリオ,Meiryo,sans-serif;overflow:hidden';const header=document.createElement('div');header.style.cssText='background:#3498db;color:white;padding:15px 20px;font-size:18px;font-weight:bold;display:flex;justify-content:space-between;align-items:center';header.innerHTML='<span>📋 レコード一括削除設定確認(有効なアプリのみ表示)</span><button id="close-popup" style="background:none;border:none;color:white;font-size:20px;cursor:pointer;">×</button>';const content=document.createElement('div');content.id='popup-content';content.style.cssText='padding:20px;max-height:calc(80vh - 100px);overflow-y:auto';popup.appendChild(header);popup.appendChild(content);document.body.appendChild(popup);document.getElementById('close-popup').addEventListener('click',()=>{document.body.removeChild(popup)});popup.addEventListener('click',(e)=>{if(e.target===popup){document.body.removeChild(popup)}});return content}function showLoading(message){let popupContent=document.getElementById('popup-content');if(!popupContent){popupContent=createPopup()}popupContent.innerHTML='<div style="text-align:center;padding:40px 20px;"><div style="font-size:48px;margin-bottom:20px;">⏳</div><div style="font-size:16px;color:#666;">'+message+'</div></div>'}function updateProgress(current,total,appName){const progress=Math.round((current/total)*100);const progressElement=document.querySelector('#popup-content div');if(progressElement){progressElement.innerHTML='<div style="font-size:48px;margin-bottom:20px;">⏳</div><div style="font-size:16px;color:#666;">処理中: '+current+'/'+total+' ('+progress+'%)<br><small>'+appName+'</small></div>'}}function hideLoading(){const popup=document.getElementById('bulk-deletion-checker-popup');if(popup){document.body.removeChild(popup)}}function displayEnabledApps(enabledApps,totalAppsCount){const popupContent=createPopup();let html='<div style="margin-bottom:20px;padding:15px;background:#ecf0f1;border-radius:5px;text-align:center;"><strong>全 '+totalAppsCount+' アプリ中、レコード一括削除が有効なアプリ:</strong><br>✅ <strong>'+enabledApps.length+'個</strong>が有効設定されています</div>';if(enabledApps.length>0){html+='<h3 style="color:#27ae60;margin-top:20px;">✅ レコード一括削除が有効なアプリ一覧</h3>';enabledApps.forEach(app=>{html+='<div style="border:1px solid #27ae60;border-radius:5px;padding:15px;margin-bottom:10px;background:#f0f8f0;border-left:4px solid #27ae60"><div style="font-weight:bold;font-size:16px;margin-bottom:8px;">'+app.name+'<span style="color:#666;font-size:14px;">(ID: '+app.appId+')</span><a href="'+app.url+'" target="_blank" style="color:#3498db;text-decoration:none;margin-left:10px;">▶ アプリを開く</a></div></div>'})}else{html+='<div style="text-align:center;padding:40px 20px;color:#666;"><div style="font-size:48px;margin-bottom:20px;">📭</div><div style="font-size:16px;">レコード一括削除が有効なアプリは見つかりませんでした</div></div>'}popupContent.innerHTML=html}function delay(ms){return new Promise(resolve=>setTimeout(resolve,ms))}checkBulkDeletionSettings()})();
ブックマークを作って、そこに貼り付けたら動く(はず)です。
動作イメージ
レコード一括削除が有効になっているアプリがリストアップされます。ちゃんと動いていますね。
さいごに
AIにどこまでkintoneのお作法を正確に伝えられるかで、生成されるコードの品質が変わるのだろうなと思いました。
メリークリスマス!










