はじめに
今回はWorkplace for MetaのWorkchatのチャット情報をcsvファイルとしてエクスポートする方法をご紹介します。
SANANE
APIを使用せずに実現可能な方法なので、技術的な知識がなくても簡単に実行できます。
通常Workchatのデータをダウンロードするには管理者の権限もしくは許可が必要です。
ですが今回はブックマークレットという方法を利用して自動で画面を操作し、過去のチャット情報を読み取る形でcsvでダウンロードする方法を紹介します。
ブックマークレットとは?
ブックマークレットは、ブラウザのブックマークとして保存できるプログラムです。 「javascript:」で始まる短いスクリプトで、ブックマークをクリックすることで任意の処理を実行できます。
ブックマークレットは便利なツールですが、悪意のあるスクリプトが含まれている可能性もあるため、信頼できるソースからのスクリプトのみを使用してください。
SANANE
実行前にAIツールなどでスクリプトを確認してもらい、外部への送信や悪意のあるダウンロードを行う処理がないか内容を確認してもらうことを推奨します!
ブックマークレットの導入方法 (Chrome)
- ブラウザのブックマークバーを表示する
- Chrome右上のメニュー(⋮) > ブックマーク > ブックマークバーを表示
- または
Ctrl + Shift + B
(Windows/Linux) /Command + Shift + B
(Mac)
- 新しいブックマークを作成する
- ブックマークバーを右クリック > 「ページを追加」を選択
- ブックマークの設定
- 名前: 任意の名前(例: Workchat Export)
- URL: 下記のJavaScriptコードをコピー&ペースト
- 保存をクリック
javascript:(async function(){
var statusDiv = document.createElement('div');
statusDiv.style.position = "fixed";
statusDiv.style.bottom = "0";
statusDiv.style.right = "0";
statusDiv.style.zIndex = "9999";
statusDiv.style.background = "rgba(0, 0, 0, 0.7)";
statusDiv.style.color = "white";
statusDiv.style.padding = "10px";
statusDiv.style.fontSize = "12px";
statusDiv.style.maxWidth = "300px";
statusDiv.style.lineHeight = "1.2em";
statusDiv.style.fontFamily = "Arial, sans-serif";
statusDiv.innerHTML = "Starting...";
document.body.appendChild(statusDiv);
function updateStatus(msg) {
statusDiv.innerHTML = msg;
}
var main = document.querySelector('[role="main"]');
if(!main){ updateStatus("Main div not found."); return; }
var targetDivs = main.querySelectorAll('div');
if(targetDivs.length < 7){ updateStatus("Not enough divs in main."); return; }
var scrollContainer = targetDivs[6];
var processed = new Set();
var csvLines = [];
var iteration = 0;
while(true){
iteration++;
updateStatus("Iteration: " + iteration + " - Checking for unprocessed chats...");
var containers = Array.from(document.querySelectorAll('div[data-virtualized="false"]'));
var unprocessed = containers.filter(el => !processed.has(el));
if(unprocessed.length > 0){
unprocessed.sort((a, b) => b.getBoundingClientRect().top - a.getBoundingClientRect().top);
let chatContainer = unprocessed[0];
processed.add(chatContainer);
let chatContent = "";
let contentElem = chatContainer.querySelector('div[dir="auto"].html-div');
if(contentElem){
chatContent = contentElem.textContent;
console.log("Chat content:", chatContent);
}
let chatDatetime = "";
let messagesTables = chatContainer.querySelectorAll('div[data-scope="messages_table"]');
let messagesTable = null;
if(messagesTables.length > 1){ messagesTable = messagesTables[1]; }
else if(messagesTables.length === 1){ messagesTable = messagesTables[0]; }
if(messagesTable){
let children = messagesTable.children;
for(let i = 0; i < children.length; i++){
if(children[i].tagName.toUpperCase() !== "DIV") continue;
let role = children[i].getAttribute("role");
if(role === "presentation" || role === "none") continue;
chatDatetime = children[i].textContent;
console.log("Chat datetime:", chatDatetime);
break;
}
}
let userText = "";
if(messagesTable){
let userElem = messagesTable.querySelector('div[role="presentation"]');
if(userElem){
userText = userElem.textContent;
console.log("User text:", userText);
}
}
let csvLine = '"' + chatContent.replace(/"/g,'""') + '","' + chatDatetime.replace(/"/g,'""') + '","' + userText.replace(/"/g,'""') + '"';
csvLines.push(csvLine);
console.log("Processed chat:", csvLine);
updateStatus("Processed chats: " + csvLines.length);
chatContainer.scrollIntoView();
await new Promise(r => setTimeout(r, 1000));
continue;
} else {
updateStatus("No unprocessed chats found. Scrolling up...");
let prevScrollTop = scrollContainer.scrollTop;
scrollContainer.scrollTop = prevScrollTop - 100;
console.log("Scrolled up. New scrollTop:", scrollContainer.scrollTop);
await new Promise(r => setTimeout(r, 1000));
if(scrollContainer.scrollTop <= 0 || scrollContainer.scrollTop === prevScrollTop){
updateStatus("Reached top. Waiting for new chats...");
let waited = 0;
let newChatFound = false;
while(waited < 10){
await new Promise(r => setTimeout(r, 1000));
waited++;
containers = Array.from(document.querySelectorAll('div[data-virtualized="false"]'));
unprocessed = containers.filter(el => !processed.has(el));
if(unprocessed.length > 0){
newChatFound = true;
updateStatus("New chats loaded after waiting " + waited + " seconds.");
break;
}
}
if(newChatFound){ continue; }
else {
updateStatus("No new chats after waiting for 10 seconds. Finishing up...");
break;
}
}
}
}
let csvContent = csvLines.join("\n");
let bom = "\uFEFF";
let blob = new Blob([bom + csvContent], {type:"text/csv;charset=utf-8"});
let url = URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = "chats.csv";
a.click();
updateStatus("CSV file downloaded. Total chats: " + csvLines.length);
console.log("CSV file downloaded.");
})();
これで設定は完了です。
Workchatをブラウザで開き、ダウンロードを取得したいチャットを開きます。
あとは作成したブックマークをクリックすると、 スクリプトが実行されメッセージの読み込みとエクスポートが開始されます。
ブックマークレットの動作
動作の流れ:
- 実行すると、右下にステータスが表示され画面に表示されているチャットを取得します。
- 画面内のすべてのチャットを取得すると、上部までスクロールして過去メッセージを読み込みます。
- 全メッセージの処理完了後、csvファイルをダウンロードします。
- csvにはメッセージ内容、チャット日、ユーザを記録します。
注意事項
- WebブラウザのWorkchatで実行する必要があります。
- 取得できるのは1トークルームずつです。
- Workplaceのチャット画面で実行してください