Skip to content

Commit

Permalink
Merge pull request #17 from PicardParis/main
Browse files Browse the repository at this point in the history
fix: allow direct gcloud run deploy w/o Dockerfile
  • Loading branch information
tswast authored May 23, 2023
2 parents ab65193 + b65a1cc commit 8e34d52
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 179 deletions.
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
25 changes: 0 additions & 25 deletions extra-credit/Dockerfile

This file was deleted.

198 changes: 107 additions & 91 deletions extra-credit/kittenbot.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,79 +17,88 @@ limitations under the License.
This is a sample Slack bot built with Botkit.
*/

const { Botkit, BotkitConversation } = require('botkit')
const { SlackAdapter, SlackEventMiddleware } = require(
'botbuilder-adapter-slack')
const { SecretManagerServiceClient } = require('@google-cloud/secret-manager')
const { Botkit, BotkitConversation } = require('botkit');
const {
SlackAdapter,
SlackEventMiddleware,
} = require('botbuilder-adapter-slack');
const { SecretManagerServiceClient } = require('@google-cloud/secret-manager');

/**
* Returns the secret string from Google Cloud Secret Manager
* @param {string} name The name of the secret.
* @return {string} The string value of the secret.
* @return {Promise<string>} The string value of the secret.
*/
async function accessSecretVersion (name) {
const client = new SecretManagerServiceClient()
const projectId = process.env.PROJECT_ID
async function accessSecretVersion(name) {
const client = new SecretManagerServiceClient();
const projectId = process.env.PROJECT_ID;
const [version] = await client.accessSecretVersion({
name: `projects/${projectId}/secrets/${name}/versions/1`
})
name: `projects/${projectId}/secrets/${name}/versions/1`,
});

// Extract the payload as a string.
const payload = version.payload.data.toString('utf8')
const payload = version.payload.data.toString('utf8');

return payload
return payload;
}

/**
* Asynchronous function to initialize kittenbot.
* Function to initialize kittenbot.
*/
async function kittenbotInit () {
async function kittenbotInit() {
const adapter = new SlackAdapter({
clientSigningSecret: await accessSecretVersion('client-signing-secret'),
botToken: await accessSecretVersion('bot-token')
})
botToken: await accessSecretVersion('bot-token'),
});

adapter.use(new SlackEventMiddleware())
adapter.use(new SlackEventMiddleware());

const controller = new Botkit({
webhook_uri: '/api/messages',
adapter: adapter
})
adapter: adapter,
});

// Add Kitten Dialog
const convo = createKittenDialog(controller)
controller.addDialog(convo)
const convo = createKittenDialog(controller);
controller.addDialog(convo);

// Controller is ready
controller.ready(() => {
controller.hears(['hello', 'hi'], ['message', 'direct_message'],
controller.hears(
['hello', 'hi', 'hey'],
['message', 'direct_message'],
async (bot, message) => {
return bot.reply(message, 'Meow. :smile_cat:')
})
await bot.reply(message, 'Meow. :smile_cat:');
return;
}
);

// START: listen for cat emoji delivery
controller.hears(['cat', 'cats', 'kitten', 'kittens'],
controller.hears(
['cat', 'cats', 'kitten', 'kittens'],
['message', 'direct_message'],
async (bot, message) => {
// Don't respond to self
if (message.bot_id !== message.user) {
await bot.startConversationInChannel(message.channel, message.user)
return bot.beginDialog('kitten-delivery')
await bot.startConversationInChannel(message.channel, message.user);
await bot.beginDialog('kitten-delivery');
return;
}
})
}
);
// END: listen for cat emoji delivery

// START: slash commands
controller.on('slash_command', async (bot, message) => {
const numCats = parseInt(message.text)
const response = makeCatMessage(numCats)
bot.httpBody({ text: response })
})
const numCats = parseInt(message.text);
const response = makeCatMessage(numCats);
bot.httpBody({ text: response });
});
// END: slash commands
})
});
}

const maxCats = 20
const maxCats = 20;
const catEmojis = [
':smile_cat:',
':smiley_cat:',
Expand All @@ -105,110 +114,117 @@ const catEmojis = [
':leopard:',
':lion_face:',
':tiger:',
':tiger2:'
]
':tiger2:',
];

/**
* Function to concatenate cat emojis
* @param {number} numCats Number of cat emojis.
* @return {string} The string message of cat emojis.
*/
function makeCatMessage (numCats) {
let catMessage = ''
function makeCatMessage(numCats) {
let catMessage = '';
for (let i = 0; i < numCats; i++) {
// Append a random cat from the list
catMessage += catEmojis[Math.floor(Math.random() * catEmojis.length)]
catMessage += catEmojis[Math.floor(Math.random() * catEmojis.length)];
}
return catMessage
return catMessage;
}

/**
* Function to create the kitten conversation
* @param {Object} controller The botkit controller.
* @return {Object} The BotkitConversation object.
*/
function createKittenDialog (controller) {
const convo = new BotkitConversation('kitten-delivery', controller)
function createKittenDialog(controller) {
const convo = new BotkitConversation('kitten-delivery', controller);

convo.ask('Does someone need a kitten delivery?', [
{
pattern: 'yes',
handler: async (response, convo, bot) => {
await convo.gotoThread('yes_kittens')
}
await convo.gotoThread('yes_kittens');
},
},
{
pattern: 'no',
handler: async (response, convo, bot) => {
await convo.gotoThread('no_kittens')
}
await convo.gotoThread('no_kittens');
},
},
{
default: true,
handler: async (response, convo, bot) => {
await convo.gotoThread('default')
}
}

])

convo.addQuestion('How many would you like?', [
{
pattern: '^[0-9]+?',
handler: async (response, convo, bot, message) => {
const numCats = parseInt(response)
if (numCats > maxCats) {
await convo.gotoThread('too_many')
} else {
convo.setVar('full_cat_message', makeCatMessage(numCats))
await convo.gotoThread('cat_message')
}
}
await convo.gotoThread('default');
},
},
{
default: true,
handler: async (response, convo, bot, message) => {
if (response) {
await convo.gotoThread('ask_again')
} else {
// The response '0' is interpreted as null
await convo.gotoThread('zero_kittens')
}
}
}
], 'num_kittens', 'yes_kittens')
]);

convo.addQuestion(
'How many would you like?',
[
{
pattern: '^[0-9]+?',
handler: async (response, convo, bot, message) => {
const numCats = parseInt(response);
if (numCats > maxCats) {
await convo.gotoThread('too_many');
} else {
convo.setVar('full_cat_message', makeCatMessage(numCats));
await convo.gotoThread('cat_message');
}
},
},
{
default: true,
handler: async (response, convo, bot, message) => {
if (response) {
await convo.gotoThread('ask_again');
} else {
// The response '0' is interpreted as null
await convo.gotoThread('zero_kittens');
}
},
},
],
'num_kittens',
'yes_kittens'
);

// If numCats is too large, jump to start of the yes_kittens thread
convo.addMessage(
'Sorry, {{vars.num_kittens}} is too many cats. Pick a smaller number.',
'too_many')
convo.addAction('yes_kittens', 'too_many')
'too_many'
);
convo.addAction('yes_kittens', 'too_many');

// If response is not a number, jump to start of the yes_kittens thread
convo.addMessage('Sorry I didn\'t understand that', 'ask_again')
convo.addAction('yes_kittens', 'ask_again')
convo.addMessage("Sorry I didn't understand that", 'ask_again');
convo.addAction('yes_kittens', 'ask_again');

// If numCats is 0, send a dog instead
convo.addMessage(
{
text: 'Sorry to hear you want zero kittens. ' +
'Here is a dog, instead. :dog:',
text:
'Sorry to hear you want zero kittens. ' +
'Here is a dog, instead. :dog:',
attachments: [
{
fallback: 'Chihuahua Bubbles - https://youtu.be/s84dBopsIe4',
text: '<https://youtu.be/s84dBopsIe4|' +
'Chihuahua Bubbles>!'
}
]
}, 'zero_kittens')
text: '<https://youtu.be/s84dBopsIe4|' + 'Chihuahua Bubbles>!',
},
],
},
'zero_kittens'
);

// Send cat message
convo.addMessage('{{vars.full_cat_message}}', 'cat_message')
convo.addMessage('{{vars.full_cat_message}}', 'cat_message');

convo.addMessage('Perhaps later.', 'no_kittens')
convo.addMessage('Perhaps later.', 'no_kittens');

return (convo)
return convo;
}
// END: kitten-delivery convo

kittenbotInit()
kittenbotInit();
17 changes: 10 additions & 7 deletions extra-credit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@
"version": "2.0.0",
"description": "A sample Slack Botkit bot.",
"main": "kittenbot.js",
"dependencies": {
"botbuilder-adapter-slack": "^1.0.8",
"botkit": "^4.6.2",
"@google-cloud/secret-manager": "2.1.0"
},
"devDependencies": {},
"scripts": {
"start": "node kittenbot.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"engines": {
"node": "16"
},
"dependencies": {
"@google-cloud/secret-manager": "4",
"botbuilder-adapter-slack": "1",
"request": "2"
},
"repository": {
"type": "git",
"url": "https://github.com/googlecodelabs/cloud-slack-bot.git"
},
"author": "Google Inc.",
"license": "Apache-2.0"
}
}
25 changes: 0 additions & 25 deletions start/Dockerfile

This file was deleted.

Loading

0 comments on commit 8e34d52

Please sign in to comment.