DEV Community

ocomoji
ocomoji

Posted on

A beginner tried making a SlackBot app with [ChatGPT + GAS]

self-introduction

Nice to meet you, I'm K, an engineer at ocomoji.
I made a SlackBot app with GAS using the recently popular ChatGPT API, so I'll introduce it.

Introduction

I use Slack as a communication tool at work,
so Slack is always running, but to use chatGPT, I had to start the browser every
time . That's right, if you create a chatGPT BOT application with Slack, you can solve it !?
"
Since it was my first time, I developed it while researching from scratch
(80% thanks to articles by others ^^;)

what i wanted to do

Create a bot that returns an answer from chatGPT when you post on a channel that the created SlackBot is participating in

Advance preparation

Slack, GAS (GoogleAppsScript), and OpenAI (chatGPT) accounts must be prepared and ready to use (including permissions)

Development table of contents

  1. Create a URL for receiving post events from Slack with GAS

  2. Create a SlackBot app

  3. Get a token to use the SlackBot app

  4. Add Slack library to GAS

  5. Get a member ID to use the SlackBot app

  6. Get an API key to use chatGPT

  7. Link SlackBot app and chatGPT to GAS ~Settings~

  8. Add the SlackBot app to your Slack channel

  9. Connect SlackBot app and chatGPT to GAS

  10. [Troubleshooting] Operation check - Communication - [GAS + SlackBot]

  11. [Troubleshooting] Operation check - communication - [GAS + chatGPT]

  12. [Troubleshooting] Secret trick

1. Create a URL for receiving post events from Slack in GAS

Enable GAS to receive posts from Slack

1.Start GAS ( https://script.google.com/home )

2.Press new project (project name and file name are optional)

3.Overwrite the existing code with the following code (overwrite with the save project button)

//Receive post from Slack
    function doPost(e) {
        //Parse received data (parse and extract data) 
        const postParam = JSON.parse(e.postData.getDataAsString());

        //Challenge authentication
        //①This authentication process is NG
        /*
        if (postParam.type === 'url_verification') {
            return ContentService.createTextOutput(postParam.challenge);
        }
        */

        //②This authentication process is OK
        if('challenge' in postParam){
            return ContentService.createTextOutput(postParam .challenge); return}
Enter fullscreen mode Exit fullscreen mode

 * The function name "doPost" is an event (reserved word ) so do not change it arbitrarily (I thought it was a non-reserved word)
It didn't work well When I
 looked into other articles, 2 authentication was also introduced, so when I implemented it, it worked well Has the
 GAS specification changed?

4.Deployment execution

(Deployment → New deployment → Select type: Web application → Accessible users: Everyone → Press deploy button)

Image description

5.On the deployment completion screen, copy the URL of the web application and
press the memo completion button.

Image description
We will check in step 2 to see if authentication from Slack to GAS has passed, so please try creating it in order 1 for the time being.

2. Create a SlackBot app

The SlackBot app page is in English, so it's hard to see ^^;
1.Launch SlackAPI ( https://api.slack.com/apps )
2.Press Create New App Select
From scratch Select
App Name and Pick a workspace to develop your app in
*The name of the app I created this time is "chatGPT2" Press
Create App
3.Press Event Subscriptions on the sidebar Toggle Enable Events and paste the URL for receiving post events from Slack (URL created in order 1) in
On Request URL *Authentication succeeded when Verified is displayed! Add the following event with Subscribe to bot events → Add Bot User Event  app_mention: Specify mention  message.channels: Post message to channel Press Save Changes

Image description
4.Press OAuth & Permissions on the sidebar Add
the following scopes with Scopes → Bot Token Scopes → Add an OAuth Scope
 chat: write: message
 posting Press
for Your Workspace
 Install to Workspace Press
 Allow

Image description

3. Get a token to use the SlackBot app

Get a token for your SlackBot app (something like an ID)
1.Launch SlackAPI ( https://api.slack.com/apps )
2.Press OAuth & Permissions in the sidebar
3.Copy OAuth Tokens for Your Workspace Bot User OAuth Token and make a note of it

Image description

4. Add Slack library to GAS

Add SlackAPI library to GAS
1.Start GAS ( https://script.google.com/home )
2.Press + on Library
3.Add library
4.Copy and paste the following ID in the script ID and press search[1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bqbr]
5.Press the add button (version and ID are OK with the initial values)

Image description

5. Add SlackBot app to Slack and get member ID

Add the created bot app to Slack and get the member ID
1.Launch Slack
2.Sidebar → Add application → Search by chatGPT2 → Press the corresponding application
3.Since chatGPT2 is added to the sidebar, press chatGPT2 to launch the profile

Image description
4.Copy the member ID and make a note of it

Image description

6. Get an API key to use chatGPT

1.Launch OpenAI ( https://platform.openai.com/overview )
2.login
3.Click on your account icon on the top right
4.Press View API keys
5.Press Create new secret key
6.The displayed key is your API key. copy and note

Image description

7. Connect SlackBot app and chatGPT to GAS ~Settings~

Configure SlackBot app and chatGPT linkage settings to GAS
1.Start GAS ( https://script.google.com/home )
2.Press the gear mark (settings) on the sidebar
3.Press Add script property and add three as shown in the image below
 openApiKey: OpenAI's API key for using chatGPT. Get from OpenAI account (order 6)
 slackBotId: SlackBot app member ID. Get from Slack app (order 5)
 slackBotToken: SlackBot app token. Get from browser. Bot User OAuth Token (order 3)
4.Press save script properties

Image description

8. Add the SlackBot app to your Slack channel

1.Launch Slack
2.Press any channel to launch the property screen
3.Press integration on the top tab
4.press add app
5.The created SlackBot (chatGPT2) will appear in the list, so press Add

Image description

9. Connect SlackBot app and chatGPT to GAS ~Code~

Implemented SlackBot and chatGPT linkage to GAS
1.Start GAS ( https://script.google.com/home )
2.Overwrite the existing code in GAS with the following code (overwrite with the save project button)

    //Receive posts from Slack
    //**********  START Main **********
    function doPost(e) {
      //Parse received data Extraction
      const postParam = JSON.parse(e.postData.getDataAsString());

      //Challenge authentication

      //1.This authentication process is NG
      /*
      if (postParam.type === 'url_verification') {
        return ContentService.createTextOutput(postParam.challenge);
      }
      */

      //2. OK with this authentication process
      if('challenge' in postParam){
        return ContentService.createTextOutput(postParam.challenge);
      }

      //3.Return the sentence to the channel posted on Slack
      //sendSlack(postParam.event.channel, 'Catch the post from Slack! GAS will reply!');

      //Event retransmission avoidance
      //Processed if loaded in cache
      //Stacked in cache if unprocessed (validity period 5m)
      const event_id = postParam.event_id;
      const cache = CacheService.getScriptCache();
      const isProcessed = cache.get(event_id);

      if (isProcessed) return;

      cache.put(event_id, true, 601);

      //event with subtype set 
      if('subtype' in postParam.event) return;

      //When sent by ChatGPTBot
      //Create a response message in ChatGPT and send it to Slack
      const botId = PropertiesService.getScriptProperties().getProperty('slackBotId');
      if (postParam.event && postParam.event.user !== botId) {
        const channel = postParam.event.channel;
        const text = postParam.event.text;
        var message = requestChatGPT(text);

        sendSlack(channel, message);
      }

      return;
    }
    //**********  END MAIN **********


    //4. **********  START [Troubleshooting] Operation check - communication - [GAS + chatGPT] **********
    function testGAStoChatGPT() {
      console.log(requestChatGPT(" What is chatGPT?"));
    }
    //**********  END [Troubleshooting] Operation check - communication - [GAS + chatGPT] **********


    //**********  START Send message through SlackBots **********
    //20230301 Confirmed that this works by itself
    function sendSlack(channel, message) {
      const slackToken = PropertiesService.getScriptProperties().getProperty('slackBotToken');
      const slackApp = SlackApp.create(slackToken);
      slackApp.postMessage(channel, message);
    }
    //**********  END Send message through SlackBots**********


    //**********  START Send text to ChatGPT and get response message **********
    //20230301 20230301 Confirmed that this works by itself
    function requestChatGPT(message) {

      const apiKey = PropertiesService.getScriptProperties().getProperty('openApiKey');
      const apiUrl = 'https://api.openai.com/v1/chat/completions';

      //Request Data Settings
      const headers = {
        'Authorization':'Bearer '+ apiKey,
        'Content-type': 'application/json'
      };
      const options = {
        'headers': headers, 
        'method': 'POST',
        'payload': JSON.stringify({
          //Specify model gpt-3.5-turbo:chatGPT text-davinci-003:GPT-3
          'model': 'gpt-3.5-turbo',
          //Specify the maximum number of tokens in the generated text. like word count
          'max_tokens' : 1500,
          //If you specify 0.5, the generated sentences tend to be similar to the input sentence
          //If you specify 1.0, the generated sentences will be more diverse
          'temperature': 0.5,
          //Specify a query string
          'messages': [{ role: "user", content: message }]
        })
      };

      //Send a request and get the result
      const response = JSON.parse(UrlFetchApp.fetch(apiUrl, options).getContentText());
      const resMessage = response.choices[0].message.content;

      return resMessage;
    }
    //********** END Send text to ChatGPT and get response message **********

Enter fullscreen mode Exit fullscreen mode

3.Redeploy with the following procedure
1.Deployments → Manage Deployments → Pencil Mark (Edit)
2.Press the version and select [New version] *1
3.press deploy
4.Press Approve access
5.After that, permission confirmation for access appears several times, but all are permitted

*If there is an error in the redeployment procedure,
 the URL will be different from the web application URL when SlackBots was created, and it will not work

Image description
4.Mention your bot and ask questions in any channel where you
added the SlackBot app
5.Answers are returned from the SlackBot app
6.Cooperation success! good job for today!

Image description

10. [Troubleshooting] Communication check [GAS → SlackBot]

If there is no reply from SlackBot, perform a communication test to see if GAS and SlackBot are linked Communication
flow: Slack → GAS → chatGPT → GAS → Slack
1,Start GAS ( https://script.google.com/home )
2.Uncomment 3 in the existing code (order 9) (delete the slash)
//sendSlack~~ → sendSlack~~
3.Redeploy (order 9-3)
4.@mention the bot in any channel where you added the SlackBot app and send an appropriate message
5.From the SlackBot app, "Catch posts from Slack OK! I will reply from GAS! If you receive a reply that says, the
communication is successful.
6.Communication test success: Check the communication of GAS → chatGPT → GAS in the following order
Communication test failure: Review the settings between GAS and Slack
(For now, ignore chatGPT and implement simple processing with GAS + Slack and test good)
7.Return the comment at 3 in the existing code (order 9) (restore the slash slash)
sendSlack~~ → //sendSlack~~
8.Redeploy and return to the original state (order 9-3)

Image description

11. [Troubleshooting] Communication check [GAS → chatGPT → GAS]

If there is a reply from GAS to SlackBot but no reply from chatGPT (order 10 is a successful state), perform a communication test to see if GAS and chatGPT are linked Communication flow: Slack → GAS → chatGPT
→ GAS → Slack

1.Start GAS ( https://script.google.com/home )
2.Select function: testGAStoChatGPT from the right side of debug in the top menu

  • Execute the function prepared in the existing code (order 9) 3.Press the execution of the upper menu 4.Successful communication when an answer from chtatGPT arrives in the execution log at the bottom

5.Successful communication test:
 Check Slack → GAS communication. You can ignore it and implement a simple process with GAS + chatGPT and test it.)

Image description

12. [Troubleshooting] Tricks

If it doesn't work so far, please delete the created GAS/SlackBot app and try to create it from 1. But it doesn't work when it comes to the integration test><' I didn't know the cause, so I thought it would be better to hurry, so I recreated it from order 1 and it worked normally.

struggled

1.Challenge authentication (order 1)

2.It worked at the component level, but it didn't work when combined (correspond in order  12
)
There seems to be a way, so if I could do that, I might have been able to develop efficiently.
 
3.Struggling with JavaScript in GAS
There is "function doPost (e) {" in the code (order 9), but I recognized it as "a function that receives posts from Slack named doPost" I found out later (because I referred to other people's articles for this part),
but doPost was "a GAS-only event that receives posts from Slack, not a function" *To be exact, it is an event
that accepts HTTP POST .

without realizing it, where are the post events from Slack? I was confused and had a hard time understanding the code. Cry
doPost The function name is difficult to understand, so let's change it! By taking action, the parts that had been working until now stopped working, and it was even more confusing... If you search for "GAS doPost", the explanation article will be staggered, and it will be easily resolved
. later in my impressions

4.Slack, GAS, and chatGPT_API are used, and the procedure is long and I feel like I'm going to break my heart!
Patience is required

Impressions after trying to make it

In order to realize this project, it was necessary to understand three tools: GAS, Slack application, and chatGPT_AI
. When I tried to create it, I had a hard time, but I was able to realize it surprisingly easily (thanks to the article of others )

. It must be a function because it has a function, but there is no event that executes
this function anywhere!" I thought so based on my experience and intuition
.・ There are many cases where [relying on one's own experience and intuition] leads to shortcuts, but it's not everything, and sometimes it's also important to [question one's own experience and intuition].It was a good experience for the first time . It's something I use, so I think I could have developed it without having to struggle in strange places if I researched more in advance about what GAS is, what is a Slack app, etc. Create a bot that returns an answer from]

This is what I wanted to do.
Future tasks will be described below, but I hope that I can update it from time to time because it is a bot that can still grow.

Future tasks

1.Learn the log output function of GAS
2.Use jQuery library with GAS
3.Reply to thread from bot
4.Reply speed from bot UP
5.Character settings (ocomoji-kun!)

bonus

After changing and redeploying part of the existing code 2.(order 9) that I had chatGPT itself check for [lie], which is a weak point of chatGPT, I

threw a question to the bot as follows.

//If ChatGPTBot sent //Create a response message in ChatGPT and send it to Slack const botId = PropertiesService.getScriptProperties ( ) . getProperty ( ' slackBotId ' ) ; if ( postParam.event && postParam.event.user ! = = botId ) { const channel = postParam.event.channel ; const text = postParam.event.text ; _ _ _ _ _ _ _ _


        var message = requestChatGPT ( text ); // Let yourself do a fact check 
        sendSlack ( channel , "[Before fact check]\n" + message );  
        message = "Fact check the following and then reply again \n\n" + message ; 
        message = requestChatGPT ( message ); 
        sendSlack ( channel , "[after fact check]\n" + message ) ;
Enter fullscreen mode Exit fullscreen mode

Image description

Kashima City doesn't have Kashima Higashi High School or Kashima South High School.
What kind of answer will you get if you do multiple fact checks?

We are ocomoji Corporation, an RPA and business efficiency company in Saga, Japan. Please feel free to contact us.

ocomoji.co "Bring DX closer to you."

Top comments (0)