? ChatGPT-Conversation-Exporter: 一个革命性的油猴脚本,为ChatGPT网站引入了一个独特的功能——一键式会话导出。?旨在为您的ChatGPT体验增添无限便利!
? 想要保存您与ChatGPT的精彩对话?这个脚本能让你轻松做到!只需单击页面上的复制按钮,整个会话就会被优雅地转换成Markdown格式,并自动复制到您的剪贴板。无论是用于记录灵感、保存重要信息,还是仅仅分享有趣的交流,ChatGPT-Conversation-Exporter都是您的完美助手。
✨ 特点:
- 一键导出:在ChatGPT页面上轻松访问和使用。
- Markdown格式:整洁的格式,方便阅读和分享。
- 即刻复制:将整个会话立即复制到剪贴板,无需复杂操作。
? 加入成千上万的用户,开始您的高效ChatGPT对话体验吧!快速、简单、直观——一切尽在ChatGPT-Conversation-Exporter。
https://github.com/glwhappen/chatgpt-conversation-exporter
https://greasyfork.org/zh-CN/scripts/481328-chatgpt-conversation-data-fetcher
功能
- 获取当前ChatGPT会话的ID和内容。
- 将对话内容转换为Markdown格式。
- 提供一个按钮来复制格式化后的对话到剪贴板。
代码
// ==UserScript==
// @name ChatGPT Conversation Data Fetcher
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Fetch and log conversation data from ChatGPT using an access token
// @author You
// @match https://chat.openai.com/*
// @grant GM_xmlhttpRequest
// @homepage https://www.glwsq.cn/post/ChatGPT-Conversation-Exporter
// @downloadURL https://github.com/glwhappen/chatgpt-conversation-exporter/raw/main/ChatGPT-Conversation-Exporter.user.js
// @supportURL https://github.com/glwhappen/chatgpt-conversation-exporter/issues
// @updateURL https://github.com/glwhappen/chatgpt-conversation-exporter/raw/main/ChatGPT-Conversation-Exporter.user.js
// ==/UserScript==
(function() {
'use strict';
// 创建复制按钮并添加到页面
window.addEventListener('load', function() {
const copyButton = document.createElement('button');
copyButton.textContent = '复制对话';
copyButton.style.position = 'fixed';
copyButton.style.top = '10px';
copyButton.style.right = '110px'; // 向左偏移100px
copyButton.style.zIndex = 1000;
copyButton.style.padding = '5px 10px';
copyButton.style.border = 'none';
copyButton.style.borderRadius = '5px';
copyButton.style.backgroundColor = '#4CAF50';
copyButton.style.color = 'white';
copyButton.style.cursor = 'pointer';
document.body.appendChild(copyButton);
// 点击按钮时执行操作
copyButton.addEventListener('click', function() {
this.textContent = '复制中...';
fetchAccessTokenAndConversation(() => {
this.textContent = '复制对话';
showCopySuccessMessage();
});
});
});
// 显示复制成功消息
function showCopySuccessMessage() {
const message = document.createElement('div');
message.textContent = '对话内容已复制到剪贴板';
message.style.position = 'fixed';
message.style.top = '50px';
message.style.right = '110px';
message.style.backgroundColor = '#4CAF50';
message.style.color = 'white';
message.style.padding = '5px 10px';
message.style.borderRadius = '5px';
message.style.zIndex = 1001;
document.body.appendChild(message);
// 3秒后移除消息
setTimeout(() => {
document.body.removeChild(message);
}, 1000);
}
// 获取访问令牌并获取对话内容
function fetchAccessTokenAndConversation(callback) {
GM_xmlhttpRequest({
method: "GET",
url: "https://chat.openai.com/api/auth/session",
onload: function(response) {
try {
const responseData = JSON.parse(response.responseText);
const accessToken = responseData.accessToken;
if (accessToken) {
fetchConversationData(accessToken, callback);
}
} catch (e) {
console.error("解析响应时出错: ", e);
}
},
onerror: function(error) {
console.error("请求错误: ", error);
}
});
}
// 获取对话内容
function fetchConversationData(accessToken, callback) {
const conversationId = window.location.pathname.split('/')[2];
if (conversationId) {
GM_xmlhttpRequest({
method: "GET",
url: `https://chat.openai.com/backend-api/conversation/${conversationId}`,
headers: {
"Authorization": `Bearer ${accessToken}`
},
onload: function(response) {
try {
const jsonData = JSON.parse(response.responseText);
const markdown = convertToMarkdown(jsonData);
navigator.clipboard.writeText(markdown).then(function() {
console.log('对话内容已复制到剪贴板');
if (callback) callback();
}, function(err) {
console.error('无法复制文本: ', err);
});
} catch (e) {
console.error("解析响应数据出错: ", e);
}
},
onerror: function(error) {
console.error("获取对话内容时发生错误: ", error);
}
});
}
}
function convertToMarkdown(conversationData) {
let markdown = "### 对话内容\n\n";
// 循环遍历每个消息
for (const key in conversationData.mapping) {
if (conversationData.mapping.hasOwnProperty(key)) {
const node = conversationData.mapping[key];
const message = node.message;
if (message) {
const sender = message.author.role === 'user' ? '用户' : '机器人';
const contentParts = message.content.parts.join("\n");
const content = contentParts.trim() === '' ? '[无内容]' : contentParts;
markdown += `#### ${sender}:\n${content}\n\n`;
}
}
}
return markdown;
}
})();