Skip to content
Notifications
Clear all

Built a Slack bot that posts our daily security score trend

2 Posts
2 Users
0 Reactions
0 Views
(@code_reviewer_anna_v2)
Reputable Member
Joined: 4 months ago
Posts: 194
Topic starter   [#23400]

Hey folks! 👋 I've been working on a little automation project that's been a hit with our security team, and I wanted to share the approach. We use Braintrust to track our security posture score, and I built a Slack bot that posts the daily trend line every morning. It gives everyone a quick, visible pulse on whether we're improving or if something needs attention.

The core idea is simple: use Braintrust's API to fetch the score history, calculate the recent trend, and format a clean message for Slack. Here's the key part of the Python script that runs as a scheduled job:

```python
import requests
import os
from datetime import datetime, timedelta
from slack_sdk import WebClient

BRAINTRUST_API_KEY = os.environ.get("BRAINTRUST_API_KEY")
SLACK_BOT_TOKEN = os.environ.get("SLACK_BOT_TOKEN")
PROJECT_ID = "your-project-id-here"

# Fetch last 7 days of scores
response = requests.get(
f"https://www.braintrust.dev/api/project/{PROJECT_ID}/scores",
headers={"Authorization": f"Bearer {BRAINTRUST_API_KEY}"},
params={"limit": 7}
)
scores_data = response.json()

# Simple linear trend calculation (simplified for example)
dates = [datetime.fromisoformat(s['date'][:-1]) for s in scores_data['scores']]
values = [s['value'] for s in scores_data['scores']]
if len(values) > 1:
trend = values[-1] - values[0] # change over the period
else:
trend = 0

# Build Slack message
emoji = "📈" if trend >= 0 else "📉"
client = WebClient(token=SLACK_BOT_TOKEN)
client.chat_postMessage(
channel="#security-metrics",
text=f"{emoji} *Security Score Trend* (7-day window): {trend:+.2f}nLatest score: {values[-1]:.1f}"
)
```

A couple of best practices I learned:
* **Always cache or limit API calls.** Braintrust's API is responsive, but be nice to it. I fetch only the last 7 data points.
* **Handle missing data gracefully.** Some days might not have a score entry, so my production code has logic to interpolate or skip gaps.
* **Make the Slack message actionable.** We added a direct link to the Braintrust project dashboard in the message using `blocks` for richer formatting.

The biggest "aha" was deciding on the trend window. A 7-day rolling window smoothed out weekend noise but still showed recent shifts. We also experimented with posting to different channels for devs vs. leadership, with slightly different commentary.

It's a small thing, but it's made our security metrics way more visible and sparked some great conversations. Has anyone else built similar integrations? I'm curious about how you're calculating trends or if you're pulling in other Braintrust data.

Happy coding!


Clean code, happy life


   
Quote
(@aiden22)
Estimable Member
Joined: 2 weeks ago
Posts: 110
 

Watch your runtime costs if you're polling that API daily with a scheduled job. Consider moving the logic to a serverless function that only runs when a new score is actually available, maybe via a webhook from Braintrust. You'll cut compute time by 99% and avoid paying for idle time.


Show me the bill


   
ReplyQuote