您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds ChatGPT into Instructure Canvas
当前为
- // ==UserScript==
- // @name Canvas ChatGPT
- // @namespace http://tampermonkey.net/
- // @version 1.3
- // @description Adds ChatGPT into Instructure Canvas
- // @author Riley Campbell
- // @match *.instructure.com/*
- // @license https://creativecommons.org/licenses/by-nc/4.0/
- // ==/UserScript==
- (async function() {
- 'use strict';
- if (window.location.href.indexOf("instructure.com") !== -1) {
- if (!window.location.href.includes("conversations")) {
- setInterval(function() {
- window.defaultMessage = {
- "role": "system",
- "content": localStorage.getItem('AIprompt')
- }
- }, 1000)
- let prompt = localStorage.getItem('AIprompt')
- if (prompt == null) {
- prompt = ''
- localStorage.setItem('AIprompt', '')
- }
- window.defaultMessage = {
- "role": "system",
- "content": prompt
- }
- window.AImessages = [window.defaultMessage]
- window.renderMessages = function() {
- let container = document.getElementById('container')
- container.innerHTML = ''
- for (let message in window.AImessages) {
- message = window.AImessages[message]
- if (message.role == "system") {
- continue
- }
- container.innerHTML += '<table><tr><th><p>' + message.role.charAt(0).toUpperCase() + message.role.slice(1) + ': </p></th><th style="white-space: break-spaces;">' + message.content + '</th></tr></table><hr class="solid">'
- }
- window.scrollTo({
- top: document.body.scrollHeight,
- behavior: 'smooth'
- });
- }
- window.sendMessage = async function() {
- document.getElementById('container').innerHTML += '<img style="display: block; width: 20px;margin-left: auto; margin-right: auto; margin-bottom:5px;" src="https://i.gifer.com/origin/34/34338d26023e5515f6cc8969aa027bca_w200.gif">'
- let message = {
- "role": "user",
- "content": document.getElementById('myTextArea').value
- }
- window.AImessages.push(message)
- document.getElementById('myTextArea').value = ''
- let messages = [window.defaultMessage, message]
- if (document.getElementById('memory').checked) {
- messages = window.AImessages
- }
- let response = await fetch('https://api.openai.com/v1/chat/completions', {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Authorization": `Bearer ` + localStorage.getItem('openaiAPIKey')
- },
- body: JSON.stringify({
- "model": localStorage.getItem('AImodel'),
- "messages": messages,
- "temperature": 1
- })
- });
- if (response.ok) {
- let result = await response.json()
- window.AImessages.push(result.choices[0].message)
- window.renderMessages()
- } else {
- document.getElementById('container').innerHTML = `Error ${response.status}: ${response.statusText}`;
- };
- }
- window.populateModels = async function() {
- let supportedModels = ['gpt-4', 'gpt-4-0314', 'gpt-4-32k', 'gpt-4-32k-0314', 'gpt-3.5-turbo', 'gpt-3.5-turbo-0301']
- let response = await fetch('https://api.openai.com/v1/models', {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- "Authorization": `Bearer ` + localStorage.getItem('openaiAPIKey')
- },
- });
- if (!response.ok) {
- return 0;
- }
- let options = await response.json()
- let item = null
- let element = null
- let models = document.getElementById('models')
- models.innerHTML = ''
- for (let i = 0; i < options.data.length; i++) {
- item = options.data[i]
- if (supportedModels.includes(item.id)) {
- element = document.createElement("option")
- element.value = item.id
- element.innerHTML = item.id
- models.appendChild(element)
- }
- }
- }
- let elem = document.createElement('div')
- elem.id='chatGPTbox'
- elem.setAttribute('style','margin-left:auto;margin-right:auto;width:95%')
- document.getElementById('wrapper').appendChild(elem)
- document.getElementById('chatGPTbox').innerHTML = `
- <style>
- .switch {
- position: relative;
- display: inline-block;
- width: 60px;
- height: 34px
- }
- .switch input {
- opacity: 0;
- width: 0;
- height: 0
- }
- .slider {
- position: absolute;
- cursor: pointer;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: #ccc;
- -webkit-transition: .4s;
- transition: .4s
- }
- .slider:before {
- position: absolute;
- content: "";
- height: 26px;
- width: 26px;
- left: 4px;
- bottom: 4px;
- background-color: #fff;
- -webkit-transition: .4s;
- transition: .4s
- }
- input:checked+.slider {
- background-color: #2196F3
- }
- input:focus+.slider {
- box-shadow: 0 0 1px #2196F3
- }
- input:checked+.slider:before {
- -webkit-transform: translateX(26px);
- -ms-transform: translateX(26px);
- transform: translateX(26px)
- }
- .slider.round {
- border-radius: 34px
- }
- .slider.round:before {
- border-radius: 50%
- }
- input[type="checkbox"] {
- display: none;
- }
- .wrap-collabsible {
- margin: 1.2rem 0;
- }
- .lbl-toggle {
- display: block;
- font-weight: bold;
- font-family: monospace;
- font-size: 1.2rem;
- text-transform: uppercase;
- text-align: center;
- padding: 1rem;
- color: #DDD;
- background: #0069ff;
- cursor: pointer;
- border-radius: 7px;
- transition: all 0.25s ease-out;
- }
- .lbl-toggle:hover {
- color: #FFF;
- }
- .lbl-toggle::before {
- content: " ";
- display: inline-block;
- border-top: 5px solid transparent;
- border-bottom: 5px solid transparent;
- border-left: 5px solid currentColor;
- vertical-align: middle;
- margin-right: .7rem;
- transform: translateY(-2px);
- transition: transform .2s ease-out;
- }
- .toggle:checked+.lbl-toggle::before {
- transform: rotate(90deg) translateX(-3px);
- }
- .collapsible-content {
- max-height: 0px;
- overflow: hidden;
- transition: max-height .25s ease-in-out;
- }
- .toggle:checked+.lbl-toggle+.collapsible-content {
- max-height: 350px;
- }
- .toggle:checked+.lbl-toggle {
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
- }
- .collapsible-content .content-inner {
- background: rgba(0, 105, 255, .2);
- border-bottom: 1px solid rgba(0, 105, 255, .45);
- border-bottom-left-radius: 7px;
- border-bottom-right-radius: 7px;
- padding: .5rem 1rem;
- }
- .collapsible-content p {
- margin-bottom: 0;
- }
- </style>
- <div class="ic-DashboardCard" style="padding:10px; color: ; margin-bottom:10px; width: 100%;margin-left:auto;margin-right:auto;">
- <div width=100% height=650px style="padding:10px;" id="container"></div>
- <textarea style="display: block; width: 95%; height: 100px; resize: none; margin-left: auto; margin-right: auto; margin-top:10px;" id="myTextArea"></textarea>
- <br>
- <button class="Button button-sidebar-wide" id=\'submitButton\' style="display: block; width: 95%;margin-left: auto; margin-right: auto; margin-top: 5px; margin-botton: 5px;">Clear History</button>
- <br>
- <div class="wrap-collabsible">
- <input id="collapsible" class="toggle" type="checkbox">
- <label for="collapsible" class="lbl-toggle">Settings</label>
- <div class="collapsible-content">
- <div class="content-inner">
- <table style="max-height:34px;">
- <tr style="max-height:34px;">
- <td>
- <label style="display:block; max-height:34px;" class="switch">
- <input id="memory" type="checkbox">
- <span class="slider round"></span>
- </label>
- </td>
- <td>
- <label style="display:block;max-height:34px;text-align: center;margin-top:auto;margin-bottom:auto;">Allow AI to remember past messages. (may incur extra charges)</label>
- </td>
- </tr>
- </table>
- <br>
- <label for="models">Model:</label>
- <select name="models" id="models"></select>
- <br>
- <textarea style="display: block; width: 95%; height: 100px; resize: none; margin-left: auto; margin-right: auto; margin-top:10px;" placeholder="Default System Prompt (Requires history to be cleared in order to take effect)" id="systemPrompt">` + localStorage.getItem('AIprompt') + `</textarea>
- <br>
- <input id="key" placeholder="API Key" type="text" style="display:block;float:left;"></input>
- <button class="Button button-sidebar-wide" id="setAPIKey" style="display: block;">Set API Key</button>
- </div>
- </div>
- </div>
- </div>
- `
- await window.populateModels()
- document.getElementById('models').value = localStorage.getItem('AImodel')
- let checked = (localStorage.getItem('AImemory') === 'true')
- document.getElementById('memory').checked = checked
- setInterval(function() {
- localStorage.setItem('AImemory', document.getElementById('memory').checked)
- localStorage.setItem('AImodel', document.getElementById('models').value)
- localStorage.setItem('AIprompt', document.getElementById('systemPrompt').value)
- }, 1000)
- document.getElementById('submitButton').onclick = async () => {
- window.AImessages = [window.defaultMessage]
- window.renderMessages()
- };
- document.getElementById('setAPIKey').onclick = async () => {
- localStorage.setItem('openaiAPIKey', document.getElementById('key').value)
- document.getElementById('key').value = ''
- await window.populateModels()
- };
- const myTextarea = document.getElementById("myTextArea");
- myTextarea.addEventListener("keydown", async function(event) {
- if (event.key === "Enter" && !event.shiftKey) {
- event.preventDefault();
- await window.sendMessage()
- }
- })
- };
- }
- })();