Skip to content

Commit

Permalink
add a sample, daily joke
Browse files Browse the repository at this point in the history
  • Loading branch information
jianzs committed Oct 24, 2023
1 parent a7a004c commit af5b223
Show file tree
Hide file tree
Showing 15 changed files with 220 additions and 0 deletions.
37 changes: 37 additions & 0 deletions examples/daily-joke-slack/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
node_modules
.pnp
.pnp.js

# testing
coverage

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# turbo
.turbo

# vercel
.vercel

# compilation result
**/dist/

# pluto
**/compiled/
7 changes: 7 additions & 0 deletions examples/daily-joke-slack/.pluto/pluto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: morning-message-slack
stacks:
- name: aws
runtime:
type: AWS
engine: pulumi
current: aws
69 changes: 69 additions & 0 deletions examples/daily-joke-slack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# A Joke Bot for Slack

This article presents a sample application using Pluto that creates a simple joke bot on AWS using the Slack WebAPI. The bot will send a daily joke to a specified channel.

## Preparation

### Creating a Slack App

To begin, you need to create a Slack App. Click [here](https://api.slack.com/apps?new_app=1) to start the creation process.

Once you're in the creation process, you'll see the following interface. Choose the first option, "From scratch."

<p align="center">
<img src="./assets/create-app.png" alt="create app" width="350">
</p>

In the next steps, provide a desired name for your bot and select the space where it will send messages.

<p align="center">
<img src="./assets/give-name.png" alt="give a name" width="350">
</p>

After the creation is complete, select "OAuth & Permissions" from the sidebar. Scroll down and set the necessary permissions for the bot. In this case, we need the `channels:read`, `chat:write`, and `chat:write.public` permissions.

<p align="center">
<img src="./assets/grant-premission-1.png" alt="grant premission" width="150">
<img src="./assets/grant-permission-2.png" alt="grant premission" width="350">
</p>

Next, select "Install App" from the sidebar and click "Install to Workspace" to complete the authorization process.

<p align="center">
<img src="./assets/install-app.png" alt="install app to workspace" width="550">
</p>

<p align="center">
<img src="./assets/install-app2.png" alt="authorization" width="350">
</p>

Afterwards, you will obtain a Bot User OAuth Token.

<p align="center">
<img src="./assets/token.png" alt="got token" width="350">
</p>

Once you have the token, you need to obtain the ID of the channel where you want the bot to send messages. This ID can be found in the Slack client. Find the desired channel, click on its name, and you will find the ID at the bottom.

<p align="center">
<img src="./assets/channel-id.png" alt="got channel id" width="450">
</p>

### Installing Pluto

If you haven't installed Pluto yet, you can refer to the installation steps [here](https://github.com/pluto-lang/pluto#-quick-start).

## Modifying the Code

Modify the `src/index.ts` file and replace the `slackAppToken` and `channelId` with the Bot User OAuth Token and the channel ID obtained earlier.

## One-Click Deployment

In the root directory of this example program, execute `pluto deploy` to deploy it.


## Show Time

<p align="center">
<img src="./assets/effect.png" alt="effect" width="650">
</p>
Binary file added examples/daily-joke-slack/assets/channel-id.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/daily-joke-slack/assets/create-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/daily-joke-slack/assets/effect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/daily-joke-slack/assets/give-name.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/daily-joke-slack/assets/install-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/daily-joke-slack/assets/token.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions examples/daily-joke-slack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "daily-joke-slack",
"version": "0.0.0",
"scripts": {
"test:dev": "pluto test --sim",
"test:prod": "pluto test",
"deploy": "pluto deploy",
"destroy": "pluto destroy"
},
"dependencies": {
"@plutolang/pluto": "latest",
"@slack/web-api": "^6.9.0"
},
"devDependencies": {
"@plutolang/base": "latest",
"@plutolang/pluto-infra": "latest",
"@pulumi/pulumi": "^3.88.0",
"@types/node": "^20",
"typescript": "^5.2.2"
},
"main": "dist/index.js"
}
50 changes: 50 additions & 0 deletions examples/daily-joke-slack/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Schedule } from "@plutolang/pluto";
import { retryPolicies, WebClient, LogLevel } from "@slack/web-api";

const sched = new Schedule("joke-sched");

sched.cron("0 9 * * *", async () => {
// Replace the placeholder with your token and DO NOT publish it publicly.
const slackAppToken = "xoxb-xxxxxxxxxxxxxxxxx";
// Replace the channel you want to post the message to
const channelId = "C06xxxxxxxx";

const fetchJoke = async (): Promise<string> => {
const JOKE_URL =
"https://v2.jokeapi.dev/joke/Programming?blacklistFlags=nsfw,religious,political,racist&type=single";
const response = await fetch(JOKE_URL);
const data: any = await response.json();
if (response.status != 200 || data["error"] != false) {
throw new Error("Failed to fetch the joke.");
}
return data["joke"];
};

try {
const client = new WebClient(slackAppToken, {
logLevel: LogLevel.DEBUG,
retryConfig: retryPolicies.fiveRetriesInFiveMinutes,
});
const joke = await fetchJoke();

const text = `Hey there, everyone!
Just wanted to drop in and say hello to all of you amazing people. Hope you're all doing great!
Now, I've got a little something to tickle your funny bones. Check out this joke:
${joke}
Take care and stay awesome,
Joke Bot powered by Pluto`;

// Call the chat.postMessage method using the WebClient
const result = await client.chat.postMessage({
channel: channelId,
text: text,
});

console.log(result);
} catch (error) {
console.error(error);
}
});
35 changes: 35 additions & 0 deletions examples/daily-joke-slack/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"alwaysStrict": true,
"declaration": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"inlineSourceMap": true,
"inlineSources": true,
"lib": [
"es2019"
],
"module": "CommonJS",
"noEmitOnError": false,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"strict": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"stripInternal": true,
"target": "ES2019"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}

0 comments on commit af5b223

Please sign in to comment.