Skip to main content

Notifications

HubSpot Deploy's notification system keeps you informed about important events like deployment results, backup failures, and drift detection alerts. Notifications are sent via email to all workspace members, ensuring your team stays up-to-date on critical changes.

Notification Types

HubSpot Deploy sends notifications for the following events:

EventNotification TypeWhen Triggered
Deployment Completeddeploy_resultAfter a deployment finishes (success or failure)
Backup Successfulbackup_successAfter a metadata backup completes successfully
Backup Failedbackup_failWhen a metadata backup fails
Drift Detecteddrift_detectedWhen manual changes are detected in a portal

How Notifications Work

1. Event Occurs

When a significant event happens (e.g., a deployment completes), the application enqueues a notification:

await NotificationService.enqueue(workspaceId, 'deploy_result', {
status: 'completed',
successCount: 10,
failCount: 0,
comparisonId: 'abc-123'
})

2. Notification Queue

The notification is added to the notification_queue table with:

  • Workspace ID — Which workspace to notify
  • Notification Type — Type of event (deploy_result, backup_fail, etc.)
  • Payload — Event-specific data (status, counts, IDs, etc.)
  • Statuspending (waiting to be processed)

3. Notification Worker

The Notification Worker polls the queue every 5 seconds:

  1. Fetches pending notifications
  2. Looks up enabled notification channels for the workspace
  3. Fetches all workspace member emails
  4. Sends the notification via each enabled channel
  5. Updates the notification status to sent or failed

4. Email Delivery

For email notifications:

  1. The worker renders an HTML email template based on the notification type
  2. Sends the email to each workspace member
  3. Logs the result (success or failure)
  4. Retries up to 3 times if delivery fails

Email Notifications

Email Templates

Each notification type has a specific email template:

Deployment Result

Subject: Deployment COMPLETED or Deployment FAILED

Content:

  • Deployment status (completed, failed, partially_deployed)
  • Number of successful items
  • Number of failed items
  • Error message (if failed)
  • Link to view comparison details

Example:

Deployment Result

Status: completed
Successes: 15
Failures: 0

View Comparison Details: [Link]

Backup Successful

Subject: Backup Successful - 2026-04-16

Content:

  • Confirmation that backup completed
  • Connection ID
  • Backup run ID

Example:

Backup Completed

Metadata backup for connection abc-123 was successful.

Run ID: run-456

Backup Failed

Subject: Backup FAILED

Content:

  • Notification that backup failed
  • Connection ID
  • Error message
  • Backup run ID

Example:

Backup Failed

Metadata backup for connection abc-123 failed.

Error: HubSpot API rate limit exceeded

Run ID: run-789

Drift Detected

Subject: ⚠️ Drift Detected in HubSpot Portal abc-123

Content:

  • Alert that manual changes were detected
  • Number of changes found
  • Link to view drift details
  • Recommendation to review and decide on action

Example:

Manual Changes Detected

We found manual changes in your HubSpot portal that were not made via the deployment tool.

Changes count: 5

View Drift Details: [Link]

Review the changes and decide whether to commit them to Git or restore the state from Git.

Notification Channels

Email Channel

Provider: email
Status: ✅ Fully implemented

Configuration:

  • SMTP host, port, and credentials (configured via environment variables)
  • From email address
  • Enabled/disabled per workspace

Recipients:

  • All workspace members (admins and members)
  • Emails are fetched from the profiles table

Slack Channel

Provider: slack
Status: 🚧 Planned (not yet implemented)

Planned Features:

  • Send notifications to a Slack channel
  • Configurable webhook URL per workspace
  • Rich message formatting with buttons

Microsoft Teams Channel

Provider: teams
Status: 🚧 Planned (not yet implemented)

Planned Features:

  • Send notifications to a Teams channel
  • Configurable webhook URL per workspace
  • Adaptive card formatting

Configuring Notifications

Email Configuration (Environment Variables)

Email notifications are configured via environment variables in the backend:

# SMTP Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password

# From Address
NOTIFICATION_FROM_EMAIL=noreply@hubspot-deploy.com

# Frontend URL (for links in emails)
FRONTEND_URL=https://app.hubspot-deploy.com

SMTP Providers:

  • Gmail: smtp.gmail.com:587 (requires app password)
  • SendGrid: smtp.sendgrid.net:587
  • AWS SES: email-smtp.us-east-1.amazonaws.com:587
  • Mailgun: smtp.mailgun.org:587
  • Custom SMTP: Any SMTP server
Gmail Setup

To use Gmail:

  1. Enable 2-factor authentication on your Google account
  2. Generate an app password: https://myaccount.google.com/apppasswords
  3. Use the app password in SMTP_PASS

Workspace Notification Channels

Each workspace can have multiple notification channels configured in the notification_channels table:

CREATE TABLE notification_channels (
id UUID PRIMARY KEY,
workspace_id UUID NOT NULL,
provider_type TEXT NOT NULL, -- 'email', 'slack', 'teams'
config JSONB NOT NULL, -- Provider-specific config
enabled BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW()
);

Default Channel: When a workspace is created, an email channel is automatically enabled with default SMTP settings.


Managing Notifications

Viewing Notification History

Currently, there is no UI for viewing notification history. However, you can query the database:

SELECT
id,
notification_type,
status,
created_at,
processed_at,
error_log
FROM notification_queue
WHERE workspace_id = 'your-workspace-id'
ORDER BY created_at DESC
LIMIT 50;

Status Values:

  • pending — Waiting to be processed
  • sent — Successfully sent
  • failed — Failed after 3 retries

Disabling Notifications

To disable notifications for a workspace:

UPDATE notification_channels
SET enabled = false
WHERE workspace_id = 'your-workspace-id'
AND provider_type = 'email';

To re-enable:

UPDATE notification_channels
SET enabled = true
WHERE workspace_id = 'your-workspace-id'
AND provider_type = 'email';
note

A UI for managing notification preferences is planned for a future release.


Notification Recipients

Who Receives Notifications?

All workspace members (both admins and members) receive notifications. Recipients are determined by:

  1. Workspace Membership

    • Query the workspace_members table for the workspace
    • Get all user IDs
  2. User Profiles

    • Query the profiles table for each user ID
    • Extract email addresses
  3. Email Validation

    • Filter out null or invalid emails
    • Send to all valid emails

Adding Recipients

To add a recipient, invite them to the workspace:

  1. Go to Workspace Settings
  2. Click Invite Member
  3. Enter their email address
  4. They will receive notifications once they accept the invitation

Removing Recipients

To remove a recipient, remove them from the workspace:

  1. Go to Workspace Settings
  2. Find the member in the list
  3. Click Remove
  4. They will no longer receive notifications

Notification Delivery

Retry Logic

If a notification fails to send, the system retries up to 3 times:

  1. First Attempt — Immediate
  2. Second Attempt — After next poll (5 seconds)
  3. Third Attempt — After next poll (5 seconds)
  4. Final Status — Marked as failed if all attempts fail

Delivery Guarantees

  • At-least-once delivery — Notifications may be sent multiple times in rare cases
  • No guaranteed order — Notifications may arrive out of order
  • Best-effort delivery — If SMTP is down, notifications will fail

Monitoring Delivery

Check the notification_queue table for delivery status:

-- Count notifications by status
SELECT status, COUNT(*)
FROM notification_queue
WHERE workspace_id = 'your-workspace-id'
GROUP BY status;

-- View failed notifications
SELECT *
FROM notification_queue
WHERE status = 'failed'
AND workspace_id = 'your-workspace-id'
ORDER BY created_at DESC;

Troubleshooting

Not Receiving Emails

Possible Causes:

  1. SMTP credentials are incorrect
  2. Email is in spam folder
  3. Notification channel is disabled
  4. User is not a workspace member
  5. User's email is not set in their profile

Solutions:

  1. Check SMTP Configuration

    # Verify environment variables
    echo $SMTP_HOST
    echo $SMTP_USER
  2. Check Spam Folder

    • Look for emails from noreply@hubspot-deploy.com
    • Mark as "Not Spam" and add to contacts
  3. Verify Channel is Enabled

    SELECT enabled
    FROM notification_channels
    WHERE workspace_id = 'your-workspace-id'
    AND provider_type = 'email';
  4. Verify Workspace Membership

    SELECT *
    FROM workspace_members
    WHERE workspace_id = 'your-workspace-id';
  5. Verify Email in Profile

    SELECT email
    FROM profiles
    WHERE id = 'your-user-id';

Emails Stuck in "Pending"

Cause: Notification Worker is not running or is overloaded.

Solution:

  1. Check if the Notification Worker is running:

    ps aux | grep notificationLauncher
  2. Restart the worker:

    npm run worker:notifications
  3. Check worker logs for errors:

    tail -f logs/notification-worker.log

SMTP Authentication Failed

Cause: Invalid SMTP credentials or 2FA not configured.

Solution:

For Gmail:

  1. Enable 2-factor authentication
  2. Generate an app password
  3. Use the app password in SMTP_PASS

For Other Providers:

  1. Verify username and password are correct
  2. Check if the SMTP server requires TLS/SSL
  3. Ensure the SMTP port is correct (587 for TLS, 465 for SSL)

Notification Sent Multiple Times

Cause: Worker restarted during processing or database transaction failed.

Solution:

  • This is expected behavior (at-least-once delivery)
  • Duplicate notifications are rare and usually harmless
  • If frequent, check worker logs for errors

Best Practices

1. Use a Dedicated Email Service

For production, use a dedicated email service like:

  • SendGrid — Reliable, good free tier
  • AWS SES — Scalable, pay-per-email
  • Mailgun — Developer-friendly
  • Postmark — High deliverability

Avoid using personal Gmail accounts for production notifications.

2. Monitor Notification Queue

Regularly check the notification_queue table for:

  • Failed notifications (investigate and retry)
  • Pending notifications stuck for >1 hour (restart worker)
  • High volume of notifications (may indicate an issue)

3. Test Notifications

After setting up SMTP, test notifications:

  1. Trigger a manual backup
  2. Wait for it to complete
  3. Check your email for the "Backup Successful" notification
  4. If not received, check troubleshooting steps

4. Configure Spam Filters

Add noreply@hubspot-deploy.com to your email whitelist to ensure notifications aren't marked as spam.

5. Set Up Alerts for Failed Notifications

Create a monitoring alert for failed notifications:

SELECT COUNT(*)
FROM notification_queue
WHERE status = 'failed'
AND created_at > NOW() - INTERVAL '1 hour';

If count > 5, investigate SMTP issues.


Future Enhancements

Planned Features

  1. Notification Preferences UI

    • Enable/disable notifications per user
    • Choose which notification types to receive
    • Set quiet hours (no notifications during certain times)
  2. Slack Integration

    • Send notifications to Slack channels
    • Rich message formatting with buttons
    • Interactive actions (approve deployment, view details)
  3. Microsoft Teams Integration

    • Send notifications to Teams channels
    • Adaptive card formatting
    • Actionable messages
  4. Notification History UI

    • View all past notifications in the dashboard
    • Filter by type, status, date
    • Resend failed notifications
  5. Custom Notification Templates

    • Customize email templates per workspace
    • Add company branding
    • Include custom fields
  6. Webhook Notifications

    • Send notifications to custom webhooks
    • Integrate with third-party tools (PagerDuty, Datadog, etc.)

API Reference

Enqueue Notification

await NotificationService.enqueue(workspaceId, type, payload)

Parameters:

  • workspaceId (string) — The workspace to notify
  • type (string) — Notification type (deploy_result, backup_success, backup_fail, drift_detected)
  • payload (object) — Event-specific data

Returns:

  • booleantrue if enqueued successfully, false otherwise

Example:

await NotificationService.enqueue('workspace-123', 'deploy_result', {
status: 'completed',
successCount: 10,
failCount: 0,
comparisonId: 'comparison-456'
})

Database Schema

notification_queue

CREATE TABLE notification_queue (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
notification_type TEXT NOT NULL,
payload JSONB NOT NULL,
status TEXT NOT NULL DEFAULT 'pending', -- 'pending', 'sent', 'failed'
retry_count INTEGER DEFAULT 0,
error_log JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
processed_at TIMESTAMPTZ
);

notification_channels

CREATE TABLE notification_channels (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
provider_type TEXT NOT NULL, -- 'email', 'slack', 'teams'
config JSONB NOT NULL,
enabled BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);