Skip to content

Commit

Permalink
Merge pull request #12500 from ethereum/discord-gfi-webhook-2
Browse files Browse the repository at this point in the history
Discord GFI webhook
  • Loading branch information
pettinarip authored Mar 25, 2024
2 parents 8fcccaa + d09ba0d commit 6afa2b2
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/lib/utils/gh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,46 @@ export const getLastModifiedDateByPath = (path: string): string => {
const logInfo = getGitLogFromPath(path)
return extractDateFromGitLogInfo(logInfo)
}

const LABELS_TO_SEARCH = [
"content",
"design",
"dev",
"doc",
"translation",
"event",
] as const

const LABELS_TO_TEXT: Record<(typeof LABELS_TO_SEARCH)[number], string> = {
content: "content",
design: "design",
dev: "dev",
doc: "docs",
translation: "translation",
event: "event",
}

// Given a list of labels, it returns a new array with the labels that match the
// LABELS_TO_SEARCH list, using the LABELS_TO_TEXT values
// Example:
// - ["content :pencil:", "ux design"] => ["content", "design"]
// - ["documentation :emoji:", "dev required", "good first issue"] => ["docs", "dev"]
export const normalizeLabels = (labels: string[]) => {
const labelsFound = labels
.map((label) => {
const labelIndex = LABELS_TO_SEARCH.findIndex((l) =>
label.toLocaleLowerCase().includes(l)
)

if (labelIndex === -1) {
return
}

const labelMatched = LABELS_TO_SEARCH[labelIndex]
return LABELS_TO_TEXT[labelMatched]
})
.filter(Boolean)

// remove duplicates
return Array.from(new Set(labelsFound))
}
93 changes: 93 additions & 0 deletions src/pages/api/gfi-issues-webhook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { NextApiRequest, NextApiResponse } from "next"

import { normalizeLabels } from "@/lib/utils/gh"

const LABELS_TO_EMOJI = {
content: "📝",
design: "🎨",
dev: "🛠️",
docs: "📚",
translation: "🌐",
event: "🗓️",
}

type ResponseData = {
message: string
}

const GFI_LABEL = "good first issue"

export default async function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
const { method } = req

if (method !== "POST") {
return res.status(405).json({ message: "Method not allowed" })
}

const { action, label, issue } = req.body

if (action !== "labeled") {
return res.status(200).json({ message: "Not a label action" })
}

if (label.name !== GFI_LABEL) {
return res.status(200).json({ message: "Not a good first issue" })
}

if (issue.assignee) {
return res.status(200).json({ message: "Issue already assigned" })
}

// send a notification to discord webhook
const webhookUrl = `https://discord.com/api/webhooks/${process.env.DISCORD_ID}/${process.env.DISCORD_TOKEN}`

const embeds = [
{
title: issue.title,
url: issue.html_url,
timestamp: issue.created_at,
description: issue.labels.map((label) => label.name).join(" • "),
color: 10181046, // purple
author: {
name: issue.user.login,
url: issue.user.html_url,
icon_url: issue.user.avatar_url,
},
},
]

const allLabels = issue.labels.map((label) => label.name)
const [firstLabel] = normalizeLabels(allLabels)

let content: string
if (firstLabel) {
const labelsText = ` - ${firstLabel}`
const emoji = LABELS_TO_EMOJI[firstLabel]
const emojiText = emoji ? `${emoji} ` : ""
content = `### ${emojiText}New good first issue${labelsText}`
} else {
content = `### New good first issue`
}

const message = {
content,
embeds,
}

const discordRes = await fetch(webhookUrl, {
method: "post",
body: JSON.stringify(message),
headers: { "Content-Type": "application/json" },
})

if (!discordRes.ok) {
const error = await discordRes.json()
console.log(error)
return res.status(500).json({ message: "Error sending GFI to Discord" })
}

res.status(200).json({ message: "New GFI sent to Discord!" })
}

0 comments on commit 6afa2b2

Please sign in to comment.