Skip to content

Commit

Permalink
Fjord v0.1 integration (Webhook + Discord) (#264)
Browse files Browse the repository at this point in the history
### Notes
This PR adds support for webhooks into valkyrie to run automations /
send workflow results to Discord. In order to function, a new `.env`
variables need to be added as mentioned.

This PR adds several new .ENV flags that need to be added on deployment

```
export HUBOT_WEBHOOK_URL="/discord/"
export HUBOT_WEBHOOK_AUTH="INSERT passkey"
export HUBOT_N8N_WEBHOOK="INSERT n8n router webhook URL"
```

### Steps to deploy
1. First setup valkyrie deployment to have new .env flags. 
2. Test with valkyrie.thesis.co endpoint

### Discord Commands
Adds the following commands to discord server
`/stale-issues owner repository: Grab a list of stale issues from an n8n
workflow`
`/issues owner repository: Grab a list of recent issues from an n8n
workflow`
`/activity owner repository: View activity stats from a specific
repository`
`/exec workflow-name: run an automation based on the workflow name on
n8n router`
`/debug : send adapter data to hubot console for debugging channel /
thread / guild info`

### To do

- [x] Setup valkyrie URL endpoint
- [x] Threading for webhooks
- [x] Setup ENV flags for webhook URLs
- [x] Setup public facing URL on valkyrie n8s instance for webhook
- [x] Add auth layer to webhook
- [x] Implement proper discord commands
- [x] Add dynamic routing to channels based on channel definition in
email
  • Loading branch information
puppycodes authored Jun 15, 2023
2 parents ca28892 + 2c8cc44 commit 6d76452
Show file tree
Hide file tree
Showing 7 changed files with 471 additions and 3 deletions.
1 change: 0 additions & 1 deletion bin/hubot
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ set -e

export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"


NODE_OPTIONS="--experimental-vm-modules --experimental-loader ts-node/esm --no-experimental-fetch" exec node_modules/.bin/hubot --alias "\\" --name "valkyrie" "$@"
87 changes: 87 additions & 0 deletions discord-scripts/discord-webhook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { Client, TextChannel, ChannelType } from "discord.js"
import { Robot } from "hubot"
import express from "express"

export default async function webhookDiscord(
discordClient: Client,
robot: Robot,
) {
async function sendToDiscordChannel(
channelName: string,
tagUser: string,
title: string,
message: string,
) {
let channel: TextChannel | undefined
const guilds = discordClient.guilds.cache

guilds.forEach((guild) => {
const matchedChannel = guild.channels.cache.find(
(ch) => ch.name === channelName && ch.type === ChannelType.GuildText,
)

if (matchedChannel && matchedChannel.type === ChannelType.GuildText) {
channel = matchedChannel as TextChannel
}
})

if (!channel)
throw new Error(
"Text-based channel with the given name not found in any guild",
)

const memberIds = tagUser.split(",")
const existingThread = channel.threads.cache.find(
(thread) => thread.name === title,
)

if (existingThread) {
await existingThread.send("@here")
await existingThread.send(message)
} else {
const newThread = await channel.threads.create({
name: title,
autoArchiveDuration: 60,
reason: message,
})
await newThread.send("@here")
if (tagUser !== "0") {
await Promise.all(
memberIds.map((id) => newThread.members.add(id.trim())),
)
}
await newThread.send(message)
}
}

if (process.env.HUBOT_WEBHOOK_URL) {
const webhookUrl = process.env.HUBOT_WEBHOOK_URL
const requiredAuth = process.env.HUBOT_WEBHOOK_AUTH

robot.router.post(
`${webhookUrl}`,
(
req: express.Request,
res: express.Response,
next: express.NextFunction,
) => {
const authHeader = req.headers.authorization
if (!authHeader || authHeader !== requiredAuth) {
res.status(401).send("Unauthorized")
} else {
next()
}
},
async (req: express.Request, res: express.Response) => {
const { channelName, tagUser, title, message } = req.body

robot.logger.info(
`Received data: channelName = ${channelName}, title = ${title}, tagged users = ${tagUser} , message = ${message}`,
)
await sendToDiscordChannel(channelName, tagUser, title, message)

res.status(200).send("Message sent to Discord")
},
)
}
}
1 change: 0 additions & 1 deletion discord-scripts/figma-integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
ApplicationCommandOptionType,
ChannelType,
Client,
ClientApplication,
EmbedBuilder,
GuildTextBasedChannel,
TextBasedChannel,
Expand Down
Loading

0 comments on commit 6d76452

Please sign in to comment.