I spent hours trying to find someone who could make it simple. Thank you so much for making the video and being so generous with your sharing of the script.
This video is a godsend. I suck as a programmer, but I was beginning to investigate how to do exactly this for a curriculum project I'm working on. Thank you. Subscribed!
How to create a function that would prompt to summarizea long article (5k plus words) as input and would use chunking to read the whole article and give one output
I was able to implement this code and I really like it. I was wondering how I would be able to edit it to use Chat GPT 4, and/or preferably, be able to connect it to my paid GPT account and to a specific chat I have open with Chat GPT. I'm trying to have Chat GPT analyze a fiction work I'm writing, but with the text limit, it forgets what happens in the story all the time. I was hoping using this extension would solve the issue, but there's still a text limit. Is there any way to get around these issues?
So I attempted to fix this issue with this code: // Constants const API_KEY = "sk-xxxx"; const MODEL_TYPE = "gpt-3.5-turbo"; // Creates a custom menu in Google Docs function onOpen() { DocumentApp.getUi().createMenu("ChatGPT") .addItem("Generate Prompt", "generatePrompt") .addItem("Review Section", "generateIdeas") .addItem("Update ChatGPT on Story", "main") .addItem("Analyze and Provide Suggestions", "analyzeAndProvideSuggestions") .addItem("Generate Continuation Prompt", "generateContinuationPrompt") .addToUi(); } // Function to get Google Doc content starting from "Chapter 1" and log element types function getDocContent() { const doc = DocumentApp.getActiveDocument(); const body = doc.getBody(); const totalElements = body.getNumChildren(); let content = ""; let foundStartChapter = false; for (let i = 0; i < totalElements; ++i) { const element = body.getChild(i); const elementType = element.getType(); Logger.log("Element Type: " + elementType); // Log the element type if (element.getText) { Logger.log("Element Content: " + element.getText()); // Log content if it has a getText method } if (element.getText && element.getText().includes("Chapter 1")) { foundStartChapter = true; } if (foundStartChapter) { if (element.getText) { content += element.getText() + " "; } } } Logger.log("Content obtained: " + (content || "None")); // Log the content return content; } // Function to split the content into smaller segments function splitContent(content) { const maxLength = 900; const segments = []; let start = 0; while (start < content.length) { const segment = content.substring(start, start + maxLength); segments.push(segment); start += maxLength; } return segments; } // Function to send a segment to ChatGPT function sendSegmentToChatGPT(segment, context = "") { const prompt = context + segment; const temperature = 0; const maxTokens = 2000; const requestBody = { model: MODEL_TYPE, messages: [{role: "user", content: prompt}], temperature, max_tokens: maxTokens, }; const requestOptions = { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + API_KEY, }, payload: JSON.stringify(requestBody), }; const response = UrlFetchApp.fetch("api.openai.com/v1/chat/completions", requestOptions); const responseText = response.getContentText(); const json = JSON.parse(responseText); const generatedText = json['choices'][0]['message']['content']; Logger.log(generatedText); } function main() { const context = "Your high-level synopsis or sticky notes here."; const content = getDocContent(); const doc = DocumentApp.getActiveDocument(); const body = doc.getBody(); if (content === "") { body.appendParagraph("No content found starting from 'Chapter 1'."); return; } body.appendParagraph("Found content, proceeding to split and send to GPT-3."); const segments = splitContent(content); const scriptProperties = PropertiesService.getScriptProperties(); let lastProcessedIndex = scriptProperties.getProperty('lastProcessedIndex'); body.appendParagraph("LastProcessedIndex before: " + lastProcessedIndex); if (!lastProcessedIndex) { lastProcessedIndex = 0; } else { lastProcessedIndex = parseInt(lastProcessedIndex); } const maxIterations = 5; for (let i = lastProcessedIndex; i < Math.min(lastProcessedIndex + maxIterations, segments.length); i++) { body.appendParagraph(`Processing segment ${i + 1} of ${segments.length}`); sendSegmentToChatGPT(segments[i], context); scriptProperties.setProperty('lastProcessedIndex', i + 1); } body.appendParagraph("LastProcessedIndex after: " + scriptProperties.getProperty('lastProcessedIndex')); if (lastProcessedIndex + maxIterations >= segments.length) { scriptProperties.deleteProperty('lastProcessedIndex'); Logger.log("Processing completed."); } else { Logger.log("Partial processing completed. Run the script again to continue."); } Logger.log("Last processed index after update: " + scriptProperties.getProperty('lastProcessedIndex')); } function analyzeAndProvideSuggestions() { const doc = DocumentApp.getActiveDocument(); const body = doc.getBody(); // Get the content of the entire story const content = getDocContent(); // Set up the prompt with story context const prompt = "Analyze the following story and provide suggestions: " + content; const temperature = 0.7; // Adjust the temperature for creativity const maxTokens = 200; // You can adjust the max tokens based on the desired response length const requestBody = { model: MODEL_TYPE, messages: [{ role: "user", content: prompt }], temperature, max_tokens: maxTokens, }; const requestOptions = { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + API_KEY, }, payload: JSON.stringify(requestBody), }; const response = UrlFetchApp.fetch( "api.openai.com/v1/chat/completions", requestOptions ); const responseText = response.getContentText(); const json = JSON.parse(responseText); const generatedText = json["choices"][0]["message"]["content"]; // Append suggestions to the end of the document body.appendParagraph("Suggestions for improving your story:"); body.appendParagraph(generatedText); // Return the generated suggestions return generatedText; } // Create a function to generate prompts for continuing the story function generateContinuationPrompt() { const doc = DocumentApp.getActiveDocument(); const body = doc.getBody(); const selectedText = doc.getSelection().getRangeElements()[0].getElement().asText().getText(); // Get the context for the prompt const context = getDocContent(selectedText); // Get suggestions for continuing the story const suggestions = analyzeAndProvideSuggestions(context); // Append the suggestions to the document body.appendParagraph("Suggestions for continuing the story:"); body.appendParagraph(suggestions); } // Placeholder for your existing functions function generatePrompt() { const doc = DocumentApp.getActiveDocument(); const selectedText = doc.getSelection().getRangeElements()[0].getElement().asText().getText(); const body = doc.getBody(); const prompt = "Generate an essay on " + selectedText; const temperature = 0; const maxTokens = 2060; const requestBody = { model: MODEL_TYPE, messages: [{role: "user", content: prompt}], temperature, max_tokens: maxTokens, }; const requestOptions = { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + API_KEY, }, payload: JSON.stringify(requestBody), }; const response = UrlFetchApp.fetch("api.openai.com/v1/chat/completions", requestOptions); const responseText = response.getContentText(); const json = JSON.parse(responseText); const generatedText = json['choices'][0]['message']['content']; Logger.log(generatedText); body.appendParagraph(generatedText.toString()); } function generateIdeas() { const doc = DocumentApp.getActiveDocument(); const selectedText = doc.getSelection().getRangeElements()[0].getElement().asText().getText(); const body = doc.getBody(); const prompt = "Help me come up with ideas for this text based on the story so far. This is the text:" + selectedText; const temperature = 0; const maxTokens = 2060; const requestBody = { model: MODEL_TYPE, messages: [{role: "user", content: prompt}], temperature, max_tokens: maxTokens, }; const requestOptions = { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + API_KEY, }, payload: JSON.stringify(requestBody), }; const response = UrlFetchApp.fetch("api.openai.com/v1/chat/completions", requestOptions); const responseText = response.getContentText(); const json = JSON.parse(responseText); const generatedText = json['choices'][0]['message']['content']; Logger.log(generatedText); body.appendParagraph(generatedText.toString()); } But I'm having a lot of issues with it. It keeps looping through my document and the Analyze function doesn't seem to be able to get the information from the document to use as context. Any advice?
Thank you for the video, super helpful. I wonder, can we train the ChatGPT with specific link (ex: Company's FAQ knowledge based) so when we try to generate articles, the source of the GPT is coming from that "specific link"? pardon for the noob question!
In general, LLMs are not good to work on tabular data, only natural language. You could translate this data into natural language and feee it to the LLM.
Hello, Thank you for this amazing tutorial. How can I make it works for several lines / short paragraphs ? It seems that it stops working/sending the text as soon as it reaches a line break.
This is incredible, absolutely love it!! Thank you. I tweaked the code a bit to suit my own purposes, but only running into one minor issue. It seems like the 2nd option I added in ignores the selected text and just covers the entire text, not sure why. My first option is used to generate a blog outline based on the highlighted text, and my 2nd option is supposed to generate body content for the blog based on the section I highlight from the outline. But when I run the body generator, it just generates body sections for the entire blog outline instead of only my highlighted section. Any suggestions? :) -- either way, this is a gamechanger! Thanks again
any tips on how to deal with texts that exceed the character limit? I want to use chat gpt to summarise podcast episodes giving the transcript as input
I was able to successfully add the extension. However next time when I went to the google docs, the extension was not present. I had to reconfigure it again. How can I save this permanently?
Do I understand correctly that this only works with the paid plan? My answer is "You have exceeded your current quota, please check your plan and billing information".
Very nice bro. Now, If only I know how to code, I think I can make a lot of tools for many small business people. BTW, how much does it cost to generate 2000 words in chatGPT?
Hi, thanks for that BUT all I did was add my API key into your code, saved and ran but I get the error: 10:38:54 AM Error Exception: Cannot call DocumentApp.getUi() from this context. onOpen @ Code.gs:7 only added my API into your code, I didn't change anything else, can you please tell me what's wrong? Thank you
I figured it out. Don't delete the function when you first come to the code. You have to paste his code INSIDE the function {} brackets that already exist and it will work.