@kudoai/chatgpt.js 2.9.3 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -13
- package/chatgpt.js +93 -100
- package/dist/chatgpt.min.js +3 -9
- package/docs/README.md +28 -13
- package/docs/USERGUIDE.md +80 -53
- package/package.json +6 -6
- package/starters/chrome/LICENSE.md +2 -2
- package/starters/chrome/docs/README.md +2 -2
- package/starters/chrome/docs/SECURITY.md +2 -2
- package/starters/chrome/extension/lib/chatgpt.js +93 -100
- package/starters/chrome/extension/manifest.json +1 -1
- package/starters/chrome/extension/popup/index.html +1 -1
- package/starters/greasemonkey/LICENSE.md +2 -2
- package/starters/greasemonkey/chatgpt.js-greasemonkey-starter.user.js +4 -4
- package/starters/greasemonkey/docs/SECURITY.md +2 -2
|
@@ -3,8 +3,13 @@
|
|
|
3
3
|
// User guide: https://chatgptjs.org/userguide
|
|
4
4
|
// Latest minified release: https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js/chatgpt.min.js
|
|
5
5
|
|
|
6
|
-
// Init
|
|
7
|
-
|
|
6
|
+
// Init feedback props
|
|
7
|
+
localStorage.alertQueue = JSON.stringify([]);
|
|
8
|
+
localStorage.notifyProps = JSON.stringify({ queue: { topRight: [], bottomRight: [], bottomLeft: [], topLeft: [] }});
|
|
9
|
+
|
|
10
|
+
// Define chatgpt API
|
|
11
|
+
const chatgpt = { // eslint-disable-line no-redeclare
|
|
12
|
+
openAIaccessToken: {}, endpoints: {
|
|
8
13
|
assets: 'https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js',
|
|
9
14
|
openAI: {
|
|
10
15
|
session: 'https://chatgpt.com/api/auth/session',
|
|
@@ -13,16 +18,7 @@ const endpoints = {
|
|
|
13
18
|
share_create: 'https://chatgpt.com/backend-api/share/create',
|
|
14
19
|
share: 'https://chatgpt.com/backend-api/share',
|
|
15
20
|
instructions: 'https://chatgpt.com/backend-api/user_system_messages'
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
// Init feedback properties
|
|
20
|
-
localStorage.alertQueue = JSON.stringify([]);
|
|
21
|
-
localStorage.notifyProps = JSON.stringify({ queue: { topRight: [], bottomRight: [], bottomLeft: [], topLeft: [] }});
|
|
22
|
-
|
|
23
|
-
// Define chatgpt.methods
|
|
24
|
-
const chatgpt = { // eslint-disable-line no-redeclare
|
|
25
|
-
openAIaccessToken: {},
|
|
21
|
+
}},
|
|
26
22
|
|
|
27
23
|
actAs: function(persona) {
|
|
28
24
|
// Prompts ChatGPT to act as a persona from https://github.com/KudoAI/chat-prompts/blob/main/personas.json
|
|
@@ -127,8 +123,9 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
127
123
|
+ 'background-color: ' + ( scheme == 'dark' ? '#00cfff' : '#9cdaff' ) + ';'
|
|
128
124
|
+ 'box-shadow: 2px 1px ' + ( scheme == 'dark' ? '54px #00cfff' : '30px #9cdaff' ) + '}'
|
|
129
125
|
+ '.modal-close-btn {'
|
|
130
|
-
+ 'cursor: pointer ; width:
|
|
131
|
-
|
|
126
|
+
+ 'cursor: pointer ; width: 29px ; height: 29px ; border-radius: 17px ;'
|
|
127
|
+
+ 'float: right ; position: relative ; right: -6px ; top: -5px }'
|
|
128
|
+
+ '.modal-close-btn svg { margin: 10px }' // center SVG for hover underlay
|
|
132
129
|
+ `.modal-close-btn:hover { background-color: #f2f2f2${ scheme == 'dark' ? '00' : '' }}`
|
|
133
130
|
|
|
134
131
|
// Checkbox styles
|
|
@@ -226,7 +223,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
226
223
|
modalContainer.style.display = '';
|
|
227
224
|
setTimeout(() => { // delay non-0 opacity's for transition fx
|
|
228
225
|
modalContainer.style.backgroundColor = (
|
|
229
|
-
`rgba(67, 70, 72, ${ scheme === 'dark' ? 0.62 : 0 })`);
|
|
226
|
+
`rgba(67, 70, 72, ${ scheme === 'dark' ? 0.62 : 0.1 })`);
|
|
230
227
|
modalContainer.classList.add('animated'); }, 100);
|
|
231
228
|
}
|
|
232
229
|
|
|
@@ -234,13 +231,15 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
234
231
|
const clickHandler = event => { // explicitly defined to support removal post-dismissal
|
|
235
232
|
if (event.target == event.currentTarget || event.target instanceof SVGPathElement) dismissAlert(); };
|
|
236
233
|
const keyHandler = event => { // to dismiss active alert
|
|
237
|
-
const dismissKeys = [
|
|
238
|
-
|
|
234
|
+
const dismissKeys = [' ', 'Spacebar', 'Enter', 'Return', 'Escape', 'Esc'],
|
|
235
|
+
dismissKeyCodes = [32, 13, 27];
|
|
236
|
+
if (dismissKeys.includes(event.key) || dismissKeyCodes.includes(event.keyCode)) {
|
|
239
237
|
for (const alertId of alertQueue) { // look to handle only if triggering alert is active
|
|
240
238
|
const alert = document.getElementById(alertId);
|
|
241
239
|
if (alert && alert.style.display !== 'none') { // active alert found
|
|
242
|
-
if (event.keyCode
|
|
243
|
-
|
|
240
|
+
if (event.key.includes('Esc') || event.keyCode == 27) // esc pressed
|
|
241
|
+
dismissAlert(); // dismiss alert & do nothing
|
|
242
|
+
else if ([' ', 'Spacebar', 'Enter', 'Return'].includes(event.key) || [32, 13].includes(event.keyCode)) { // space/enter pressed
|
|
244
243
|
const mainButton = alert.querySelector('.modal-buttons').lastChild; // look for main button
|
|
245
244
|
if (mainButton) { mainButton.click(); event.preventDefault(); } // click if found
|
|
246
245
|
} return;
|
|
@@ -363,7 +362,10 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
363
362
|
|
|
364
363
|
isLightMode: function() { return window.matchMedia?.('(prefers-color-scheme: light)')?.matches; },
|
|
365
364
|
isDarkMode: function() { return window.matchMedia?.('(prefers-color-scheme: dark)')?.matches; },
|
|
366
|
-
isChromium: function() { return navigator.
|
|
365
|
+
isChromium: function() { return !!JSON.stringify(navigator.userAgentData?.brands)?.includes('Chromium'); },
|
|
366
|
+
isChrome: function() { return !!JSON.stringify(navigator.userAgentData?.brands)?.includes('Chrome'); },
|
|
367
|
+
isEdge: function() { return !!JSON.stringify(navigator.userAgentData?.brands)?.includes('Edge'); },
|
|
368
|
+
isBrave: function() { return !!JSON.stringify(navigator.userAgentData?.brands)?.includes('Brave'); },
|
|
367
369
|
isFirefox: function() { return navigator.userAgent.includes('Firefox'); },
|
|
368
370
|
|
|
369
371
|
isFullScreen: function() {
|
|
@@ -377,49 +379,20 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
377
379
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); }
|
|
378
380
|
},
|
|
379
381
|
|
|
380
|
-
clearChats: async function(
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
settingsBtn.click(); await delay(333);
|
|
395
|
-
const settingsBtns = document.querySelectorAll('[id*=radix] button'),
|
|
396
|
-
deleteBtn = settingsBtns[settingsBtns.length - 1];
|
|
397
|
-
deleteBtn.click(); await delay(10);
|
|
398
|
-
document.querySelector('button[class*="danger"').click(); // confirm clear
|
|
399
|
-
return console.info('Chats successfully cleared.');
|
|
400
|
-
} catch (err) {
|
|
401
|
-
console.error(err.message);
|
|
402
|
-
if (arguments.length == 0) {
|
|
403
|
-
console.info('Using backend API method instead.'); chatgpt.clearChats('api'); }
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
} else { // API method
|
|
407
|
-
// NOTE: DOM is not updated to reflect new empty chat list (until session refresh)
|
|
408
|
-
|
|
409
|
-
return new Promise((resolve, reject) => {
|
|
410
|
-
chatgpt.getAccessToken().then(token => {
|
|
411
|
-
const xhr = new XMLHttpRequest();
|
|
412
|
-
xhr.open('PATCH', endpoints.openAI.chats, true);
|
|
413
|
-
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
414
|
-
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
|
|
415
|
-
xhr.onload = () => {
|
|
416
|
-
if (xhr.status !== 200) return reject('🤖 chatgpt.js >> Request failed. Cannot clear chats.');
|
|
417
|
-
console.info('Chats successfully cleared'); resolve();
|
|
418
|
-
};
|
|
419
|
-
xhr.send(JSON.stringify({ is_visible: false }));
|
|
420
|
-
}).catch(err => reject(new Error(err.message)));
|
|
421
|
-
});
|
|
422
|
-
}
|
|
382
|
+
clearChats: async function() { // back-end method
|
|
383
|
+
return new Promise((resolve, reject) => {
|
|
384
|
+
chatgpt.getAccessToken().then(token => {
|
|
385
|
+
const xhr = new XMLHttpRequest();
|
|
386
|
+
xhr.open('PATCH', chatgpt.endpoints.openAI.chats, true);
|
|
387
|
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
388
|
+
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
|
|
389
|
+
xhr.onload = () => {
|
|
390
|
+
if (xhr.status !== 200) return reject('🤖 chatgpt.js >> Request failed. Cannot clear chats.');
|
|
391
|
+
console.info('Chats successfully cleared'); resolve();
|
|
392
|
+
};
|
|
393
|
+
xhr.send(JSON.stringify({ is_visible: false }));
|
|
394
|
+
}).catch(err => reject(new Error(err.message)));
|
|
395
|
+
});
|
|
423
396
|
},
|
|
424
397
|
|
|
425
398
|
code: {
|
|
@@ -439,6 +412,34 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
439
412
|
return codeBlocks ? codeBlocks[codeBlocks.length - 1] : msg;
|
|
440
413
|
},
|
|
441
414
|
|
|
415
|
+
isIdle: async function() {
|
|
416
|
+
await new Promise(resolve => { // when in conversation page
|
|
417
|
+
(function checkConvoPage() {
|
|
418
|
+
document.querySelector('div[data-message-author-role]') ? resolve(true)
|
|
419
|
+
: setTimeout(checkConvoPage, 200); })();
|
|
420
|
+
});
|
|
421
|
+
await new Promise(resolve => { // when reply starts generating
|
|
422
|
+
(function checkReplyExists() {
|
|
423
|
+
const msgDivs = document.querySelectorAll('div[data-message-author-role]');
|
|
424
|
+
msgDivs[msgDivs.length - 1].dataset.messageAuthorRole == 'assistant' ? resolve(true)
|
|
425
|
+
: setTimeout(checkReplyExists, 200); })();
|
|
426
|
+
});
|
|
427
|
+
const lastReplyDiv = await new Promise(resolve => { // when code starts generating
|
|
428
|
+
(function checkPreExists() {
|
|
429
|
+
const replyDivs = document.querySelectorAll('div[data-message-author-role="assistant"]'),
|
|
430
|
+
lastReplyDiv = replyDivs[replyDivs.length - 1];
|
|
431
|
+
lastReplyDiv.querySelector('pre') ? resolve(lastReplyDiv)
|
|
432
|
+
: setTimeout(checkPreExists, 200); })();
|
|
433
|
+
});
|
|
434
|
+
return Promise.race([
|
|
435
|
+
new Promise(resolve => { // when code block not last child of reply div
|
|
436
|
+
(function checkPreNotLast() {
|
|
437
|
+
lastReplyDiv.querySelector('pre').nextElementSibling ? resolve(true)
|
|
438
|
+
: setTimeout(checkPreNotLast, 200); })();
|
|
439
|
+
}), chatgpt.isIdle() // ...or reply stopped generating
|
|
440
|
+
]);
|
|
441
|
+
},
|
|
442
|
+
|
|
442
443
|
minify: async function(code) {
|
|
443
444
|
if (!code) return console.error('Code argument not supplied. Pass some code!');
|
|
444
445
|
if (typeof code !== 'string') return console.error('Code argument must be a string!');
|
|
@@ -609,6 +610,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
609
610
|
},
|
|
610
611
|
|
|
611
612
|
extractCode: function() { chatgpt.code.extract(); },
|
|
613
|
+
focusChatbar: function() { chatgpt.getChatBox()?.focus(); },
|
|
612
614
|
|
|
613
615
|
generateRandomIP: function() {
|
|
614
616
|
const ip = Array.from({length: 4}, () => Math.floor(chatgpt.randomFloat() * 256)).join('.');
|
|
@@ -625,9 +627,9 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
625
627
|
throw new TypeError('Invalid arguments. Both arguments must be strings.'); }
|
|
626
628
|
|
|
627
629
|
// Validate targetType
|
|
628
|
-
if (!
|
|
630
|
+
if (!cjsTargetTypes.includes(targetType.toLowerCase())) {
|
|
629
631
|
throw new Error('Invalid targetType: ' + targetType
|
|
630
|
-
+ '. Valid values are: ' + JSON.stringify(
|
|
632
|
+
+ '. Valid values are: ' + JSON.stringify(cjsTargetTypes)); }
|
|
631
633
|
|
|
632
634
|
// Validate targetName scoped to pre-validated targetType
|
|
633
635
|
const targetNames = [], reTargetName = new RegExp('^get(.*)' + targetType + '$', 'i');
|
|
@@ -655,7 +657,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
655
657
|
(Date.parse(chatgpt.openAIaccessToken.expireDate) - Date.parse(new Date()) >= 0)) // not expired
|
|
656
658
|
return resolve(chatgpt.openAIaccessToken.token);
|
|
657
659
|
const xhr = new XMLHttpRequest();
|
|
658
|
-
xhr.open('GET', endpoints.openAI.session, true);
|
|
660
|
+
xhr.open('GET', chatgpt.endpoints.openAI.session, true);
|
|
659
661
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
660
662
|
xhr.onload = () => {
|
|
661
663
|
if (xhr.status !== 200) return reject('🤖 chatgpt.js >> Request failed. Cannot retrieve access token.');
|
|
@@ -688,7 +690,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
688
690
|
// Return account details
|
|
689
691
|
return new Promise((resolve, reject) => {
|
|
690
692
|
const xhr = new XMLHttpRequest();
|
|
691
|
-
xhr.open('GET', endpoints.openAI.session, true);
|
|
693
|
+
xhr.open('GET', chatgpt.endpoints.openAI.session, true);
|
|
692
694
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
693
695
|
xhr.onload = () => {
|
|
694
696
|
if (xhr.status === 200) {
|
|
@@ -744,7 +746,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
744
746
|
const re_chatID = /\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/;
|
|
745
747
|
return new Promise((resolve, reject) => {
|
|
746
748
|
const xhr = new XMLHttpRequest();
|
|
747
|
-
xhr.open('GET', endpoints.openAI.chats, true);
|
|
749
|
+
xhr.open('GET', chatgpt.endpoints.openAI.chats, true);
|
|
748
750
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
749
751
|
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
|
|
750
752
|
xhr.onload = () => {
|
|
@@ -784,7 +786,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
784
786
|
return new Promise((resolve, reject) => {
|
|
785
787
|
const xhr = new XMLHttpRequest();
|
|
786
788
|
getChatDetails(token, ['id']).then(chat => {
|
|
787
|
-
xhr.open('GET', `${endpoints.openAI.chat}/${chat.id}`, true);
|
|
789
|
+
xhr.open('GET', `${chatgpt.endpoints.openAI.chat}/${chat.id}`, true);
|
|
788
790
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
789
791
|
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
|
|
790
792
|
xhr.onload = () => {
|
|
@@ -917,8 +919,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
917
919
|
isLoaded: function() {
|
|
918
920
|
return new Promise(resolve => {
|
|
919
921
|
(function checkChatHistory() {
|
|
920
|
-
|
|
921
|
-
else setTimeout(checkChatHistory, 200);
|
|
922
|
+
document.querySelector('nav') ? resolve(true) : setTimeout(checkChatHistory, 200);
|
|
922
923
|
})();
|
|
923
924
|
});}
|
|
924
925
|
},
|
|
@@ -996,7 +997,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
996
997
|
|
|
997
998
|
return new Promise((resolve, reject) => {
|
|
998
999
|
const xhr = new XMLHttpRequest();
|
|
999
|
-
xhr.open(method, endpoints.openAI.instructions, true);
|
|
1000
|
+
xhr.open(method, chatgpt.endpoints.openAI.instructions, true);
|
|
1000
1001
|
// Set headers
|
|
1001
1002
|
xhr.setRequestHeader('Accept-Language', 'en-US');
|
|
1002
1003
|
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
|
|
@@ -1048,29 +1049,24 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1048
1049
|
}
|
|
1049
1050
|
},
|
|
1050
1051
|
|
|
1051
|
-
isChromium: function() { return chatgpt.browser.isChromium(); },
|
|
1052
1052
|
isDarkMode: function() { return document.documentElement.classList.toString().includes('dark'); },
|
|
1053
|
-
isFirefox: function() { return chatgpt.browser.isFirefox(); },
|
|
1054
1053
|
isFullScreen: function() { return chatgpt.browser.isFullScreen(); },
|
|
1055
1054
|
|
|
1056
1055
|
isIdle: function() {
|
|
1057
1056
|
return new Promise(resolve => {
|
|
1058
1057
|
(function checkIsIdle() {
|
|
1059
|
-
|
|
1060
|
-
else setTimeout(checkIsIdle, 200);
|
|
1058
|
+
chatgpt.getRegenerateButton() ? resolve(true) : setTimeout(checkIsIdle, 200);
|
|
1061
1059
|
})();
|
|
1062
1060
|
});},
|
|
1063
1061
|
|
|
1064
1062
|
isLoaded: function() {
|
|
1065
1063
|
return new Promise(resolve => {
|
|
1066
1064
|
(function checkIsLoaded() {
|
|
1067
|
-
|
|
1068
|
-
else setTimeout(checkIsLoaded, 200);
|
|
1065
|
+
chatgpt.getNewChatButton() ? resolve(true) : setTimeout(checkIsLoaded, 200);
|
|
1069
1066
|
})();
|
|
1070
1067
|
});},
|
|
1071
1068
|
|
|
1072
1069
|
isLightMode: function() { return document.documentElement.classList.toString().includes('light'); },
|
|
1073
|
-
isMobileDevice: function() { return chatgpt.browser.isMobile(); },
|
|
1074
1070
|
|
|
1075
1071
|
logout: function() { window.location.href = 'https://chat.openai.com/auth/logout'; },
|
|
1076
1072
|
|
|
@@ -1106,7 +1102,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1106
1102
|
const icon = document.createElement('img');
|
|
1107
1103
|
icon.src = attrs?.icon && typeof attrs.icon == 'string' // can also be base64 encoded image string
|
|
1108
1104
|
? attrs.icon // add icon to button element if given, else default one
|
|
1109
|
-
: ( endpoints.assets + '/starters/chrome/extension/icons/icon128.png' );
|
|
1105
|
+
: ( chatgpt.endpoints.assets + '/starters/chrome/extension/icons/icon128.png' );
|
|
1110
1106
|
icon.width = 18;
|
|
1111
1107
|
newElement.insertBefore(icon, newElement.firstChild);
|
|
1112
1108
|
|
|
@@ -1177,7 +1173,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1177
1173
|
|
|
1178
1174
|
notify: async function(msg, position, notifDuration, shadow) {
|
|
1179
1175
|
notifDuration = notifDuration ? +notifDuration : 1.75; // sec duration to maintain notification visibility
|
|
1180
|
-
const fadeDuration = 0.
|
|
1176
|
+
const fadeDuration = 0.35, // sec duration of fade-out
|
|
1181
1177
|
vpYoffset = 23, vpXoffset = 27; // px offset from viewport border
|
|
1182
1178
|
|
|
1183
1179
|
// Create/append notification div
|
|
@@ -1560,7 +1556,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1560
1556
|
return new Promise((resolve, reject) => {
|
|
1561
1557
|
const xhr = new XMLHttpRequest();
|
|
1562
1558
|
chatgpt.getChatData(chatToGet).then(chat => {
|
|
1563
|
-
xhr.open('GET', `${ endpoints.openAI.chat }/${ chat.id }`, true);
|
|
1559
|
+
xhr.open('GET', `${ chatgpt.endpoints.openAI.chat }/${ chat.id }`, true);
|
|
1564
1560
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
1565
1561
|
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
|
|
1566
1562
|
xhr.onload = () => {
|
|
@@ -1575,7 +1571,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1575
1571
|
return new Promise((resolve, reject) => {
|
|
1576
1572
|
const xhr = new XMLHttpRequest();
|
|
1577
1573
|
chatgpt.getChatData(chatToGet).then(chat => {
|
|
1578
|
-
xhr.open('POST', endpoints.openAI.share_create, true);
|
|
1574
|
+
xhr.open('POST', chatgpt.endpoints.openAI.share_create, true);
|
|
1579
1575
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
1580
1576
|
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
|
|
1581
1577
|
xhr.onload = () => {
|
|
@@ -1593,7 +1589,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1593
1589
|
const confirmShareChat = (token, data) => {
|
|
1594
1590
|
return new Promise((resolve, reject) => {
|
|
1595
1591
|
const xhr = new XMLHttpRequest();
|
|
1596
|
-
xhr.open('PATCH', `${ endpoints.openAI.share }/${ data.share_id }`, true);
|
|
1592
|
+
xhr.open('PATCH', `${ chatgpt.endpoints.openAI.share }/${ data.share_id }`, true);
|
|
1597
1593
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
1598
1594
|
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
|
|
1599
1595
|
xhr.onload = () => {
|
|
@@ -1703,7 +1699,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1703
1699
|
const icon = document.createElement('img');
|
|
1704
1700
|
icon.src = attrs?.icon && typeof attrs.icon == 'string' // Can also be base64 encoded image string
|
|
1705
1701
|
? attrs.icon // Add icon to button element if given, else default one
|
|
1706
|
-
: ( endpoints.assets + '/starters/chrome/extension/icons/icon128.png' );
|
|
1702
|
+
: ( chatgpt.endpoints.assets + '/starters/chrome/extension/icons/icon128.png' );
|
|
1707
1703
|
icon.width = 18;
|
|
1708
1704
|
newElement.insertBefore(icon, newElement.firstChild);
|
|
1709
1705
|
|
|
@@ -1752,12 +1748,9 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1752
1748
|
|
|
1753
1749
|
toggle: function() {
|
|
1754
1750
|
const isMobileDevice = chatgpt.browser.isMobile(),
|
|
1755
|
-
|
|
1756
|
-
navBtnSelector = isMobileDevice ? '#__next button' : isGPT4oUI ? 'nav button' : 'main button',
|
|
1751
|
+
navBtnSelector = isMobileDevice ? '#__next button' : 'nav button',
|
|
1757
1752
|
isToggleBtn = isMobileDevice ? () => true // since 1st one is toggle
|
|
1758
|
-
:
|
|
1759
|
-
: /* post-GPT-4o desktop */ btn => [...btn.querySelectorAll('*')]
|
|
1760
|
-
.some(child => child.style.transform.includes('translateY'));
|
|
1753
|
+
: btn => btn.querySelectorAll('svg path[d*="M8.857 3h6.286c1.084"]').length > 0;
|
|
1761
1754
|
for (const btn of document.querySelectorAll(navBtnSelector))
|
|
1762
1755
|
if (isToggleBtn(btn)) { btn.click(); return; }
|
|
1763
1756
|
},
|
|
@@ -1767,8 +1760,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1767
1760
|
return Promise.race([
|
|
1768
1761
|
new Promise(resolve => {
|
|
1769
1762
|
(function checkNewChatLink() {
|
|
1770
|
-
|
|
1771
|
-
else setTimeout(checkNewChatLink, 200);
|
|
1763
|
+
chatgpt.getNewChatLink() ? resolve(true) : setTimeout(checkNewChatLink, 200);
|
|
1772
1764
|
})();
|
|
1773
1765
|
}),
|
|
1774
1766
|
new Promise(resolve => setTimeout(resolve, 5000)) // since New Chat link not always present
|
|
@@ -1859,9 +1851,9 @@ const chatgpt = { // eslint-disable-line no-redeclare
|
|
|
1859
1851
|
chatgpt.scheme = { ...chatgpt.settings.scheme }; // copy `chatgpt.settings.scheme` methods into `chatgpt.scheme`
|
|
1860
1852
|
|
|
1861
1853
|
// Create chatgpt.[actions]Button(identifier) functions
|
|
1862
|
-
const
|
|
1863
|
-
for (const
|
|
1864
|
-
chatgpt[
|
|
1854
|
+
const cjsBtnActions = ['click', 'get'], cjsTargetTypes = [ 'button', 'link', 'div', 'response' ];
|
|
1855
|
+
for (const btnAction of cjsBtnActions) {
|
|
1856
|
+
chatgpt[btnAction + 'Button'] = function handleButton(buttonIdentifier) {
|
|
1865
1857
|
const button = /^[.#]/.test(buttonIdentifier) ? document.querySelector(buttonIdentifier)
|
|
1866
1858
|
: /send/i.test(buttonIdentifier) ? document.querySelector('form button[class*="bottom"]')
|
|
1867
1859
|
: /scroll/i.test(buttonIdentifier) ? document.querySelector('button[class*="cursor"]')
|
|
@@ -1872,12 +1864,12 @@ for (const buttonAction of buttonActions) {
|
|
|
1872
1864
|
for (const navLink of document.querySelectorAll('nav a')) { // try nav links if no button
|
|
1873
1865
|
if (navLink.textContent.toLowerCase().includes(buttonIdentifier.toLowerCase())) {
|
|
1874
1866
|
return navLink; }}})();
|
|
1875
|
-
if (
|
|
1867
|
+
if (btnAction == 'click') { button.click(); } else { return button; }
|
|
1876
1868
|
};
|
|
1877
1869
|
}
|
|
1878
1870
|
|
|
1879
1871
|
// Create alias functions
|
|
1880
|
-
const
|
|
1872
|
+
const cjsFuncAliases = [
|
|
1881
1873
|
['actAs', 'actas', 'act', 'become', 'persona', 'premadePrompt', 'preMadePrompt', 'prePrompt', 'preprompt', 'roleplay', 'rolePlay', 'rp'],
|
|
1882
1874
|
['activateAutoRefresh', 'activateAutoRefresher', 'activateRefresher', 'activateSessionRefresher',
|
|
1883
1875
|
'autoRefresh', 'autoRefresher', 'autoRefreshSession', 'refresher', 'sessionRefresher'],
|
|
@@ -1917,7 +1909,7 @@ const funcAliases = [
|
|
|
1917
1909
|
['unminify', 'unminifyCode', 'codeUnminify'],
|
|
1918
1910
|
['writeCode', 'codeWrite']
|
|
1919
1911
|
];
|
|
1920
|
-
const
|
|
1912
|
+
const cjsFuncSynonyms = [
|
|
1921
1913
|
['account', 'acct'],
|
|
1922
1914
|
['activate', 'turnOn'],
|
|
1923
1915
|
['analyze', 'check', 'evaluate', 'review'],
|
|
@@ -1930,6 +1922,7 @@ const synonyms = [
|
|
|
1930
1922
|
['data', 'details'],
|
|
1931
1923
|
['deactivate', 'deActivate', 'turnOff'],
|
|
1932
1924
|
['execute', 'interpret', 'interpreter', 'run'],
|
|
1925
|
+
['firefox', 'ff'],
|
|
1933
1926
|
['generating', 'generation'],
|
|
1934
1927
|
['minify', 'uglify'],
|
|
1935
1928
|
['refactor', 'rewrite'],
|
|
@@ -1946,7 +1939,7 @@ const camelCaser = (words) => {
|
|
|
1946
1939
|
for (const prop in chatgpt) {
|
|
1947
1940
|
|
|
1948
1941
|
// Create new function for each alias
|
|
1949
|
-
for (const subAliases of
|
|
1942
|
+
for (const subAliases of cjsFuncAliases) {
|
|
1950
1943
|
if (subAliases.includes(prop)) {
|
|
1951
1944
|
if (subAliases.some(element => element.includes('.'))) {
|
|
1952
1945
|
const nestedFunction = subAliases.find(element => element.includes('.')).split('.')[1];
|
|
@@ -1966,7 +1959,7 @@ for (const prop in chatgpt) {
|
|
|
1966
1959
|
if (typeof chatgpt[funcName] == 'function') {
|
|
1967
1960
|
const funcWords = funcName.split(/(?=[A-Zs])/); // split function name into constituent words
|
|
1968
1961
|
for (const funcWord of funcWords) {
|
|
1969
|
-
const synonymValues = [].concat(...
|
|
1962
|
+
const synonymValues = [].concat(...cjsFuncSynonyms // flatten into single array w/ word's cjsFuncSynonyms
|
|
1970
1963
|
.filter(arr => arr.includes(funcWord.toLowerCase())) // filter in relevant synonym sub-arrays
|
|
1971
1964
|
.map(arr => arr.filter(synonym => synonym !== funcWord.toLowerCase()))); // filter out matching word
|
|
1972
1965
|
for (const synonym of synonymValues) { // create function per synonym
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
</div>
|
|
43
43
|
-->
|
|
44
44
|
<footer>
|
|
45
|
-
<div class="chatgpt-js"><a title="Powered by chatgpt.js" href="https://chatgpt.js.org" target="_blank" rel="noopener"><img src="https://media.chatgptjs.org/images/badges/powered-by-chatgpt.js-faded.png"></a></div>
|
|
45
|
+
<div class="chatgpt-js"><a title="Powered by chatgpt.js" href="https://chatgpt.js.org" target="_blank" rel="noopener"><img src="https://media.chatgptjs.org/images/badges/powered-by-chatgpt.js-faded.png?main"></a></div>
|
|
46
46
|
<span title="Check for Updates" class="menu-icon menu-area" style="right:58px ; padding-top: 7px" >
|
|
47
47
|
<img width=15 height=15 src="https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@258bec1/starters/chrome/media/images/icons/refresh/icon16.png" style="margin-top: 0.04rem">
|
|
48
48
|
</span>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h6>
|
|
3
3
|
<picture>
|
|
4
|
-
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://media.chatgptjs.org/images/icons/earth-americas-white-icon32.svg">
|
|
5
|
-
<img height=14 src="https://media.chatgptjs.org/images/icons/earth-americas-icon32.svg">
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://media.chatgptjs.org/images/icons/earth-americas-white-icon32.svg?main">
|
|
5
|
+
<img height=14 src="https://media.chatgptjs.org/images/icons/earth-americas-icon32.svg?main">
|
|
6
6
|
</picture>
|
|
7
7
|
English |
|
|
8
8
|
<a href="docs/zh-cn/LICENSE.md">简体中文</a> |
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
// @description A Greasemonkey template to start using chatgpt.js like a boss
|
|
4
4
|
// @author chatgpt.js
|
|
5
5
|
// @namespace https://chatgpt.js.org
|
|
6
|
-
// @version 2024.
|
|
6
|
+
// @version 2024.7.19.1
|
|
7
7
|
// @license MIT
|
|
8
8
|
// @match *://chatgpt.com/*
|
|
9
9
|
// @match *://chat.openai.com/*
|
|
10
|
-
// @icon https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@
|
|
11
|
-
// @icon64 https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@
|
|
12
|
-
// @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@
|
|
10
|
+
// @icon https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@3.0.1/starters/greasemonkey/media/images/icons/robot/icon48.png
|
|
11
|
+
// @icon64 https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js@3.0.1/starters/greasemonkey/media/images/icons/robot/icon64.png
|
|
12
|
+
// @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@3.0.1/dist/chatgpt.min.js
|
|
13
13
|
// @grant GM_getValue
|
|
14
14
|
// @grant GM_setValue
|
|
15
15
|
// @noframes
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<div align="right">
|
|
2
2
|
<h6>
|
|
3
3
|
<picture>
|
|
4
|
-
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://media.chatgptjs.org/images/icons/earth-americas-white-icon32.svg">
|
|
5
|
-
<img height=14 src="https://media.chatgptjs.org/images/icons/earth-americas-icon32.svg">
|
|
4
|
+
<source type="image/svg+xml" media="(prefers-color-scheme: dark)" srcset="https://media.chatgptjs.org/images/icons/earth-americas-white-icon32.svg?main">
|
|
5
|
+
<img height=14 src="https://media.chatgptjs.org/images/icons/earth-americas-icon32.svg?main">
|
|
6
6
|
</picture>
|
|
7
7
|
English |
|
|
8
8
|
<a href="https://github.com/KudoAI/chatgpt.js-greasemonkey-starter/blob/main/docs/zh-cn/SECURITY.md">简体中文</a> |
|