Skip to content

Commit

Permalink
implement channel-notifier
Browse files Browse the repository at this point in the history
  • Loading branch information
pizzacat83 committed Mar 31, 2020
0 parents commit 2dd6d33
Show file tree
Hide file tree
Showing 16 changed files with 498 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .funcignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.js.map
*.ts
.git*
.vscode
local.settings.json
test
tsconfig.json
97 changes: 97 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TypeScript output
dist
out

# Azure Functions artifacts
bin
obj
appsettings.json
local.settings.json

# Others
/tmp/
5 changes: 5 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"ms-azuretools.vscode-azurefunctions"
]
}
12 changes: 12 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Node Functions",
"type": "node",
"request": "attach",
"port": 9229,
"preLaunchTask": "func: host start"
}
]
}
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"azureFunctions.deploySubpath": ".",
"azureFunctions.projectLanguage": "TypeScript",
"azureFunctions.projectRuntime": "~2",
"debug.internalConsoleOptions": "neverOpen",
"azureFunctions.preDeployTask": "npm prune"
}
31 changes: 31 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "func",
"command": "host start",
"problemMatcher": "$func-watch",
"isBackground": true,
"dependsOn": "npm build"
},
{
"type": "shell",
"label": "npm build",
"command": "npm run build",
"dependsOn": "npm install",
"problemMatcher": "$tsc"
},
{
"type": "shell",
"label": "npm install",
"command": "npm install"
},
{
"type": "shell",
"label": "npm prune",
"command": "npm prune --production",
"dependsOn": "npm build",
"problemMatcher": []
}
]
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# ap2020bot
20 changes: 20 additions & 0 deletions SlackEvents/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
],
"scriptFile": "../dist/SlackEvents/index.js"
}
39 changes: 39 additions & 0 deletions SlackEvents/handlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Context } from "@azure/functions"
import { WebClient } from '@slack/web-api';

const webClient = new WebClient(process.env.SLACK_TOKEN_BOT);

namespace Events {
export interface ChannelCreated {
type: "channel_created";
channel: {
id: string;
name: string;
created: number;
creator: string;
}
}

export interface ChannelUnarchive {
type: "channel_unarchive";
channel: string;
user: string;
}
}

// Handlers
// the name of the handler must be the type of the event

export const channel_created = async ({channel}: Events.ChannelCreated, context: Context) => {
await webClient.chat.postMessage({
channel: process.env.SLACK_CHANNEL_NOTIFICATIONS_OTHERS,
text: `:new: <@${channel.creator}> が <#${channel.id}> を作成しました :rocket:`,
});
}

export const channel_unarchive = async ({channel, user}: Events.ChannelUnarchive, context: Context) => {
await webClient.chat.postMessage({
channel: process.env.SLACK_CHANNEL_NOTIFICATIONS_OTHERS,
text: `:recycle: <@${user}> が <#${channel}> をアーカイブから復元しました :rocket:`,
});
};
52 changes: 52 additions & 0 deletions SlackEvents/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { AzureFunction, Context, HttpRequest } from "@azure/functions"
import * as handlers from "./handlers";
import * as crypto from "crypto";
import * as timingSafeCompare from "tsscmp";

const verify = (req: HttpRequest) => {
const version = 'v0';
const actual = req.headers['x-slack-signature'];

const timestamp = req.headers['x-slack-request-timestamp'];
const hmac = crypto.createHmac('sha256', process.env.SLACK_SIGNING_SECRET);
hmac.update(`${version}:${timestamp}:${req.rawBody}`);
const expected = `${version}=${hmac.digest('hex')}`;

return timingSafeCompare(expected, actual);
}

const httpTrigger: AzureFunction = async (context: Context, req: HttpRequest): Promise<void> => {
if (!verify(req)) {
context.log.error('unverified request from:', req.headers['x-forwarded-for']);
context.res = {
body: "",
};
return;
}
switch (req.body.type) {
case "url_verification":
context.log('Challenge from Slack');
context.res = {
body: req.body.challenge,
}
return;
case "event_callback":
let eventType = req.body.event.type
context.log('Incoming event: ', eventType);
context.res = {
body: "",
};
context.done(); // easy return because of the 3sec rule
if (eventType in handlers) {
// TODO: handle errors
await handlers[eventType](req.body.event, context);
} else {
context.log.error('no handler for event type:', eventType);
}
break;
default:
context.log.error('not recognized top-level event: ', req.body.type);
}
};

export default httpTrigger;
3 changes: 3 additions & 0 deletions SlackEvents/sample.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "Azure"
}
7 changes: 7 additions & 0 deletions host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
Loading

0 comments on commit 2dd6d33

Please sign in to comment.