-
-
Save vanpariyar/82138c8d92ea907b770324fab3aa6a67 to your computer and use it in GitHub Desktop.
Slack App in Google Apps Script
This file contains hidden or 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
// *** Request Verification *** | |
// The currently recommended way is to verify request signature: https://api.slack.com/authentication/verifying-requests-from-slack | |
// Unfortunately, GAS web apps don"t have means to access request headers. Thus, this example uses the old way to verify requests. | |
// >>> Settings > Basic Information > App Credentials > Verification Token | |
const legacyVerificationToken = PropertiesService.getScriptProperties().getProperty("SLACK_VERIFICATION_TOKEN"); | |
// *** OAuth Access Token *** | |
// Install your Slack app into its development workspace. | |
// >>> Settings > Install App > Bot User OAuth Access Token | |
const token = PropertiesService.getScriptProperties().getProperty("SLACK_BOT_TOKEN"); | |
// Example modal view | |
// Build your own modals here: https://app.slack.com/block-kit-builder | |
const modalView = { | |
"type": "modal", | |
"callback_id": "modal-id", | |
"submit": { | |
"type": "plain_text", | |
"text": "Submit" | |
}, | |
"close": { | |
"type": "plain_text", | |
"text": "Cancel" | |
}, | |
"title": { | |
"type": "plain_text", | |
"text": "Notification settings" | |
}, | |
"blocks": [ | |
{ | |
"type": "actions", | |
"block_id": "b", | |
"elements": [ | |
{ | |
"type": "checkboxes", | |
"action_id": "a", | |
"options": [ | |
{ | |
"text": { | |
"type": "plain_text", | |
"text": "New tasks" | |
}, | |
"value": "tasks", | |
"description": { | |
"type": "plain_text", | |
"text": "When new tasks are added to project" | |
} | |
}, | |
{ | |
"text": { | |
"type": "plain_text", | |
"text": "New comments" | |
}, | |
"value": "comments", | |
"description": { | |
"type": "plain_text", | |
"text": "When new comments are added" | |
} | |
}, | |
{ | |
"text": { | |
"type": "plain_text", | |
"text": "Project updates" | |
}, | |
"value": "updates", | |
"description": { | |
"type": "plain_text", | |
"text": "When project is updated" | |
} | |
} | |
] | |
} | |
] | |
} | |
] | |
}; | |
// POST request handler | |
function doPost(e) { | |
console.log(`Incoming form request data: ${JSON.stringify(e.postData)}`); | |
if (typeof e.postData === "undefined") { | |
return ack("invalid request"); | |
} | |
if (e.postData.type === "application/json") { | |
// ---------------------------- | |
// Events API / url_verification | |
// ---------------------------- | |
const payload = JSON.parse(e.postData.getDataAsString()); | |
if (payload.token !== legacyVerificationToken) { | |
console.log(`Invalid verification token detected (actual: ${payload.token}, expected: ${legacyVerificationToken})`); | |
return ack("invalid request"); | |
} | |
if (typeof payload.challenge !== "undefined") { | |
return ack(payload.challenge); | |
} | |
console.log(`Events API payload: ${JSON.stringify(payload)}`); | |
// ------------------------------------------------------------- | |
// TODO: Implement your own logic here | |
if (typeof payload.event.channel !== "undefined") { | |
callWebApi(token, "chat.postMessage", { | |
channel: payload.event.channel, | |
text: "Hi there!" | |
}); | |
} | |
// ------------------------------------------------------------- | |
return ack(""); | |
} else if (e.postData.type === "application/x-www-form-urlencoded") { | |
if (typeof e.parameters.payload !== "undefined") { | |
// ---------------------------- | |
// Interactivity & Shortcuts | |
// ---------------------------- | |
const payload = JSON.parse(e.parameters.payload[0]); | |
if (payload.token !== legacyVerificationToken) { | |
console.log(`Invalid verification token detected (actual: ${payload.token}, expected: ${legacyVerificationToken})`); | |
return ack("invalid request"); | |
} | |
console.log(`Interactivity payload: ${JSON.stringify(payload)}`); | |
// ------------------------------------------------------------- | |
// TODO: Implement your own logic here | |
if (payload.type === "shortcut") { | |
if (payload.callback_id === "gas") { | |
callWebApi(token, "views.open", { | |
trigger_id: payload.trigger_id, | |
user_id: payload.user.id, | |
view: JSON.stringify(modalView) | |
}); | |
} | |
} else if (payload.type === "message_action") { | |
if (payload.callback_id === "gas-msg") { | |
respond(payload.response_url, "Thanks for running a message shortcut!"); | |
} | |
} else if (payload.type === "block_actions") { | |
console.log(`Action data: ${JSON.stringify(payload.actions[0])}`); | |
} else if (payload.type === "view_submission") { | |
if (payload.view.callback_id === "modal-id") { | |
const stateValues = payload.view.state.values; | |
console.log(`View submssion data: ${JSON.stringify(stateValues)}`); | |
return ack(""); | |
} | |
} | |
// ------------------------------------------------------------- | |
} else if (typeof e.parameters.command !== "undefined") { | |
// ---------------------------- | |
// Slash Commands | |
// ---------------------------- | |
const payload = {} | |
for (const [key, value] of Object.entries(e.parameters)) { | |
payload[key] = value[0]; | |
} | |
if (payload.token !== legacyVerificationToken) { | |
console.log(`Invalid verification token detected (actual: ${payload.token}, expected: ${legacyVerificationToken})`); | |
return ack("invalid request"); | |
} | |
console.log(`Slash command payload: ${JSON.stringify(payload)}`); | |
// ------------------------------------------------------------- | |
// TODO: Implement your own logic here | |
if (payload.command === "/gas") { | |
return ack("Hi there!"); | |
} | |
// ------------------------------------------------------------- | |
} | |
} | |
// acknowledge the request | |
return ack(""); | |
} | |
function callWebApi(token, apiMethod, payload) { | |
const response = UrlFetchApp.fetch( | |
`https://www.slack.com/api/${apiMethod}`, | |
{ | |
method: "post", | |
contentType: "application/x-www-form-urlencoded", | |
headers: { "Authorization": `Bearer ${token}` }, | |
payload: payload, | |
} | |
); | |
console.log(`Web API (${apiMethod}) response: ${response}`) | |
return response; | |
} | |
function respond(responseUrl, payload) { | |
var responseBody = payload; | |
if (typeof payload === "string") { | |
responseBody = { "text": payload }; | |
} | |
const response = UrlFetchApp.fetch(responseUrl, { | |
method: "post", | |
contentType: "application/json; charset=utf-8", | |
payload: JSON.stringify(responseBody), | |
} | |
); | |
console.log(response); | |
} | |
function ack(payload) { | |
if (typeof payload === "string") { | |
return ContentService.createTextOutput(payload); | |
} else { | |
return ContentService.createTextOutput(JSON.stringify(payload)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment