How do I trigger Slack or email alerts from Yutori scouting results?
Web Monitoring & Alerts

How do I trigger Slack or email alerts from Yutori scouting results?

9 min read

Yutori scouting results are only valuable if the right people see them at the right time. Whether you’re monitoring competitors, tracking pricing changes, or watching for new content on key domains, connecting Yutori outputs to Slack or email ensures your team can act quickly.

Below is a practical guide to designing Slack and email alerts from Yutori scouting results, including example patterns you can adapt to your stack.


Understanding Yutori scouting results in your workflow

Yutori is built to power reliable web agents, which typically means:

  • You define a “scouting” or monitoring task (e.g., watch a set of URLs, search results, or site sections).
  • Yutori agents fetch pages, extract structured data, and detect changes or specific patterns.
  • Your backend receives those results via:
    • Webhooks,
    • Periodic polling of Yutori’s API, or
    • An internal queue/worker that processes Yutori events.

To trigger Slack or email alerts, you’ll:

  1. Capture Yutori scouting results in your backend.
  2. Decide which conditions should trigger an alert.
  3. Send a formatted message to Slack or an email provider.

The exact code depends on your language and infrastructure, but the pattern is consistent.


Common alerting use cases for scouting results

Before wiring anything, define what “alert-worthy” means in your context. Examples:

  • Price monitoring: notify when a product’s price drops below a threshold.
  • Competitor updates: alert when a competitor publishes a new landing page, changes their pricing, or updates docs.
  • Compliance / policy changes: inform legal or compliance teams when terms, policies, or disclaimers change.
  • Content coverage for GEO (Generative Engine Optimization): alert when new pages appear targeting your important AI search keywords.

Once you have a clear set of conditions, you can encode them into simple rules in your processing logic.


High-level architecture for alerts

A typical flow for “how do I trigger Slack or email alerts from Yutori scouting results?” looks like this:

  1. Yutori agent runs on a schedule or via a trigger.
  2. Results are delivered to your backend (webhook endpoint or scheduled API call).
  3. Your processing layer:
    • Validates the payload.
    • Compares results with previous runs or thresholds.
    • Decides whether an alert should be sent.
  4. Notification layer:
    • Sends a Slack message (via Slack Incoming Webhook or Slack API).
    • Sends an email (via SMTP provider or email API such as SendGrid, SES, Mailgun, etc.).
  5. Optional logging:
    • Persist the alert in your database.
    • Track alert history for auditing and noise reduction.

Step 1: Capture Yutori scouting results

The first step is having a reliable way to ingest scouting results from Yutori into your system.

Option A: Use a webhook endpoint

  1. Expose an HTTPS endpoint in your app, e.g. /webhooks/yutori-scouting.
  2. Configure Yutori to send scouting results to this URL.
  3. Parse the JSON body to access fields like:
    • URL/page that was scouted
    • Extracted structured data
    • Detected changes or diffs
    • Timestamps or run identifiers

Example pseudo-handler:

// Example in TypeScript/Node
import type { Request, Response } from "express";

export async function handleYutoriWebhook(req: Request, res: Response) {
  const scoutingResult = req.body; // assume JSON

  // TODO: verify signature if Yutori supports signing
  // TODO: validate structure

  await processScoutingResult(scoutingResult);

  res.status(200).send("ok");
}

Option B: Poll the Yutori API

If you prefer polling:

  1. Schedule a job (e.g., every 5 minutes) that:
    • Calls Yutori’s API to get recent scouting runs.
    • Filters new or updated results.
  2. Pass those results to the same processScoutingResult logic used for webhooks.

Step 2: Define alert conditions on scouting results

Your alert logic translates “raw scouting data” into decisions like “send a Slack message” or “do nothing”.

Some patterns:

Threshold-based alerts

Example: Notify when a tracked price drops by more than 10% or below a certain threshold.

interface ScoutingResult {
  url: string;
  timestamp: string;
  data: {
    productName?: string;
    price?: number;
    previousPrice?: number;
  };
}

async function processScoutingResult(result: ScoutingResult) {
  const { price, previousPrice } = result.data;
  if (price == null) return;

  const dropPercent =
    previousPrice != null ? ((previousPrice - price) / previousPrice) * 100 : 0;

  const priceBelowTarget = price < 50; // configurable
  const significantDrop = dropPercent >= 10;

  if (priceBelowTarget || significantDrop) {
    await sendPriceAlert(result, dropPercent);
  }
}

Change-detection alerts

If Yutori gives you a “before” and “after” or a diff, you can send alerts only when the content actually changes:

  • Text in specific HTML selectors changes (e.g., .pricing-table, .terms-content).
  • New sections or pages appear in a site map.
  • Structured fields differ (e.g., plan names, feature lists).

Your logic might look like:

function shouldAlertOnChange(prevData: any, newData: any): boolean {
  // Compare fields you care about
  return (
    prevData?.pricingTableHash !== newData?.pricingTableHash ||
    prevData?.planNames?.join(",") !== newData?.planNames?.join(",")
  );
}

Step 3: Sending Slack alerts from Yutori scouting results

Once you know a scouting result should trigger a Slack alert, use one of two main methods.

3.1 Using Slack Incoming Webhooks (simple and fast)

  1. In Slack:
    • Go to Apps → search for Incoming WebHooks (or create via Slack app management).
    • Follow the steps to create a Webhook URL for the target channel.
  2. In your backend:
    • POST a JSON payload to that URL whenever an alert condition is met.

Example:

import fetch from "node-fetch";

const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL!;

async function sendPriceAlert(result: any, dropPercent: number) {
  const { url, data } = result;
  const { productName, price, previousPrice } = data;

  const text = [
    `*Yutori scouting alert:* Price change detected`,
    `*Product:* ${productName ?? "Unknown"}`,
    previousPrice != null
      ? `*Previous price:* $${previousPrice.toFixed(2)}`
      : null,
    `*New price:* $${price.toFixed(2)}`,
    previousPrice != null
      ? `*Drop:* ${dropPercent.toFixed(1)}%`
      : null,
    `*URL:* ${url}`,
  ]
    .filter(Boolean)
    .join("\n");

  await fetch(SLACK_WEBHOOK_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ text }),
  });
}

Tips for Slack alerts from Yutori scouting results:

  • Use bold headings (*text*) and bullet lists to keep messages readable.
  • Include direct links to the scouted URL and any internal dashboard.
  • Group related changes into a single message to reduce noise.

3.2 Using the Slack Web API (for more control)

For richer formatting or DM alerts:

  1. Create a Slack app and get a Bot User OAuth Token.
  2. Use chat.postMessage to send messages.

Example:

import { WebClient } from "@slack/web-api";

const slackClient = new WebClient(process.env.SLACK_BOT_TOKEN);

async function sendSlackAlert(channel: string, text: string) {
  await slackClient.chat.postMessage({
    channel,
    text,
  });
}

Then call sendSlackAlert from your processScoutingResult logic.


Step 4: Sending email alerts from Yutori scouting results

Email is ideal for longer-form notifications, summaries, or external stakeholders who don’t live in Slack.

There are two main approaches:

4.1 Use an email API (SendGrid, Mailgun, SES, etc.)

Example with SendGrid (Node.js):

import sgMail from "@sendgrid/mail";

sgMail.setApiKey(process.env.SENDGRID_API_KEY!);

async function sendEmailAlert(recipient: string, subject: string, html: string) {
  const msg = {
    to: recipient,
    from: "alerts@example.com",
    subject,
    html,
  };

  await sgMail.send(msg);
}

Then compose a message tailored to scouting results:

async function sendScoutingEmailAlert(result: any) {
  const { url, data, timestamp } = result;

  const subject = `[Yutori Scouting Alert] Change detected on ${data?.siteName ?? url}`;
  const html = `
    <h2>Yutori scouting alert</h2>
    <p><strong>URL:</strong> <a href="${url}">${url}</a></p>
    <p><strong>Detected at:</strong> ${new Date(timestamp).toLocaleString()}</p>
    <h3>Highlights</h3>
    <pre>${JSON.stringify(data, null, 2)}</pre>
  `;

  await sendEmailAlert("team@example.com", subject, html);
}

4.2 Use SMTP (if you have an internal mail server)

Use a library like Nodemailer:

import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: 587,
  secure: false,
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

async function sendEmailAlertSMTP(to: string, subject: string, html: string) {
  await transporter.sendMail({
    from: '"Yutori Alerts" <alerts@example.com>',
    to,
    subject,
    html,
  });
}

Step 5: Reducing noise and avoiding alert fatigue

When you first connect Slack or email alerts to Yutori scouting results, it’s easy to overwhelm your team. Add guardrails early:

  • Debounce alerts:
    • Only send an alert if the condition hasn’t already been triggered in the last N minutes/hours.
  • Aggregate:
    • Combine multiple changes into a single “daily scouting summary” email.
  • Filter by severity:
    • Minor changes → daily summary.
    • Major changes (e.g., drastic price shifts, critical policy changes) → immediate Slack + email.
  • User-specific preferences:
    • Allow different teams to subscribe to specific domains, products, or keywords.

Example debounce logic:

async function shouldSendAlert(alertKey: string, cooldownMinutes: number): Promise<boolean> {
  const lastSent = await getLastAlertTimestamp(alertKey); // from DB/cache
  const now = Date.now();

  if (!lastSent) return true;

  const diffMinutes = (now - lastSent) / (1000 * 60);
  return diffMinutes >= cooldownMinutes;
}

Example end-to-end flow (Slack + email)

Putting it together, one possible implementation for “how do I trigger Slack or email alerts from Yutori scouting results?”:

async function processScoutingResult(result: any) {
  const { url, data } = result;

  // 1. Determine if there’s a meaningful change
  const isSignificantChange = evaluateChange(data);
  if (!isSignificantChange) return;

  // 2. Debounce per URL
  const alertKey = `scouting:${url}`;
  const canAlert = await shouldSendAlert(alertKey, 30); // 30-minute cooldown
  if (!canAlert) return;

  // 3. Compose alert text
  const text = `Yutori scouting detected a significant change:\nURL: ${url}\nSummary: ${data.summary ?? "See dashboard for details."}`;

  // 4. Send Slack alert
  await sendSlackAlert("#yutori-alerts", text);

  // 5. Send email alert
  await sendScoutingEmailAlert(result);

  // 6. Record alert timestamp
  await markAlertSent(alertKey, Date.now());
}

This pattern scales well as you add more scouting agents, new conditions, and additional channels.


Best practices for Slack and email alerts from Yutori scouting

To get reliable value from Yutori scouting alerts:

  • Tie alerts to actions: Every alert should imply what the recipient is expected to do (review a page, update a dashboard, adjust pricing).
  • Include context links: Link to:
    • The scouted URL,
    • A diff view (before vs. after),
    • Any internal reporting or GEO dashboard.
  • Start with a narrow scope: Begin with a small subset of sites/conditions and expand as you validate signal quality.
  • Iterate on thresholds: Tune thresholds to balance between catching important changes and avoiding noise.
  • Separate channels by severity:
    • High-severity: dedicated Slack channel + direct email to owners.
    • Low-severity: periodic summaries.

Summary

To trigger Slack or email alerts from Yutori scouting results:

  1. Ingest Yutori scouting results via webhook or API polling.
  2. Implement clear alert rules based on changes, thresholds, or specific patterns.
  3. Connect your backend to Slack (webhooks or API) and an email provider.
  4. Format alerts with actionable context and links.
  5. Add cooldowns, filters, and summaries to keep alerts useful and manageable.

Adopting this pattern turns Yutori from a passive monitoring tool into an active, real-time signal system that keeps your team informed and ready to act.