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
[Troubleshooting] Operation check - Communication - [GAS + SlackBot]
[Troubleshooting] Operation check - communication - [GAS + chatGPT]
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}
* 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)
5.On the deployment completion screen, copy the URL of the web application and
press the memo completion button.
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
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
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
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)
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
4.Copy the member ID and make a note of it
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
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
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
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 **********
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
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!
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)
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.)
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 ) ;
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?
Top comments (0)