chatgpt.js
chatgpt.js copied to clipboard
Rewriting getResponse
I'm using a userscript I made to rewrite the fetch function calls and log the details, and I found an API-way to get a response. I'm working on it, and it might even be better than the DOM solution
const endpoints = {
session: 'https://chat.openai.com/api/auth/session',
chat: 'https://chat.openai.com/backend-api/conversations',
singleChat: 'https://chat.openai.com/backend-api/conversation'
};
test: function(chatIdx, responseIdx, regeneratedIdx) {
chatIdx = chatIdx ? chatIdx : 0; // leave it as is because getChatDetails already takes care of the -1
responseIdx = responseIdx ? responseIdx - 1 : 0;
regeneratedIdx = regeneratedIdx ? regeneratedIdx - 1 : 0;
return new Promise((resolve) => { chatgpt.getAccessToken().then(token => {
getChatData(token).then(data => { resolve(data); });});});
function getChatData(token) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
chatgpt.getChatDetails(chatIdx).then(chat => {
xhr.open('GET', endpoints.singleChat + '/' + chat.id, true); // GET request to the conversation
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.onload = () => {
if (xhr.status !== 200) return reject('🤖 chatgpt.js >> Request failed. Cannot retrieve chat messages.');
const data = JSON.parse(xhr.responseText).mapping; // all messages
const userMessages = [];
const responses = [];
for (const key in data) if (data[key].message && data[key].message.author.role === 'user') userMessages.push(data[key].id); // filter out user messages
for (const key in data)
// match responses with their indexed parent (user message)
if (data[key].message && data[key].message.author.role === 'assistant' && data[key].parent === userMessages[responseIdx]) // use responseIdx because at each user message corresponds a response so it doesn't matter if the variable says response
responses.push(data[key].message); // push only chatgpt responses
responses.sort((a, b) => a.create_time - b.create_time); // sort by creation time (in case of the response being regenerated)
resolve(responses[regeneratedIdx].content.parts[0]); // resolve promise giving the regenerate value requested
};
xhr.send();
});
});}
},
Then we can eventually market it as ultimate frontend + backend lib when all the components will be there to use on any site, which is really just getAccessToken + getReply(prompt)
My DDGPT and bravegpt scripts already do this you can copy the logic from there
@adamlui for some reason getChatDetails inside of the test function keeps returning me the whole object, that's why I used .id instead of passing the id argument string
but if I call it alone it works perfectly
..but I never implemented using /conversation , instead for continuation I sent a previous reply as part of prompt
(but /conversation obviously better)
I've left some comments so it's easier to understand. install this userscript so you can see the fetch requests' data the function is in a raw state and has no name and it can be done better
// ==UserScript==
// @name Requests checker | ChatGPT
// @namespace Violentmonkey Scripts
// @match https://chat.openai.com/*
// @grant none
// @version 1.0
// @author -
// @description 7/9/2023, 3:21:31 PM
// @run-at document-start
// ==/UserScript==
(async () => {
const originalFetch = window.fetch;
window.fetch = function (url, options) {
return originalFetch.apply(this, arguments)
.then((response) => {
let resp = response.clone();
resp.json().then((data) => {
console.log(resp.url, '\n\n', JSON.parse(JSON.stringify(options)), '\n\n', data);
});
return response;
});
};
})();
Ok I'm currently adding some functions to the chatgpt.js-chrome-starter then i'll check it out
by 'it can be done better' I mean that it can be more user friendly, I suck at this ðŸ˜
how's it going with the method? also, if you need help with translations, I can help you with my language
@madkarmaa i didn't look at it yet but will now, also yes your language would be good