avatarTristan Wolff

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

6411

Abstract

s_">DocumentApp</span>.<span class="hljs-title function_">getActiveDocument</span>(); <span class="hljs-keyword">const</span> userText = doc.<span class="hljs-title function_">getSelection</span>().<span class="hljs-title function_">getRangeElements</span>()[<span class="hljs-number">0</span>].<span class="hljs-title function_">getElement</span>().<span class="hljs-title function_">asText</span>().<span class="hljs-title function_">getText</span>(); <span class="hljs-keyword">const</span> prompt = <span class="hljs-string">Use this idea to create a comic strip consisting of four images but answer only with brief image captions for the four images: <span class="hljs-subst">${userText}</span> \n</span>; <span class="hljs-title function_">callOpenAiAPI</span>(prompt, doc); }

<span class="hljs-keyword">function</span> <span class="hljs-title function_">textAsPrompt</span>(<span class="hljs-params"></span>) { <span class="hljs-keyword">const</span> doc = <span class="hljs-title class_">DocumentApp</span>.<span class="hljs-title function_">getActiveDocument</span>(); <span class="hljs-keyword">const</span> userText = doc.<span class="hljs-title function_">getSelection</span>().<span class="hljs-title function_">getRangeElements</span>()[<span class="hljs-number">0</span>].<span class="hljs-title function_">getElement</span>().<span class="hljs-title function_">asText</span>().<span class="hljs-title function_">getText</span>(); <span class="hljs-keyword">const</span> prompt = <span class="hljs-string"><span class="hljs-subst">${userText}</span></span>; <span class="hljs-title function_">callOpenAiAPI</span>(prompt, doc); }

<span class="hljs-keyword">function</span> <span class="hljs-title function_">callOpenAiAPI</span>(<span class="hljs-params">prompt, doc</span>) { <span class="hljs-keyword">const</span> body = doc.<span class="hljs-title function_">getBody</span>(); <span class="hljs-keyword">const</span> temperature = <span class="hljs-number">0.83</span>; <span class="hljs-keyword">const</span> maxTokens = <span class="hljs-number">2060</span>; <span class="hljs-keyword">const</span> requestBody = { <span class="hljs-attr">model</span>: <span class="hljs-variable constant_">MODEL_TYPE</span>, <span class="hljs-attr">messages</span>: [{<span class="hljs-attr">role</span>: <span class="hljs-string">"user"</span>, <span class="hljs-attr">content</span>: prompt}], temperature, <span class="hljs-attr">max_tokens</span>: maxTokens, };

<span class="hljs-keyword">const</span> options = { <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>, <span class="hljs-attr">headers</span>: { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>, <span class="hljs-title class_">Authorization</span>: <span class="hljs-string">"Bearer "</span> + <span class="hljs-variable constant_">OPENAI_API_KEY</span>, }, <span class="hljs-attr">payload</span>: <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(requestBody), };

<span class="hljs-keyword">const</span> response = <span class="hljs-title class_">UrlFetchApp</span>.<span class="hljs-title function_">fetch</span>(<span class="hljs-string">"https://api.openai.com/v1/chat/completions"</span>, options); <span class="hljs-keyword">const</span> responseText = response.<span class="hljs-title function_">getContentText</span>(); <span class="hljs-keyword">const</span> json = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(responseText); <span class="hljs-keyword">const</span> generatedText = json[<span class="hljs-string">'choices'</span>][<span class="hljs-number">0</span>][<span class="hljs-string">'message'</span>][<span class="hljs-string">'content'</span>];

<span class="hljs-title class_">Logger</span>.<span class="hljs-title function_">log</span>(generatedText); body.<span class="hljs-title function_">appendParagraph</span>(generatedText.<span class="hljs-title function_">toString</span>()); }

</pre></div><p id="6cc4">Your Code.gs file should now resemble the following:</p><figure id="efb7"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*_SR1CD7JT7dV0HtJeRONSA.png"><figcaption></figcaption></figure><h1 id="9184">Step 5: Save the script and run it</h1><p id="04e2">It’s time to save your work and test the script. Click the little 💾 item in the top menu to save the App Script.</p><p id="188e">This will enable the “Run” button. Make sure that it says “onOpen” next to it (this is the function we want to run when the script starts). Click “Run”.</p><figure id="1426"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*R12vo2pPrrQXsjjDkNZkyQ.png"><figcaption></figcaption></figure><p id="a01f">You will now be asked to review the permissions of the script. Since we will be calling an external service (the OpenAI server), Google asks us whether we trust this script and its external service.</p><p id="c7a2">Since we do, click on “Advanced” and then “Go to [your script’s name] (unsafe)”. Log in with your account and click “Allow”.</p><p id="e327">The “unsafe” tag is Google’s default assumption here, it is safe to use (well, keep in mind that you will pay for text generations on a token basis: 1000 tokens generated by GPT 3.5 will cost 0.002, if you switch to GPT 4 then you’ll have to pay 0.06 for the same amount of tokens)</p><figure id="1eea"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*PvGHyqot92RaZm0gpcLmuA.png"><figcaption></figcaption></figure><figure id="804f"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*JQAkd2M3idOHlw_YLqJYCQ.png"><figcaption></figcaption></figure><figure id="725f"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*GQBxQCRsAFuvBpXpLU-naA.png"><figcaption></figcaption></figure><h1 id="6dd6">Step 6: Test the script and customize it</h1><p id="5044">Once you reload your initial Google Doc, you will see a new menu called “AI Tools”.</p><figure id="4123"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*4ob9An1e-B5YzivoTO7Xxg.png"><figcaption></figcaption></figure><p id="d97e">Three menu items showcase some of the possibilities you now have inside your Google Doc. If you highlight something and click o

Options

ne of the items the highlighted text will be processed accordingly.</p><figure id="7354"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*rJU8vUYHDG2qp0h_A8Iyww.png"><figcaption></figcaption></figure><figure id="6bea"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*Jy6iMBZ0eJdR95l4MdXV9g.png"><figcaption></figcaption></figure><h2 id="13d6">Customization</h2><p id="3cfe">Now, it’s time to change the script according to your needs. So, let’s have a look at the code real quick (navigate back to “Extensions” > “App Scripts” and choose the file we just worked with: “Code.gs”)</p><p id="0692">You will find a function called “onOpen” which is responsible for creating the new menu and the three menu items.</p><div id="618e"><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">onOpen</span>(<span class="hljs-params"></span>) { <span class="hljs-title class_">DocumentApp</span>.<span class="hljs-title function_">getUi</span>().<span class="hljs-title function_">createMenu</span>(<span class="hljs-string">"AI Tools"</span>) .<span class="hljs-title function_">addItem</span>(<span class="hljs-string">"Create title/subtitle suggestions"</span>, <span class="hljs-string">"generateTitles"</span>) .<span class="hljs-title function_">addItem</span>(<span class="hljs-string">"Create 4 panel comic story"</span>, <span class="hljs-string">"fourPanelStory"</span>) .<span class="hljs-title function_">addItem</span>(<span class="hljs-string">"Use highlighted text as prompt"</span>, <span class="hljs-string">"textAsPrompt"</span>) .<span class="hljs-title function_">addToUi</span>(); }</pre></div><p id="8360">Each menu item has a corresponding function listed right next to the menu item’s name. For example, the menu item</p><p id="7346"><b>“Create title/subtitle suggestions”</b></p><p id="ad90">comes with a function called</p><p id="4cc7"><b>“generateTitles”</b></p><p id="0aff">If you scroll down a bit, you’ll see this function and how the underlying <a href="https://readmedium.com/mastering-chatgpt-five-advanced-prompt-techniques-you-should-consider-c0da587b74bf">prompt</a> is defined.</p><div id="022b"><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">generateTitles</span>(<span class="hljs-params"></span>) { <span class="hljs-keyword">const</span> doc = <span class="hljs-title class_">DocumentApp</span>.<span class="hljs-title function_">getActiveDocument</span>(); <span class="hljs-keyword">const</span> userText = doc.<span class="hljs-title function_">getSelection</span>().<span class="hljs-title function_">getRangeElements</span>()[<span class="hljs-number">0</span>].<span class="hljs-title function_">getElement</span>().<span class="hljs-title function_">asText</span>().<span class="hljs-title function_">getText</span>(); <span class="hljs-keyword">const</span> prompt = <span class="hljs-string">Create a bunch of titles and subtitles for the following topic: "<span class="hljs-subst">${userText}</span>"</span>; <span class="hljs-title function_">callOpenAiAPI</span>(prompt, doc); }</pre></div><p id="a76b">In this case, whenever the menu item “Create title/subtitle suggestions” is clicked, the momentarily highlighted text area will be combined with this prompt and sent to OpenAI’s text completion model GPT 3.5.</p><p id="066d">Here’s the prompt alone:</p><div id="3c10"><pre>Create a <span class="hljs-keyword">bunch </span>of titles <span class="hljs-keyword">and </span><span class="hljs-keyword">subtitles </span>for the following topic: <span class="hljs-string">"{userText}"</span></pre></div><p id="5d06"><b>The {userText} part is the placeholder for the highlighted text from your Google Doc.</b></p><p id="7043">Now you can go on and change the menu name, its items, and the corresponding prompts.</p><h2 id="6679">Changing max tokens & temperature</h2><p id="4de8">You can also change the settings for your OpenAI API call here:</p><div id="b6d9"><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">callOpenAiAPI</span>(<span class="hljs-params">prompt, doc</span>) { <span class="hljs-keyword">const</span> body = doc.<span class="hljs-title function_">getBody</span>(); <span class="hljs-keyword">const</span> temperature = <span class="hljs-number">0.83</span>; <span class="hljs-keyword">const</span> maxTokens = <span class="hljs-number">2060</span>; <span class="hljs-keyword">const</span> requestBody = { <span class="hljs-attr">model</span>: <span class="hljs-variable constant_">MODEL_TYPE</span>, <span class="hljs-attr">messages</span>: [{<span class="hljs-attr">role</span>: <span class="hljs-string">"user"</span>, <span class="hljs-attr">content</span>: prompt}], temperature, <span class="hljs-attr">max_tokens</span>: maxTokens, };</pre></div><p id="d765">That’s it.</p><p id="a5d4">If you have any questions, feel free to comment on this article or reach out to me here on Medium or Twitter. Have fun exploring! 🚀</p><p id="78b3">➡️ For more information about <a href="https://fabulous-maker-2733.ck.page/da150f448e">AI & Creativity</a>, follow me on <a href="http://twitter.com/tristwolff">Twitter</a> or Medium (<a href="https://medium.com/@tristwolff/membership">use my referral link to get full access to all my articles</a> and those of thousands of other writers).</p><div id="09b1" class="link-block"> <a href="https://medium.com/@tristwolff/membership"> <div> <div> <h2>Join Medium with my referral link - Tristan Wolff</h2> <div><h3>Read every story from Tristan Wolff (and thousands of other writers on Medium). Your membership fee directly supports…</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*vVBC6jKjFvdYC55e)"></div> </div> </div> </a> </div><p id="c1cd">➡️ If you like my content, why not leave a “clap” at the end of this article, so more people can see it?</p><p id="727a"><i>Stay updated with the latest news and updates in the creative AI space — follow the <a href="https://medium.com/generative-ai">Generative AI</a> publication.</i></p></article></body>

Streamline Your Productivity with ChatGPT in Google Docs

A Beginner’s Guide to Crafting Your Own Google Docs Plugin in Just 6 Steps

Image by author & Midjourney

In this guide, you’ll learn how to create your own AI plugin for use with Google Docs. To do this, we will use OpenAI’s language models, GPT-3.5 or GPT-4, which are powering ChatGPT. Let’s dive right in.

Step 1: Create a new document & name it

Create a new Google document or use a shortcut: type “docs.new” into your browser’s address bar.

The AI plugin we are about to create will only work in this document, so name it in order to be able to find it again later (in this demo, I called mine “AI Assistant”).

Step 2: Create a new Apps Script & name it

Navigate to “Extensions” > “Apps Scripts” and in the top left give your new Apps Script a name.

Apps Script is a scripting language that lets us automate tasks in Docs or Sheets.

Step 3: Add OpenAI API keys

In order to use OpenAI’s GPT 3.5 or GPT 4 (the models that are powering their ChatGPT interface), we need to add an API key to our Google App Script.

You can use an existing OpenAI API key or create a new one in your OpenAI account by navigating to “platform.openai.com”, clicking on “API keys” or “View API keys” in your account menu, and creating a new API key.

Once you have your OpenAI API key ready, navigate to “Project Settings” in your App Script …

… and scroll all the way down to “Script Properties”, then click “Add script property”

Name the new property “OPENAI_API_KEY” and copy/paste your OpenAI API key into the “Value” field.

Step 4: Adding the script

Finally, navigate back to the App Script’s code editor (the “<>” symbol in the left menu) and click on “Code.gs”, the main script file we are now going to edit:

Replace the 3 lines of code in Code.gs with this:

const MODEL_TYPE = "gpt-3.5-turbo";
const OPENAI_API_KEY = PropertiesService.getScriptProperties().getProperty('OPENAI_API_KEY');

function onOpen() {
  DocumentApp.getUi().createMenu("AI Tools")
      .addItem("Create title/subtitle suggestions", "generateTitles")
      .addItem("Create 4 panel comic story", "fourPanelStory")
      .addItem("Use highlighted text as prompt", "textAsPrompt")
      .addToUi();
}

function generateTitles() {
  const doc = DocumentApp.getActiveDocument();
  const userText = doc.getSelection().getRangeElements()[0].getElement().asText().getText();
  const prompt = `Create a bunch of titles and subtitles for the following topic: "${userText}"`;
  callOpenAiAPI(prompt, doc);
}

function fourPanelStory() {
  const doc = DocumentApp.getActiveDocument();
  const userText = doc.getSelection().getRangeElements()[0].getElement().asText().getText();
  const prompt = `Use this idea to create a comic strip consisting of four images but answer only with brief image captions for the four images: ${userText} \n`;
  callOpenAiAPI(prompt, doc);
}

function textAsPrompt() {
  const doc = DocumentApp.getActiveDocument();
  const userText = doc.getSelection().getRangeElements()[0].getElement().asText().getText();
  const prompt = `${userText}`;
  callOpenAiAPI(prompt, doc);
}

function callOpenAiAPI(prompt, doc) {
  const body = doc.getBody();
  const temperature = 0.83;
  const maxTokens = 2060;
  const requestBody = {
    model: MODEL_TYPE,
    messages: [{role: "user", content: prompt}],
    temperature,
    max_tokens: maxTokens,
  };

  const options = {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: "Bearer " + OPENAI_API_KEY,
    },
    payload: JSON.stringify(requestBody),
  };

  const response = UrlFetchApp.fetch("https://api.openai.com/v1/chat/completions", options);
  const responseText = response.getContentText();
  const json = JSON.parse(responseText);
  const generatedText = json['choices'][0]['message']['content'];

  Logger.log(generatedText);
  body.appendParagraph(generatedText.toString());
}

Your Code.gs file should now resemble the following:

Step 5: Save the script and run it

It’s time to save your work and test the script. Click the little 💾 item in the top menu to save the App Script.

This will enable the “Run” button. Make sure that it says “onOpen” next to it (this is the function we want to run when the script starts). Click “Run”.

You will now be asked to review the permissions of the script. Since we will be calling an external service (the OpenAI server), Google asks us whether we trust this script and its external service.

Since we do, click on “Advanced” and then “Go to [your script’s name] (unsafe)”. Log in with your account and click “Allow”.

The “unsafe” tag is Google’s default assumption here, it is safe to use (well, keep in mind that you will pay for text generations on a token basis: 1000 tokens generated by GPT 3.5 will cost $0.002, if you switch to GPT 4 then you’ll have to pay $0.06 for the same amount of tokens)

Step 6: Test the script and customize it

Once you reload your initial Google Doc, you will see a new menu called “AI Tools”.

Three menu items showcase some of the possibilities you now have inside your Google Doc. If you highlight something and click one of the items the highlighted text will be processed accordingly.

Customization

Now, it’s time to change the script according to your needs. So, let’s have a look at the code real quick (navigate back to “Extensions” > “App Scripts” and choose the file we just worked with: “Code.gs”)

You will find a function called “onOpen” which is responsible for creating the new menu and the three menu items.

function onOpen() {
  DocumentApp.getUi().createMenu("AI Tools")
      .addItem("Create title/subtitle suggestions", "generateTitles")
      .addItem("Create 4 panel comic story", "fourPanelStory")
      .addItem("Use highlighted text as prompt", "textAsPrompt")
      .addToUi();
}

Each menu item has a corresponding function listed right next to the menu item’s name. For example, the menu item

“Create title/subtitle suggestions”

comes with a function called

“generateTitles”

If you scroll down a bit, you’ll see this function and how the underlying prompt is defined.

function generateTitles() {
  const doc = DocumentApp.getActiveDocument();
  const userText = doc.getSelection().getRangeElements()[0].getElement().asText().getText();
  const prompt = `Create a bunch of titles and subtitles for the following topic: "${userText}"`;
  callOpenAiAPI(prompt, doc);
}

In this case, whenever the menu item “Create title/subtitle suggestions” is clicked, the momentarily highlighted text area will be combined with this prompt and sent to OpenAI’s text completion model GPT 3.5.

Here’s the prompt alone:

Create a bunch of titles and subtitles for the following topic: "${userText}"

The ${userText} part is the placeholder for the highlighted text from your Google Doc.

Now you can go on and change the menu name, its items, and the corresponding prompts.

Changing max tokens & temperature

You can also change the settings for your OpenAI API call here:

function callOpenAiAPI(prompt, doc) {
  const body = doc.getBody();
  const temperature = 0.83;
  const maxTokens = 2060;
  const requestBody = {
    model: MODEL_TYPE,
    messages: [{role: "user", content: prompt}],
    temperature,
    max_tokens: maxTokens,
  };

That’s it.

If you have any questions, feel free to comment on this article or reach out to me here on Medium or Twitter. Have fun exploring! 🚀

➡️ For more information about AI & Creativity, follow me on Twitter or Medium (use my referral link to get full access to all my articles and those of thousands of other writers).

➡️ If you like my content, why not leave a “clap” at the end of this article, so more people can see it?

Stay updated with the latest news and updates in the creative AI space — follow the Generative AI publication.

Artificial Intelligence
Productivity
Creativity
Writing
ChatGPT
Recommended from ReadMedium