In most companies, hitting a major goal is cause for celebration. It usually involves someone noticing the metric in a dashboard, sending a manual email or Slack message, and updating a spreadsheet. But what if your strategic goals weren't just static targets? What if reaching a goal could become an event—an automated trigger that kicks off the next phase of work?
With Goals.do, this isn't just a hypothetical. By treating your OKRs as code, you can connect goal achievement directly to your operational workflows. Forget manual updates and context switching. It's time to build a system where success automatically breeds more action.
This post will walk you through exactly how to do that. We'll show you how to use webhooks from Goals.do to trigger a serverless function that sends a celebratory Slack alert the moment a Key Result is met.
Traditional OKR software gives you a place to write down your goals. Goals.do turns your goals into an active part of your software ecosystem. When you manage OKRs programmatically, every update becomes a machine-readable event.
Instead of living in an isolated UI, these events can be broadcast across your entire tech stack. This is where the powerful combination of webhooks and serverless functions comes in.
Webhooks are the connective tissue of the modern web. They are automated messages sent from one application to another when something happens. In Goals.do, you can configure webhooks to fire whenever your goal data changes. The webhook sends a secure HTTP POST request with a JSON payload containing all the relevant details to a URL of your choice.
Here’s a sample payload you might receive when a Key Result is updated:
{
"eventId": "evt_1_1L2g3h4i5j6k7l8m",
"eventType": "keyResult.updated",
"timestamp": "2024-10-15T10:00:00Z",
"data": {
"objective": {
"id": "obj_abc123",
"title": "Launch V2 of Flagship Product"
},
"keyResult": {
"id": "kr_xyz789",
"description": "Achieve 10,000 active users",
"target": 10000,
"previous": 9985,
"current": 10001
}
}
}
Serverless Functions (like AWS Lambda, Vercel/Next.js API Routes, or Google Cloud Functions) are the perfect recipients for these webhooks. They are small, independent functions that run in response to an event. You don't need to manage a dedicated server—you just write the code that executes when the webhook is received. They are efficient, scalable, and incredibly cost-effective.
Let's build a a real-world automation. We'll post a message to a #wins channel in Slack the moment our Key Result for user acquisition is achieved.
First, we need the goal itself. Using the Goals.do SDK, we define our Q4 Objective to launch our V2 product. The code is clean, version-controllable, and lives right alongside our application code.
import { Goals } from 'goals.do';
// This objective is now an active, trackable entity in our system
const productLaunchObjective = await Goals.create({
title: 'Launch V2 of Flagship Product',
owner: 'product-team@example.com',
timeframe: 'Q4 2024',
keyResults: [
{
id: 'kr_xyz789', // A unique ID for easy reference
description: 'Achieve 10,000 active users',
target: 10000,
current: 0 // This will be updated automatically from our database
},
// ... other key results
]
});
Somewhere else in our application, we have a job that periodically updates this Key Result:
// For example, a nightly cron job
const userCount = await database.query('SELECT COUNT(id) FROM users WHERE active=true');
await Goals.keyResults.update('kr_xyz789', { current: userCount });
Now, let's create a serverless function to receive the webhook from Goals.do. We'll use TypeScript and deploy it on a platform like Vercel.
First, get a Slack Incoming Webhook URL from your Slack workspace settings. Store it securely as an environment variable (SLACK_WEBHOOK_URL).
Next, create the function (e.g., pages/api/goals-webhook.ts):
import { NextApiRequest, NextApiResponse } from 'next';
// This is a simplified example. In production, you'd want to
// add a layer to verify the webhook signature from Goals.do.
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'POST') {
return res.status(405).json({ message: 'Method Not Allowed' });
}
const event = req.body;
// We only care about Key Result updates for now
if (event.eventType === 'keyResult.updated') {
const { keyResult, objective } = event.data;
const isCompleted = keyResult.current >= keyResult.target && keyResult.previous < keyResult.target;
// Check if the KR just crossed the finish line
if (isCompleted) {
const message = `🎉 **Goal Achieved!** 🎉\n\n*Objective:* ${objective.title}\n*Key Result:* ${keyResult.description}\n*Achievement:* Reached ${keyResult.current} / ${keyResult.target}!`;
// Send the notification to Slack
await fetch(process.env.SLACK_WEBHOOK_URL!, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: message }),
});
console.log(`Sent completion notification for KR: ${keyResult.id}`);
}
}
res.status(200).json({ status: 'received' });
}
This function listens for POST requests, checks if a Key Result was just completed, and if so, sends a formatted message to Slack.
Once your serverless function is deployed, it will have a public URL (e.g., https://your-app.com/api/goals-webhook).
The final step is to tell Goals.do to send events to this URL. You can do this easily via our API or in your account settings:
// Register the webhook endpoint with Goals.do
await Goals.webhooks.create({
url: 'https://your-app.com/api/goals-webhook',
events: ['keyResult.updated'] // Subscribe to specific events
});
That's it! Now, the moment your automated job updates the user count and the "active users" key result surpasses 10,000, Goals.do will fire a webhook. Your serverless function will catch it, and your team will get an instant notification in Slack celebrating the win.
A Slack notification is just the beginning. By embracing Business-as-Code, you can orchestrate complex workflows triggered by your strategic progress:
By connecting your goals to your tools, you create a self-regulating, reactive system where strategy directly drives execution. You close the loop between planning and doing.
Ready to turn your goals into actions? Explore the Goals.do API documentation and start your journey toward true goal-driven automation.