Skip to content

feat: Add Discord webhook notifications for key platform events (#226)#274

Open
zp6 wants to merge 1 commit into
jsonresume:masterfrom
zp6:feat/discord-webhooks-226
Open

feat: Add Discord webhook notifications for key platform events (#226)#274
zp6 wants to merge 1 commit into
jsonresume:masterfrom
zp6:feat/discord-webhooks-226

Conversation

@zp6
Copy link
Copy Markdown

@zp6 zp6 commented May 15, 2026

Feature for #226

  • DiscordWebhookService with configurable webhook URL
  • Supports resume_created, resume_published, user_registered, theme_used
  • Rich embeds with colors and fields

Wallet: zp6

Summary by CodeRabbit

  • New Features
    • Added Discord webhook integration to enable real-time notifications sent to Discord channels when events occur within the application. Configuration is managed through environment settings.

Review Change Stack

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 15, 2026

⚠️ No Changeset found

Latest commit: d5f86d1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

@zp6 is attempting to deploy a commit to the JSON Resume Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Walkthrough

A new Discord webhook notification service is added in src/services/discord-webhook.js. The module reads the webhook URL from environment configuration, maps event types to embed colors, and exports an async function that formats events into Discord embeds and delivers them via HTTP POST, returning false when unconfigured or the response success status otherwise.

Changes

Discord Webhook Service

Layer / File(s) Summary
Discord webhook notification service
src/services/discord-webhook.js
Webhook service with environment-based URL configuration, main async sendDiscordNotification(event) that constructs and sends Discord embeds via fetch, and three helper functions that translate event types to titles, format descriptions from event data, and conditionally include user and resume fields in the embed payload.

Sequence Diagram(s)

N/A — Single-module service with straightforward sequential formatting and HTTP POST logic; no multi-component interaction flow to visualize.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Possibly related issues

  • #226 — Implements the Discord webhook notification utility requested by the issue; provides the sendDiscordNotification service function with environment-based URL configuration and event-to-embed formatting.

Poem

🐰 A webhook hops through Discord's door,
Events formatted, colors galore,
Embeds float swift on the fetch-powered breeze,
Notifications land with elegant ease! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding Discord webhook notifications for platform events, which aligns with the code addition of a new Discord notification service.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/services/discord-webhook.js

Parsing error: The keyword 'const' is reserved


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/services/discord-webhook.js`:
- Around line 13-19: The sendDiscordNotification function dereferences
event.type without guarding for null/undefined; update sendDiscordNotification
to defensively check that event and event.type exist (e.g., if (!event ||
!event.type) return false) before using getTitle(event.type),
getDescription(event) and EVENT_COLORS[event.type], and apply the same guard to
the later block that also reads event.type (the section around lines 42-49) so
the function fails closed instead of throwing.
- Around line 24-30: Wrap the fetch to DISCORD_WEBHOOK_URL in a try/catch and
use an AbortController with a 5-second timeout so network errors/timeouts don't
throw or hang; pass controller.signal to fetch and clear the timeout after
completion, and on any error or non-ok response return false to preserve the
function's boolean contract (ensure you still send the JSON payload with
username 'JSON Resume' and embeds: [embed]).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 68f30ce5-f4d2-445c-9504-ac19d073f635

📥 Commits

Reviewing files that changed from the base of the PR and between c9ed5d3 and d5f86d1.

📒 Files selected for processing (1)
  • src/services/discord-webhook.js

Comment on lines +13 to +19
async function sendDiscordNotification(event) {
if (!DISCORD_WEBHOOK_URL) return false;

const embed = {
title: getTitle(event.type),
description: getDescription(event),
color: EVENT_COLORS[event.type] || 0x808080,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard against malformed events before dereferencing event.type.

If event is null/undefined, this throws at runtime. Add a defensive guard and fail closed.

Suggested fix
 async function sendDiscordNotification(event) {
   if (!DISCORD_WEBHOOK_URL) return false;
+  if (!event || !event.type) return false;

Also applies to: 42-49

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/discord-webhook.js` around lines 13 - 19, The
sendDiscordNotification function dereferences event.type without guarding for
null/undefined; update sendDiscordNotification to defensively check that event
and event.type exist (e.g., if (!event || !event.type) return false) before
using getTitle(event.type), getDescription(event) and EVENT_COLORS[event.type],
and apply the same guard to the later block that also reads event.type (the
section around lines 42-49) so the function fails closed instead of throwing.

Comment on lines +24 to +30
const response = await fetch(DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'JSON Resume', embeds: [embed] }),
});

return response.ok;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether there is already a shared HTTP client pattern in this repo
# (helps align this service with existing timeout/retry conventions).
rg -n --type=js -C2 "axios.create|from 'axios'|require\\('axios'\\)|fetch\\(" src

Repository: jsonresume/jsonresume.org

Length of output: 379


🏁 Script executed:

cat -n src/services/discord-webhook.js

Repository: jsonresume/jsonresume.org

Length of output: 2252


Harden webhook delivery with timeout and error handling.

fetch can reject and has no timeout, causing callers to crash or notification flows to hang under network faults. Wrap the call in try/catch and add an AbortController-based timeout (5 seconds) to return false on failure and preserve the function's boolean contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/discord-webhook.js` around lines 24 - 30, Wrap the fetch to
DISCORD_WEBHOOK_URL in a try/catch and use an AbortController with a 5-second
timeout so network errors/timeouts don't throw or hang; pass controller.signal
to fetch and clear the timeout after completion, and on any error or non-ok
response return false to preserve the function's boolean contract (ensure you
still send the JSON payload with username 'JSON Resume' and embeds: [embed]).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant