Skip to content

Instantly share code, notes, and snippets.

@rynomad
Created April 18, 2023 20:27
Show Gist options
  • Save rynomad/0bdd930735b96e25c33e5a065a5e8bae to your computer and use it in GitHub Desktop.
Save rynomad/0bdd930735b96e25c33e5a065a5e8bae to your computer and use it in GitHub Desktop.
basic 'run script' for chatgpt, needs https://github.com/rynomad/violentmonkey
// ==UserScript==
// @name My Userscript
// @namespace http://tampermonkey.net/
// @version 1.0
// @description A ViolentMonkey userscript using BrokerClient
// @match https://chat.openai.com/*
// @grant GM.addStyle
// @grant GM.deleteValue
// @grant GM.getValue
// @grant GM.listValues
// @grant GM.setValue
// @grant GM.xmlHttpRequest
// @grant GM.notification
// @grant GM.openInTab
// @grant GM.getResourceUrl
// @grant GM.setClipboard
// @grant GM.info
// @grant GM.registerMenuCommand
// @grant GM.unregisterMenuCommand
// @grant GM.download
// @grant GM.getTab
// @grant GM.saveTab
// @grant GM.getTabs
// @grant GM.connect
// @grant GM.setIcon
// @grant GM.fetch
// @grant GM.gpt
// @grant GM.communicator
// @inject-into content
// @require https://code.jquery.com/jquery-3.6.0.min.js
// ==/UserScript==
(function() {
'use strict';
function isUserscript(code) {
const regex = /\/\/\s?==UserScript==[\s\S]*\/\/\s?==\/UserScript==/;
return regex.test(code);
}
function getIncludePatterns(code) {
const regex = /\/\/\s?@(include|match)\s+(.*)/g;
const patterns = [];
let match;
while ((match = regex.exec(code)) !== null) {
patterns.push(match[2]);
}
return patterns;
}
function isBookmarklet(code){
return code.startsWith('javascript:')
}
function isMatchPattern(url, pattern) {
if (pattern.includes('*')) {
// Handle @include patterns with wildcards
const regex = new RegExp(
'^' +
pattern
.replace(/[-[\]{}()+!<=:?.\\^$|#\s,]/g, '\\$&')
.replace(/\*/g, '.*')
.replace(/\?/g, '.') +
'$'
);
return regex.test(url);
} else {
// Handle @match patterns
const matchPatternToRegExp = (pattern) => {
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
return new RegExp(
'^' +
escapeRegExp(pattern)
.replace(/\\\*/g, '.*')
.replace(/\\\?/g, '.') +
'$'
);
};
return matchPatternToRegExp(pattern).test(url);
}
}
function createIcon(iconType, onClick) {
const icon = document.createElement('div');
icon.textContent = iconType === 'smiley' ? '😊' : '⚠️';
icon.style.position = 'fixed';
icon.style.top = '10px';
icon.style.right = iconType === 'smiley' ? '50px' : '10px';
icon.style.fontSize = '24px';
icon.style.cursor = 'pointer';
icon.style.zIndex = '99999';
icon.addEventListener('click', onClick);
return icon;
}
function handleTestScript(code, sendResponse = () => {}) {
console.log(code, location.href)
if (isBookmarklet(code)){
code = code.substring('javascript:'.length)
}
try {
const executeScript = new Function('GM', code);
executeScript(GM);
sendResponse({
success: true,
message: 'Script executed successfully.',
});
document.body.appendChild(smileyIcon);
document.body.appendChild(alertIcon);
} catch (error) {
console.log(error, code)
sendResponse({
success: false,
message: error.message,
stackTrace: error.stack,
});
}
}
const gpt = GM.gpt()
alert('got gpt')
gpt.code.on('code', (handle) => {
handle.addAutomation((language, content) => {
if (language === 'javascript'){
handle.addAction('Run Here', (language, content) => {
handleTestScript(content, (response) => {
if (response.success){
alert('your code has been run')
} else {
$('textarea').val(`there was an error: ${JSON.stringify(response, null, 2)}`)
alert('your code threw an error, it has been inserted into your chat input')
}
})
})
}
})
})
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment