Created
May 26, 2023 08:49
-
-
Save farukcan/2c4f41475bd6bed225a8b822bc9e1b6e to your computer and use it in GitHub Desktop.
App Script Chat Bot Sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1) Copy or Duplicate this spreadsheet (and this AppsScript project) | |
// | |
// 2) Run "setup" function once | |
// - Use the menu above. | |
// | |
// 3) Create Google Cloud Service Project. And copy the Project Number. | |
// | |
// 4) This > Project Settings > Set GCM project number | |
// | |
// 5) Add the line "chat": {} to your manifest file. (IMPORTANT) | |
// | |
// 6) Setup 0Auth : https://github.com/googleworkspace/apps-script-oauth2 | |
// | |
// 6) Deploy | |
// - Select type "Web App" and "Add-on" (both) | |
// - Set description "v1" | |
// - Set "Who can access" to "Anyone" | |
// | |
// 7) Copy "Deployment Id" and "Web App URL" you will use them. | |
// - Check the Web APP URL, is it working? | |
// - "message" key must equals to "working" | |
// - "setup" key must not equals to "null" | |
// | |
// 8) Enable Google Chat API on console.cloud.google.com | |
// - Use search to find "Google Chat API" and press Enable button. | |
// | |
// 9) Go to APIs > Google Chat API > Credentials and Create a service account. | |
// - Choose a account name and type a description for it. (Ex: Unity GChat ) | |
// - Click to "Create and Continue" | |
// - Select Role : "Basic > Owner" and Click "Continue" | |
// - No need to grant user access, just Click to "Done". | |
// | |
// 10) Go to APIs > Google Chat API > Configuration and fill the form. | |
// - Set App Name (Ex: Unity GChat) | |
// - Set Avatar URL (if you have not, use https://www.gstatic.com/images/branding/product/1x/chat_48dp.png ) | |
// - Set Description. (Ex: Unity GChat allows to talk with Unity) | |
// - Set Functionality | |
// * Receive 1:1 messages => checked | |
// * Join spaces and group conversations => checked | |
// - Set Connection Settings | |
// * Choose "App Script Project" option | |
// * Paste "Deployment Id" to textbox. | |
// - Set Visibility | |
// * Add your email adresses to see the bot. | |
// * Add your domain if you have google workspace. | |
// | |
// 11) Create space and your providers and bot to the group.. | |
// #################### | |
// # Setup | |
// #################### | |
function setup(){ // please select "setup" function and run it once. | |
PropertiesService.getDocumentProperties().setProperty("setup",true); | |
} | |
// #################### | |
// # API | |
// #################### | |
// - handle GET method | |
function doGet(request) { | |
var output = ContentService.createTextOutput(); | |
output.setMimeType(ContentService.MimeType.JSON); | |
output.append(JSON.stringify({ | |
message: "working", | |
setup : PropertiesService.getDocumentProperties().getProperty("setup"), | |
chat : PropertiesService.getDocumentProperties().getProperty("chat") | |
})); | |
return output; | |
} | |
// - handle POST method | |
function doPost(request){ | |
var json = { ok: false, request: request }; | |
if(!request.postData){ | |
json.error = "No post data"; | |
}else if(request.postData.type != 'application/json'){ | |
json.error = "Invalid json body"; | |
}else{ | |
json.input = JSON.parse(request.postData.contents); | |
if(request.parameters.type){ // Ex: exec?type=create | |
var type = request.parameters.type; | |
if(type=="create") createThread(json); | |
else if(type=="post") postToThread(json); | |
else if(type=="fetch") fetchThread(json); | |
else json.error ="Invalid type"; | |
}else{ | |
json.error = "Type parameter is required"; | |
} | |
} | |
return ContentService.createTextOutput(JSON.stringify(json)).setMimeType(ContentService.MimeType.JSON); | |
} | |
// - exec?type=create | |
function createThread(json){ | |
var name = "User (No Name)"; | |
if(json.input.name){ | |
name = json.input.name; | |
} | |
var response = postMessage({ | |
text: name + " created a thread." | |
}); | |
json.responseForThread = JSON.parse(response.getContentText()); | |
json.thread = json.responseForThread.thread.name; | |
response = postMessage({ | |
text: name + " : " + json.input.message, | |
messageReplyOption : "REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD", | |
thread : { | |
name : json.thread | |
} | |
}); | |
json.responseForMessage = JSON.parse(response.getContentText()); | |
json.ok = true; | |
json.message = "Thread created"; | |
} | |
// - exec?type=post | |
function postToThread(json){ | |
var name = "User (No Name)"; | |
if(json.input.name){ | |
name = json.input.name; | |
} | |
if(json.input.thread){ | |
var response = postMessage({ | |
text: name + " : " + json.input.message, | |
messageReplyOption : "REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD", | |
thread : { | |
name : json.input.thread | |
} | |
}); | |
json.responseForMessage = JSON.parse(response.getContentText()); | |
json.ok = true; | |
json.message = "Posted to the thread"; | |
}else{ | |
json.error ="thread parameter is required"; | |
} | |
} | |
// - exec?type=fetch | |
function fetchThread(json){ | |
json.ok = true; | |
json.message = "Thread fetched"; | |
if(json.input.thread){ | |
//var spaceId = PropertiesService.getDocumentProperties().getProperty("space"); | |
var service = createService(); | |
var url = 'https://chat.googleapis.com/v1/spaces/AAAAGZq2WUk/messages/9-lnyxdLHFU.9-lnyxdLHFU'; // test | |
//url +="?filter=" + encodeURI("thread.name = " + json.input.thread); | |
var response = UrlFetchApp.fetch(url, { | |
method: 'get', | |
headers: { 'Authorization': 'Bearer ' + service.getAccessToken() } | |
}); | |
json.responseForMessage = JSON.parse(response.getContentText()); | |
json.ok = true; | |
json.message = "Posted to the thread"; | |
}else{ | |
json.error ="thread parameter is required"; | |
} | |
} | |
// #################### | |
// # Bot | |
// #################### | |
function onMessage(event) { | |
var name = ""; | |
var message = ""; | |
if (event.space.type == "DM") { | |
message = "DM is not allowed." | |
} else { | |
name = event.user.displayName; | |
message = name + " said \"" + event.message.text + "\". Please use threads. "; | |
} | |
return { "text": message }; | |
} | |
function onAddToSpace(event) { | |
var message = ""; | |
if (event.space.singleUserBotDm) { | |
message = "Thank you for adding me to a DM, " + event.user.displayName + "!"; | |
} else { | |
message = "Thank you for adding me to " + | |
(event.space.displayName ? event.space.displayName : "this chat"); | |
} | |
if (event.message) { | |
// Bot added through @mention. | |
message = message + " and you said: \"" + event.message.text + "\""; | |
} | |
PropertiesService.getDocumentProperties().setProperty("space",event.space.name); | |
return { "text": message }; | |
} | |
var SCOPE = 'https://www.googleapis.com/auth/chat.messages'; | |
var TOKEN_URL = 'https://accounts.google.com/o/oauth2/token'; | |
// The values below are copied from the JSON file downloaded upon | |
// service account creation. | |
// For SERVICE_ACCOUNT_PRIVATE_KEY, remember to include the BEGIN and END lines of the private key | |
var SERVICE_ACCOUNT_PRIVATE_KEY = '--required--'; | |
var SERVICE_ACCOUNT_EMAIL = '--required--'; | |
// https://developers.google.com/chat/how-tos/apps-script#async_messages | |
function createService(){ | |
var service = OAuth2.createService('chat') | |
.setTokenUrl(TOKEN_URL) | |
.setPrivateKey(SERVICE_ACCOUNT_PRIVATE_KEY) | |
.setClientId(SERVICE_ACCOUNT_EMAIL) | |
.setPropertyStore(PropertiesService.getUserProperties()) | |
.setScope(SCOPE); | |
if (!service.hasAccess()) { | |
Logger.log('Authentication error: %s', service.getLastError()); | |
return null; | |
} | |
return service; | |
} | |
// Posts a message into the given space ID via the API, using | |
// service account authentication. | |
// https://developers.google.com/chat/api/reference/rest/v1/spaces.messages/create | |
function postMessage(message) { | |
var spaceId = PropertiesService.getDocumentProperties().getProperty("space"); | |
var service = createService(); | |
var url = 'https://chat.googleapis.com/v1/' + spaceId + '/messages'; | |
if(message.messageReplyOption){ | |
url += '?messageReplyOption=' + message.messageReplyOption; | |
delete message.messageReplyOption; | |
} | |
return UrlFetchApp.fetch(url, { | |
method: 'post', | |
headers: { 'Authorization': 'Bearer ' + service.getAccessToken() }, | |
contentType: 'application/json', | |
payload: JSON.stringify(message), | |
}); | |
} | |
function testMessage(){ | |
postMessage({ | |
text: "Hello! It's a test message." | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment