diff --git a/backend/.env.dist.local b/backend/.env.dist.local index b6913d5585..d286b5d784 100755 --- a/backend/.env.dist.local +++ b/backend/.env.dist.local @@ -127,9 +127,6 @@ CROWD_ORGANIZATION_ENRICHMENT_API_KEY= CROWD_EAGLE_EYE_URL= CROWD_EAGLE_EYE_API_KEY= -# Slack alerting settings -CROWD_SLACK_ALERTING_URL= - # Weekly emails settings CROWD_WEEKLY_EMAILS_ENABLED="true" diff --git a/backend/config/custom-environment-variables.json b/backend/config/custom-environment-variables.json index c99a9f8422..c13a0e82a2 100644 --- a/backend/config/custom-environment-variables.json +++ b/backend/config/custom-environment-variables.json @@ -143,9 +143,6 @@ "installationId": "GITHUB_TOKEN_INSTALLATION_ID", "privateKey": "GITHUB_TOKEN_PRIVATE_KEY" }, - "slackAlerting": { - "url": "CROWD_SLACK_ALERTING_URL" - }, "weeklyEmails": { "enabled": "CROWD_WEEKLY_EMAILS_ENABLED" }, diff --git a/backend/config/default.json b/backend/config/default.json index dc4148b193..e60af044e2 100644 --- a/backend/config/default.json +++ b/backend/config/default.json @@ -37,9 +37,6 @@ "organizationEnrichment": {}, "eagleEye": {}, "githubToken": {}, - "slackAlerting": { - "url": "" - }, "auth0": {}, "sso": {}, "crowdAnalytics": { diff --git a/backend/src/api/apiResponseHandler.ts b/backend/src/api/apiResponseHandler.ts index 7bf4a8b684..debe217a58 100644 --- a/backend/src/api/apiResponseHandler.ts +++ b/backend/src/api/apiResponseHandler.ts @@ -120,7 +120,7 @@ export default class ApiResponseHandler extends LoggerBase { } sendSlackNotification( - SlackChannel.ALERTS, + SlackChannel.CDP_ALERTS, SlackPersona.ERROR_REPORTER, `API Error ${code}: ${req.method} ${req.url}`, sections, diff --git a/backend/src/api/public/middlewares/errorHandler.ts b/backend/src/api/public/middlewares/errorHandler.ts index d8cdcafff1..8b514093b0 100644 --- a/backend/src/api/public/middlewares/errorHandler.ts +++ b/backend/src/api/public/middlewares/errorHandler.ts @@ -40,7 +40,7 @@ export const errorHandler: ErrorRequestHandler = ( ) sendSlackNotification( - SlackChannel.ALERTS, + SlackChannel.CDP_ALERTS, SlackPersona.ERROR_REPORTER, `Public API Error 500: ${req.method} ${req.url}`, [ diff --git a/backend/src/api/public/v1/members/identities/verifyMemberIdentity.ts b/backend/src/api/public/v1/members/identities/verifyMemberIdentity.ts index a7e725e587..cd278481c6 100644 --- a/backend/src/api/public/v1/members/identities/verifyMemberIdentity.ts +++ b/backend/src/api/public/v1/members/identities/verifyMemberIdentity.ts @@ -139,7 +139,7 @@ export async function verifyMemberIdentity(req: Request, res: Response): Promise } catch (error) { req.log.warn({ error }, 'Audit log capture failed after identity unmerge') sendSlackNotification( - SlackChannel.ALERTS, + SlackChannel.CDP_ALERTS, SlackPersona.ERROR_REPORTER, `Audit log capture failed after identity unmerge: member ${memberId}`, [{ title: 'Error', text: `\`${error?.message || error}\`` }], @@ -164,7 +164,7 @@ export async function verifyMemberIdentity(req: Request, res: Response): Promise } catch (error) { req.log.warn({ error }, 'Failed to start unmerge workflow after identity unmerge') sendSlackNotification( - SlackChannel.ALERTS, + SlackChannel.CDP_ALERTS, SlackPersona.ERROR_REPORTER, `Failed to start unmerge workflow after identity unmerge: member ${memberId}`, [ diff --git a/backend/src/conf/configTypes.ts b/backend/src/conf/configTypes.ts index 417b509284..ad764fa29e 100644 --- a/backend/src/conf/configTypes.ts +++ b/backend/src/conf/configTypes.ts @@ -156,10 +156,6 @@ export interface StackExchangeConfiguration { key: string } -export interface SlackAlertingConfiguration { - url: string -} - export interface IntegrationProcessingConfiguration { maxRetries: number } diff --git a/backend/src/conf/index.ts b/backend/src/conf/index.ts index 82d72cf7db..dfebb3c4ea 100644 --- a/backend/src/conf/index.ts +++ b/backend/src/conf/index.ts @@ -33,7 +33,6 @@ import { SSOConfiguration, SegmentConfiguration, ServiceType, - SlackAlertingConfiguration, SlackConfiguration, SnowflakeConfiguration, StackExchangeConfiguration, @@ -132,9 +131,6 @@ export const STACKEXCHANGE_CONFIG: StackExchangeConfiguration = key: process.env.STACKEXCHANGE_KEY, } -export const SLACK_ALERTING_CONFIG: SlackAlertingConfiguration = - config.get('slackAlerting') - export const INTEGRATION_PROCESSING_CONFIG: IntegrationProcessingConfiguration = config.get('integrationProcessing') diff --git a/services/apps/cron_service/src/jobs/nangoMonitoring.job.ts b/services/apps/cron_service/src/jobs/nangoMonitoring.job.ts index 19b5af5dc0..2163c79be4 100644 --- a/services/apps/cron_service/src/jobs/nangoMonitoring.job.ts +++ b/services/apps/cron_service/src/jobs/nangoMonitoring.job.ts @@ -326,7 +326,7 @@ const job: IJobDefinition = { // Queue notification for this platform notificationPromises.push( sendSlackNotificationAsync( - SlackChannel.NANGO_ALERTS, + SlackChannel.CDP_INTEGRATIONS_ALERTS, persona, `Nango Monitor: ${nangoIntegration}`, sections, @@ -344,7 +344,7 @@ const job: IJobDefinition = { if (failedStatusChecks > 0) { notificationPromises.push( sendSlackNotificationAsync( - SlackChannel.NANGO_ALERTS, + SlackChannel.CDP_INTEGRATIONS_ALERTS, SlackPersona.ERROR_REPORTER, 'Nango Monitor: API Errors', `Failed to retrieve status for ${failedStatusChecks} connection${failedStatusChecks > 1 ? 's' : ''} due to Nango API errors.\n\nCheck logs for details.`, diff --git a/services/apps/cron_service/src/jobs/queueMonitoring.job.ts b/services/apps/cron_service/src/jobs/queueMonitoring.job.ts index 169133d513..5ddc20f4d3 100644 --- a/services/apps/cron_service/src/jobs/queueMonitoring.job.ts +++ b/services/apps/cron_service/src/jobs/queueMonitoring.job.ts @@ -53,7 +53,7 @@ const job: IJobDefinition = { if (msg && msg.trim().length > 0) { await sendSlackNotificationAsync( - SlackChannel.ALERTS, + SlackChannel.CDP_CRITICAL_ALERTS, SlackPersona.WARNING_PROPAGATOR, 'Queue Monitoring Alert', msg, diff --git a/services/apps/cron_service/src/main.ts b/services/apps/cron_service/src/main.ts index 756233c63e..8199c64b87 100644 --- a/services/apps/cron_service/src/main.ts +++ b/services/apps/cron_service/src/main.ts @@ -149,7 +149,7 @@ const queueJob = async (job: IJobDefinition) => { if (err instanceof Error && err.message.includes('did not finish in time')) { sendSlackNotificationAsync( - SlackChannel.ALERTS, + SlackChannel.CDP_CRITICAL_ALERTS, SlackPersona.CRITICAL_ALERTER, `Cron job timed out: ${job.name}`, `Job \`${job.name}\` was killed after exceeding its ${job.timeout}s timeout (ran for ${diff}s).`, diff --git a/services/apps/data_sink_worker/config/custom-environment-variables.json b/services/apps/data_sink_worker/config/custom-environment-variables.json index 07554b54d9..30925aa578 100644 --- a/services/apps/data_sink_worker/config/custom-environment-variables.json +++ b/services/apps/data_sink_worker/config/custom-environment-variables.json @@ -10,9 +10,6 @@ "brokers": "CROWD_KAFKA_BROKERS", "extra": "CROWD_KAFKA_EXTRA" }, - "slackAlerting": { - "url": "CROWD_SLACK_ALERTING_URL" - }, "redis": { "username": "CROWD_REDIS_USERNAME", "password": "CROWD_REDIS_PASSWORD", diff --git a/services/apps/data_sink_worker/src/conf/index.ts b/services/apps/data_sink_worker/src/conf/index.ts index ec71246f7b..4b91a2959a 100644 --- a/services/apps/data_sink_worker/src/conf/index.ts +++ b/services/apps/data_sink_worker/src/conf/index.ts @@ -7,10 +7,6 @@ import { IRedisConfiguration } from '@crowd/redis' import { ITemporalConfig } from '@crowd/temporal' import { QueuePriorityLevel } from '@crowd/types' -export interface ISlackAlertingConfig { - url: string -} - export interface IGithubConfig { isSnowflakeEnabled: string } @@ -52,14 +48,6 @@ export const DB_CONFIG = (): IDatabaseConfig => { return dbConfig } -let slackAlertingConfig: ISlackAlertingConfig -export const SLACK_ALERTING_CONFIG = (): ISlackAlertingConfig => { - if (slackAlertingConfig) return slackAlertingConfig - - slackAlertingConfig = config.get('slackAlerting') - return slackAlertingConfig -} - let temporalConfig: ITemporalConfig | undefined export const TEMPORAL_CONFIG = (): ITemporalConfig | undefined => { if (temporalConfig) return temporalConfig diff --git a/services/apps/integration_run_worker/config/custom-environment-variables.json b/services/apps/integration_run_worker/config/custom-environment-variables.json index 881c909be6..6c0ca2c788 100644 --- a/services/apps/integration_run_worker/config/custom-environment-variables.json +++ b/services/apps/integration_run_worker/config/custom-environment-variables.json @@ -20,9 +20,6 @@ "url": "CROWD_NANGO_URL", "secretKey": "CROWD_NANGO_SECRET_KEY" }, - "slackAlerting": { - "url": "CROWD_SLACK_ALERTING_URL" - }, "github": { "appId": "CROWD_GITHUB_APP_ID", "clientId": "CROWD_GITHUB_CLIENT_ID", diff --git a/services/apps/integration_run_worker/src/conf/index.ts b/services/apps/integration_run_worker/src/conf/index.ts index fd5717c7eb..2986fa9be1 100644 --- a/services/apps/integration_run_worker/src/conf/index.ts +++ b/services/apps/integration_run_worker/src/conf/index.ts @@ -11,9 +11,6 @@ export interface INangoConfig { secretKey: string } -export interface ISlackAlertingConfig { - url: string -} export interface ILokiDbConfig { url: string token: string @@ -64,14 +61,6 @@ export const NANGO_CONFIG = (): INangoConfig => { return nangoConfig } -let slackAlertingConfig: ISlackAlertingConfig -export const SLACK_ALERTING_CONFIG = (): ISlackAlertingConfig => { - if (slackAlertingConfig) return slackAlertingConfig - - slackAlertingConfig = config.get('slackAlerting') - return slackAlertingConfig -} - const platformMap: Map = new Map() export const PLATFORM_CONFIG = (platform: string): unknown | undefined => { if (platformMap.has(platform)) { diff --git a/services/apps/snowflake_connectors/src/activities/cleanupActivity.ts b/services/apps/snowflake_connectors/src/activities/cleanupActivity.ts index 03f39f6659..373494a1fc 100644 --- a/services/apps/snowflake_connectors/src/activities/cleanupActivity.ts +++ b/services/apps/snowflake_connectors/src/activities/cleanupActivity.ts @@ -23,7 +23,7 @@ export async function executeCleanup(intervalHours = 24): Promise { } catch (err) { log.error({ jobId: job.id, s3Path: job.s3Path, err }, 'Failed to clean job, skipping') sendSlackNotification( - SlackChannel.INTEGRATION_NOTIFICATIONS, + SlackChannel.CDP_INTEGRATIONS_ALERTS, SlackPersona.ERROR_REPORTER, 'Snowflake S3 Cleanup Failed', `Failed to clean job \`${job.id}\` at \`${job.s3Path}\`.\n\n*Error:* ${err instanceof Error ? err.message : err}`, diff --git a/services/apps/snowflake_connectors/src/schedules/snowflakeS3Cleanup.ts b/services/apps/snowflake_connectors/src/schedules/snowflakeS3Cleanup.ts index 32ce4221ce..b91837aa46 100644 --- a/services/apps/snowflake_connectors/src/schedules/snowflakeS3Cleanup.ts +++ b/services/apps/snowflake_connectors/src/schedules/snowflakeS3Cleanup.ts @@ -36,7 +36,7 @@ export const scheduleSnowflakeS3Cleanup = async () => { } else { svc.log.error({ err }, 'Failed to create snowflake-s3-cleanup schedule') sendSlackNotification( - SlackChannel.INTEGRATION_NOTIFICATIONS, + SlackChannel.CDP_INTEGRATIONS_ALERTS, SlackPersona.ERROR_REPORTER, 'Snowflake S3 Cleanup Schedule Failed', `Failed to create the \`snowflake-s3-cleanup\` Temporal schedule.\n\n*Error:* ${err.message || err}`, diff --git a/services/apps/snowflake_connectors/src/schedules/snowflakeS3Export.ts b/services/apps/snowflake_connectors/src/schedules/snowflakeS3Export.ts index 96880433e4..a87b1d4f42 100644 --- a/services/apps/snowflake_connectors/src/schedules/snowflakeS3Export.ts +++ b/services/apps/snowflake_connectors/src/schedules/snowflakeS3Export.ts @@ -36,7 +36,7 @@ export const scheduleSnowflakeS3Export = async () => { } else { svc.log.error({ err }, 'Failed to create snowflake-s3-export schedule') sendSlackNotification( - SlackChannel.INTEGRATION_NOTIFICATIONS, + SlackChannel.CDP_INTEGRATIONS_ALERTS, SlackPersona.ERROR_REPORTER, 'Snowflake S3 Export Schedule Failed', `Failed to create the \`snowflake-s3-export\` Temporal schedule.\n\n*Error:* ${err.message || err}`, diff --git a/services/archetypes/worker/src/activities/activityInterceptor.ts b/services/archetypes/worker/src/activities/activityInterceptor.ts index 872260f76d..e87fb38d2e 100644 --- a/services/archetypes/worker/src/activities/activityInterceptor.ts +++ b/services/archetypes/worker/src/activities/activityInterceptor.ts @@ -34,7 +34,7 @@ export class ActivityMonitoringInterceptor implements ActivityInboundCallsInterc // Fire and forget - don't await to avoid blocking the activity sendSlackNotificationAsync( - SlackChannel.ALERTS, + SlackChannel.CDP_ALERTS, SlackPersona.WARNING_PROPAGATOR, 'High Activity Retry Count', message, diff --git a/services/archetypes/worker/src/activities/index.ts b/services/archetypes/worker/src/activities/index.ts index ac4d1df151..c8c72b06be 100644 --- a/services/archetypes/worker/src/activities/index.ts +++ b/services/archetypes/worker/src/activities/index.ts @@ -23,7 +23,7 @@ async function telemetryIncrement( async function slackNotify(message: string, persona: SlackPersona | string) { // Accept string to allow workflow code to pass string literals without importing enum await sendSlackNotificationAsync( - SlackChannel.ALERTS, + SlackChannel.CDP_ALERTS, persona as SlackPersona, 'Temporal Alert', message, diff --git a/services/libs/slack/src/channels.ts b/services/libs/slack/src/channels.ts index a7c4c3d076..91a00bcc19 100644 --- a/services/libs/slack/src/channels.ts +++ b/services/libs/slack/src/channels.ts @@ -5,11 +5,11 @@ import { SlackChannel, SlackChannelConfig } from './types' const log = getServiceLogger() const CHANNEL_WEBHOOK_URLS: Record = { - [SlackChannel.ALERTS]: process.env.CM_ALERTS_SLACK_WEBHOOK_URL, - [SlackChannel.DATA_ALERTS]: process.env.CM_DATA_ALERTS_SLACK_WEBHOOK_URL, - [SlackChannel.INTEGRATION_NOTIFICATIONS]: - process.env.CM_INTEGRATION_NOTIFICATIONS_SLACK_WEBHOOK_URL, - [SlackChannel.NANGO_ALERTS]: process.env.CM_NANGO_ALERTS_SLACK_WEBHOOK_URL, + [SlackChannel.CDP_ALERTS]: process.env.CDP_ALERTS_SLACK_WEBHOOK_URL, + [SlackChannel.CDP_CRITICAL_ALERTS]: process.env.CDP_CRITICAL_ALERTS_SLACK_WEBHOOK_URL, + [SlackChannel.CDP_DATA_QUALITY_ALERTS]: process.env.CDP_DATA_QUALITY_ALERTS_SLACK_WEBHOOK_URL, + [SlackChannel.CDP_INTEGRATIONS_ALERTS]: process.env.CDP_INTEGRATIONS_ALERTS_SLACK_WEBHOOK_URL, + [SlackChannel.CDP_PROJECTS_ALERTS]: process.env.CDP_PROJECTS_ALERTS_SLACK_WEBHOOK_URL, } // Check for missing webhook URLs on initialization @@ -26,7 +26,7 @@ function checkChannelConfigurations(): void { if (missingChannels.length > 0) { log.warn( { missingChannels }, - `Slack webhook URLs not configured for channels: ${missingChannels.join(', ')}. Set CM_{CHANNEL}_SLACK_WEBHOOK_URL environment variables.`, + `Slack webhook URLs not configured for channels: ${missingChannels.join(', ')}. Set the following env vars: ${missingChannels.map((c) => `${c}_SLACK_WEBHOOK_URL`).join(', ')}.`, ) } else { log.debug('All Slack channel webhook URLs are configured') diff --git a/services/libs/slack/src/client.ts b/services/libs/slack/src/client.ts index 5e29730318..4025c87b50 100644 --- a/services/libs/slack/src/client.ts +++ b/services/libs/slack/src/client.ts @@ -21,7 +21,7 @@ export function getWebhookClient(channel: SlackChannel): IncomingWebhook | null if (!config.webhookUrl) { log.warn( { channel }, - `Slack webhook URL not configured for channel ${channel}. Set CM_${channel}_SLACK_WEBHOOK_URL environment variable.`, + `Slack webhook URL not configured for channel ${channel}. Set ${channel}_SLACK_WEBHOOK_URL environment variable.`, ) return null } diff --git a/services/libs/slack/src/types.ts b/services/libs/slack/src/types.ts index 02c9c18144..cec6a42ce9 100644 --- a/services/libs/slack/src/types.ts +++ b/services/libs/slack/src/types.ts @@ -1,8 +1,9 @@ export enum SlackChannel { - ALERTS = 'ALERTS', - DATA_ALERTS = 'DATA_ALERTS', - INTEGRATION_NOTIFICATIONS = 'INTEGRATION_NOTIFICATIONS', - NANGO_ALERTS = 'NANGO_ALERTS', + CDP_ALERTS = 'CDP_ALERTS', + CDP_CRITICAL_ALERTS = 'CDP_CRITICAL_ALERTS', + CDP_DATA_QUALITY_ALERTS = 'CDP_DATA_QUALITY_ALERTS', + CDP_INTEGRATIONS_ALERTS = 'CDP_INTEGRATIONS_ALERTS', + CDP_PROJECTS_ALERTS = 'CDP_PROJECTS_ALERTS', } export enum SlackPersona {