diff --git a/macros/marketplace/slack/messaging_udfs.yaml.sql b/macros/marketplace/slack/messaging_udfs.yaml.sql index 7bfc025..2d026ac 100644 --- a/macros/marketplace/slack/messaging_udfs.yaml.sql +++ b/macros/marketplace/slack/messaging_udfs.yaml.sql @@ -6,31 +6,29 @@ {# Slack Webhook Messages #} - name: {{ schema_name }}.webhook_send signature: - - [WEBHOOK_URL, STRING, Slack webhook URL] + - [WEBHOOK_SECRET_NAME, STRING, "Name of webhook secret in vault (e.g., 'alerts', 'notifications')"] - [PAYLOAD, OBJECT, Complete Slack message payload according to Slack API spec] return_type: - "OBJECT" options: | - COMMENT = $$Send a message to Slack via webhook [API docs: Webhooks](https://api.slack.com/messaging/webhooks)$$ + COMMENT = 'Send a message to Slack via webhook [API docs: Webhooks](https://api.slack.com/messaging/webhooks)' sql: | - SELECT slack_utils.post_webhook( - WEBHOOK_URL, + SELECT {{ utils_schema_name }}.post_webhook( + WEBHOOK_SECRET_NAME, PAYLOAD ) as response {# Slack Web API Messages #} - name: {{ schema_name }}.post_message signature: - - [BOT_TOKEN, STRING, Slack bot token (xoxb-...)] - [CHANNEL, STRING, Slack channel ID or name] - [PAYLOAD, OBJECT, Message payload according to Slack chat.postMessage API spec] return_type: - "OBJECT" options: | - COMMENT = $$Send a message to Slack via Web API [API docs: chat.postMessage](https://api.slack.com/methods/chat.postMessage)$$ + COMMENT = 'Send a message to Slack via Web API [API docs: chat.postMessage](https://api.slack.com/methods/chat.postMessage)' sql: | - SELECT slack_utils.post_message( - BOT_TOKEN, + SELECT {{ utils_schema_name }}.post_message( CHANNEL, PAYLOAD ) as response @@ -38,17 +36,15 @@ - name: {{ schema_name }}.post_reply signature: - - [BOT_TOKEN, STRING, Slack bot token (xoxb-...)] - [CHANNEL, STRING, Slack channel ID or name] - [THREAD_TS, STRING, Parent message timestamp for threading] - [PAYLOAD, OBJECT, Message payload according to Slack chat.postMessage API spec] return_type: - "OBJECT" options: | - COMMENT = $$Send a threaded reply to Slack via Web API [API docs: chat.postMessage](https://api.slack.com/methods/chat.postMessage)$$ + COMMENT = 'Send a threaded reply to Slack via Web API [API docs: chat.postMessage](https://api.slack.com/methods/chat.postMessage)' sql: | - SELECT slack_utils.post_reply( - BOT_TOKEN, + SELECT {{ utils_schema_name }}.post_reply( CHANNEL, THREAD_TS, PAYLOAD diff --git a/macros/marketplace/slack/utils_udfs.yaml.sql b/macros/marketplace/slack/utils_udfs.yaml.sql index 8909919..a7790bc 100644 --- a/macros/marketplace/slack/utils_udfs.yaml.sql +++ b/macros/marketplace/slack/utils_udfs.yaml.sql @@ -1,36 +1,35 @@ {% macro config_slack_utils_udfs(schema_name = "slack_utils", utils_schema_name = "slack_utils") -%} {# This macro is used to generate API calls to Slack API endpoints -#} - + #} - name: {{ schema_name }}.post_webhook signature: - - [WEBHOOK_URL, STRING, Slack webhook URL] + - [WEBHOOK_SECRET_NAME, STRING, "Name of webhook secret in vault (e.g., 'alerts', 'notifications')"] - [PAYLOAD, OBJECT, Complete Slack message payload according to Slack API spec] return_type: - "OBJECT" options: | - COMMENT = $$Send a message to Slack via webhook. User provides complete payload according to Slack webhook API spec.$$ + COMMENT = $$Send a message to Slack via webhook. User provides secret name for webhook URL stored in vault.$$ sql: | - SELECT CASE - WHEN WEBHOOK_URL IS NULL OR WEBHOOK_URL = '' THEN - OBJECT_CONSTRUCT('ok', false, 'error', 'webhook_url is required') - WHEN NOT STARTSWITH(WEBHOOK_URL, 'https://hooks.slack.com/') THEN - OBJECT_CONSTRUCT('ok', false, 'error', 'Invalid webhook URL format') + SELECT CASE + WHEN WEBHOOK_SECRET_NAME IS NULL OR WEBHOOK_SECRET_NAME = '' THEN + OBJECT_CONSTRUCT('ok', false, 'error', 'webhook_secret_name is required') WHEN PAYLOAD IS NULL THEN OBJECT_CONSTRUCT('ok', false, 'error', 'payload is required') ELSE live.udf_api( 'POST', - WEBHOOK_URL, + '{WEBHOOK_URL}', OBJECT_CONSTRUCT('Content-Type', 'application/json'), - PAYLOAD + PAYLOAD, + IFF(_utils.udf_whoami() <> CURRENT_USER(), + '_FSC_SYS/SLACK/' || WEBHOOK_SECRET_NAME, + 'Vault/prod/livequery/slack/' || WEBHOOK_SECRET_NAME) ) END as response - name: {{ schema_name }}.post_message signature: - - [BOT_TOKEN, STRING, Slack bot token (xoxb-...)] - [CHANNEL, STRING, Slack channel ID or name] - [PAYLOAD, OBJECT, Message payload according to Slack chat.postMessage API spec] return_type: @@ -38,11 +37,7 @@ options: | COMMENT = $$Send a message to Slack via Web API chat.postMessage. User provides complete payload according to Slack API spec.$$ sql: | - SELECT CASE - WHEN BOT_TOKEN IS NULL OR BOT_TOKEN = '' THEN - OBJECT_CONSTRUCT('ok', false, 'error', 'bot_token is required') - WHEN NOT STARTSWITH(BOT_TOKEN, 'xoxb-') THEN - OBJECT_CONSTRUCT('ok', false, 'error', 'Invalid bot token format') + SELECT CASE WHEN CHANNEL IS NULL OR CHANNEL = '' THEN OBJECT_CONSTRUCT('ok', false, 'error', 'channel is required') WHEN PAYLOAD IS NULL THEN @@ -52,16 +47,16 @@ 'POST', 'https://slack.com/api/chat.postMessage', OBJECT_CONSTRUCT( - 'Authorization', 'Bearer ' || BOT_TOKEN, + 'Authorization', 'Bearer {BOT_TOKEN}', 'Content-Type', 'application/json' ), - OBJECT_INSERT(PAYLOAD, 'channel', CHANNEL) + OBJECT_INSERT(PAYLOAD, 'channel', CHANNEL), + IFF(_utils.udf_whoami() <> CURRENT_USER(), '_FSC_SYS/SLACK', 'Vault/prod/livequery/slack') ) END as response -- name: {{ schema_name }}.post_reply +- name: {{ schema_name }}.post_reply signature: - - [BOT_TOKEN, STRING, Slack bot token (xoxb-...)] - [CHANNEL, STRING, Slack channel ID or name] - [THREAD_TS, STRING, Parent message timestamp for threading] - [PAYLOAD, OBJECT, Message payload according to Slack chat.postMessage API spec] @@ -70,11 +65,7 @@ options: | COMMENT = $$Send a threaded reply to Slack via Web API. User provides complete payload according to Slack API spec.$$ sql: | - SELECT CASE - WHEN BOT_TOKEN IS NULL OR BOT_TOKEN = '' THEN - OBJECT_CONSTRUCT('ok', false, 'error', 'bot_token is required') - WHEN NOT STARTSWITH(BOT_TOKEN, 'xoxb-') THEN - OBJECT_CONSTRUCT('ok', false, 'error', 'Invalid bot token format') + SELECT CASE WHEN CHANNEL IS NULL OR CHANNEL = '' THEN OBJECT_CONSTRUCT('ok', false, 'error', 'channel is required') WHEN THREAD_TS IS NULL OR THREAD_TS = '' THEN @@ -86,13 +77,14 @@ 'POST', 'https://slack.com/api/chat.postMessage', OBJECT_CONSTRUCT( - 'Authorization', 'Bearer ' || BOT_TOKEN, + 'Authorization', 'Bearer {BOT_TOKEN}', 'Content-Type', 'application/json' ), OBJECT_INSERT( OBJECT_INSERT(PAYLOAD, 'channel', CHANNEL), 'thread_ts', THREAD_TS - ) + ), + IFF(_utils.udf_whoami() <> CURRENT_USER(), '_FSC_SYS/SLACK', 'Vault/prod/livequery/slack') ) END as response @@ -104,11 +96,11 @@ options: | COMMENT = $$Validate if a string is a proper Slack webhook URL format.$$ sql: | - SELECT WEBHOOK_URL IS NOT NULL + SELECT WEBHOOK_URL IS NOT NULL AND STARTSWITH(WEBHOOK_URL, 'https://hooks.slack.com/services/') AND LENGTH(WEBHOOK_URL) > 50 -- name: {{ schema_name }}.validate_bot_token +- name: {{ schema_name }}.validate_bot_token signature: - [BOT_TOKEN, STRING, Bot token to validate] return_type: @@ -116,19 +108,19 @@ options: | COMMENT = $$Validate if a string is a proper Slack bot token format.$$ sql: | - SELECT BOT_TOKEN IS NOT NULL + SELECT BOT_TOKEN IS NOT NULL AND STARTSWITH(BOT_TOKEN, 'xoxb-') AND LENGTH(BOT_TOKEN) > 20 - name: {{ schema_name }}.validate_channel signature: - - [CHANNEL, STRING, Channel ID or name to validate] + - [CHANNEL, STRING, Channel ID or name to validate] return_type: - "BOOLEAN" options: | COMMENT = $$Validate if a string is a proper Slack channel ID or name format.$$ sql: | - SELECT CHANNEL IS NOT NULL + SELECT CHANNEL IS NOT NULL AND LENGTH(CHANNEL) > 0 AND ( STARTSWITH(CHANNEL, 'C') OR -- Channel ID @@ -137,4 +129,4 @@ STARTSWITH(CHANNEL, '#') -- Channel name ) -{% endmacro %} \ No newline at end of file +{% endmacro %}