slack-webhook
Slack Webhook Integration
Send alerts and notifications to Slack using the configured webhook.
Quick Start
The webhook URL is automatically loaded from the SLACK_WEBHOOK_URL environment variable.
import os
import json
from urllib.request import Request, urlopen
def send_slack_alert(message: dict) -> bool:
"""Send a message to Slack via webhook.
Args:
message: Slack Block Kit message payload
Returns:
True if sent successfully, False otherwise
"""
webhook_url = os.environ.get('SLACK_WEBHOOK_URL')
if not webhook_url:
raise ValueError("SLACK_WEBHOOK_URL environment variable not set")
request = Request(
webhook_url,
data=json.dumps(message).encode('utf-8'),
headers={'Content-Type': 'application/json'}
)
with urlopen(request, timeout=10) as response:
return response.status == 200
Message Formats
Simple Text Message
message = {
"text": "Hello from the agent!"
}
send_slack_alert(message)
Alert with Block Kit (Recommended)
message = {
"blocks": [
{
"type": "header",
"text": {"type": "plain_text", "text": "π΄ Anomaly Detected"}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Metric:*\nConversion Rate"},
{"type": "mrkdwn", "text": "*Severity:*\nCritical"}
]
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Expected:*\n4.2%"},
{"type": "mrkdwn", "text": "*Actual:*\n1.8%"}
]
},
{"type": "divider"},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Potential Causes:*\nβ’ Checkout flow issue\nβ’ Payment gateway error\nβ’ Landing page test impact"
}
},
{
"type": "context",
"elements": [
{"type": "mrkdwn", "text": "π€ Alert generated by AI Agent"}
]
}
]
}
Anomaly Alert Template
def build_anomaly_alert(
metric_name: str,
date: str,
expected: float,
actual: float,
severity: str = "Warning",
potential_causes: list = None
) -> dict:
"""Build a formatted anomaly alert message.
Args:
metric_name: Name of the metric (e.g., "Conversion Rate")
date: Date of the anomaly
expected: Expected value
actual: Actual value
severity: "Critical" or "Warning"
potential_causes: List of potential cause strings
Returns:
Slack Block Kit message payload
"""
emoji = "π΄" if severity == "Critical" else "π‘"
pct_change = ((actual - expected) / expected) * 100
direction = "drop" if pct_change < 0 else "spike"
blocks = [
{
"type": "header",
"text": {"type": "plain_text", "text": f"{emoji} Anomaly Detected: {metric_name}"}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": f"*Date:*\n{date}"},
{"type": "mrkdwn", "text": f"*Severity:*\n{severity}"}
]
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": f"*Expected:*\n{expected:,.2f}"},
{"type": "mrkdwn", "text": f"*Actual:*\n{actual:,.2f}"}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"*Change:* {pct_change:+.1f}% {direction}"
}
}
]
if potential_causes:
causes_text = "\n".join([f"β’ {cause}" for cause in potential_causes])
blocks.extend([
{"type": "divider"},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"*Potential Causes:*\n{causes_text}"
}
}
])
blocks.append({
"type": "context",
"elements": [
{"type": "mrkdwn", "text": "π€ Alert generated by AI Agent"}
]
})
return {"blocks": blocks}
Usage Example
# Build and send an anomaly alert
alert = build_anomaly_alert(
metric_name="Trial Conversion Rate",
date="2025-11-28",
expected=37.6,
actual=10.5,
severity="Critical",
potential_causes=[
"Onboarding flow broken",
"Integration setup failing",
"New user segment with different behavior"
]
)
success = send_slack_alert(alert)
if success:
print("β
Alert sent to Slack")
else:
print("β Failed to send alert")
Testing
To test without sending (dry run):
import json
print(json.dumps(alert, indent=2))
Error Handling
from urllib.error import URLError, HTTPError
try:
send_slack_alert(message)
except ValueError as e:
print(f"Configuration error: {e}")
except HTTPError as e:
print(f"Slack API error: {e.code} - {e.reason}")
except URLError as e:
print(f"Network error: {e.reason}")
More from funnelenvy/agents_webinar_demos
bq-query-optimization
Use when writing BigQuery queries, optimizing query performance, analyzing execution plans, or avoiding common SQL gotchas. Covers parameterized queries, UDFs, scripting, window functions (QUALIFY, ROW_NUMBER, RANK, LEAD/LAG), JSON functions, ARRAY/STRUCT operations, BigQuery-specific features (EXCEPT, REPLACE, SAFE_*), CTE re-execution issues, NOT IN with NULLs, DML performance, Standard vs Legacy SQL, and performance best practices.
29gemini-qa
Use Google Gemini CLI to answer questions about code, analyze files, or perform codebase exploration. Invoke this skill when the user asks to use Gemini, wants a second opinion from another AI, or wants to compare Claude's answer with Gemini's response.
25n8n-workflow
Use when creating, deploying, or managing N8N workflows. Automatically uses N8N_HOST and N8N_API_KEY from environment.
22playwright-browser
Use when capturing screenshots, automating browser interactions, or scraping web content. Covers Playwright Python API for page navigation, screenshots, element selection, form filling, and waiting strategies.
21hubspot-crm
Use when syncing contacts or lists to HubSpot CRM. Automatically uses HUBSPOT_API_TOKEN from environment.
20gcp-cli-gotchas
Use when encountering gcloud or bq CLI formatting errors, quote escaping issues, command substitution problems, or when debugging CLI commands. Provides solutions for backtick usage, heredoc syntax, timestamp filters, parameter escaping, and multiline command formatting.
12