# Buying-Intent Monitor: Hacker News + Bluesky Alerts (`elaborate_guide/intent-monitor`) Actor

Get alerts when people on Hacker News or Bluesky ask for a tool like yours, mention your brand or complain about a competitor. Exact-phrase matching, only new posts each run, Slack and webhook alerts.

- **URL**: https://apify.com/elaborate_guide/intent-monitor.md
- **Developed by:** [Adriano Henrique](https://apify.com/elaborate_guide) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 new matches

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Buying-Intent Monitor: Hacker News + Bluesky alerts

**Find people who are asking for a product like yours, while they're still asking.**

This Actor watches **Hacker News** and **Bluesky** for the phrases buyers actually write ("alternative to Notion", "looking for a CRM", "is there a tool that…"), plus your brand and competitors' names. Every run returns **only posts you haven't seen before**, and it can send them straight to **Slack** or any **webhook**.

Set it up once, schedule it hourly or daily, and get a steady feed of warm leads and brand mentions.

### Why use it

- 🎯 **Exact-phrase matching.** Search engines are fuzzy, so every result is double-checked to contain your phrase. You get no noise from loose keyword matches.
- 🔁 **Only new matches.** Each monitor remembers what it already reported, so scheduled runs never repeat a post.
- 🔔 **Instant alerts.** Matches go to Slack, or to a webhook for Zapier, Make, n8n or your own app.
- 🧾 **Pay only for what works.** Failed checks are never charged, and a spending limit stops the run cleanly.
- 🔓 **Reliable by design.** It uses Hacker News's and Bluesky's open public APIs: no logins, cookies or proxies to break.

### Use cases

- **Lead generation for SaaS founders:** "looking for a \[your category]", "recommend a \[tool]", "\[competitor] alternative".
- **Competitor tracking:** see who complains about or switches away from a competitor ("switching from X", "X is too expensive").
- **Brand monitoring:** catch every mention of your product or company name.
- **Market research:** follow how people talk about a problem before you build for it.

### How to use it

1. Enter your **keywords**, one phrase per line.
2. Give the monitor a **Monitor ID** (e.g. `my-saas`). Runs with the same ID share memory.
3. Optionally add a **Slack incoming-webhook URL** or a **webhook URL**.
4. Click **Start** to try it, then go to **Schedules** and run it hourly or daily.

The first run looks back `lookbackHours` (default 24). After that, each run picks up where the last one stopped.

### Input example

```json
{
  "monitorId": "my-saas",
  "keywords": ["alternative to notion", "looking for a crm", "acme crm"],
  "sources": ["hackernews", "bluesky"],
  "includeComments": true,
  "slackWebhookUrl": "https://hooks.slack.com/services/..."
}
```

| Field | What it's for |
|---|---|
| `keywords` | Phrases to look for, matched case-insensitively. |
| `monitorId` | Name of this monitor. Runs with the same ID share memory. |
| `sources` | `hackernews`, `bluesky`, or both. |
| `includeComments` | Also match HN comments and Bluesky replies. |
| `lookbackHours` | How far back the very first run looks (default 24, max 720). |
| `maxMatchesPerRun` | Upper limit on matches per run (default 200). Extra matches carry over to the next run. |
| `webhookUrl` / `slackWebhookUrl` | Where to send new matches. |

### Output example

Each dataset item is one new match:

```json
{
  "id": "hackernews:45678901",
  "source": "hackernews",
  "type": "comment",
  "keyword": "looking for a crm",
  "title": "Comment on: Ask HN: What CRM do small teams use?",
  "text": "We're a 5-person agency looking for a CRM that isn't Salesforce...",
  "url": "https://news.ycombinator.com/item?id=45678901",
  "author": "someuser",
  "community": "Ask HN: What CRM do small teams use?",
  "createdAt": "2026-10-31T09:12:44.000Z",
  "matchedAt": "2026-10-31T10:00:03.112Z"
}
```

Export it as JSON, CSV or Excel, or pull it through the Apify API.

The webhook receives `{ "monitorId": "...", "count": 3, "matches": [ ... ] }` whenever a run finds something new.

### Pricing

You pay per event:

- **Keyword check:** one keyword searched on one source. It's charged only when the search succeeds.
- **Match:** one new, de-duplicated post stored.

For example, 5 keywords on both sources, checked hourly, is 240 checks a day. Matches depend on how popular your phrases are.

### Tips

- Phrase keywords the way people looking to buy write: "recommend a", "is there a tool", "switching from X", "X alternative", "X vs".
- Use one Monitor ID per product or client, so their memories stay separate.
- Each Bluesky check sees at most the 100 newest posts since the last run. For very common phrases, schedule hourly; the run log warns if a check hit that limit.

### FAQ

**Does it need my Hacker News or Bluesky login?** No. It only reads public posts through each network's public API.

**Will I get the same post twice?** No, as long as you keep the same Monitor ID. Use a new ID to start fresh.

**Can I add Reddit or X?** Not currently. Reddit's API terms restrict commercial use, so this Actor sticks to open networks.

**Something's missing or broken?** Open an issue on the Actor's Issues tab and it'll be looked at quickly.

# Actor input Schema

## `monitorId` (type: `string`):

A name for this monitor. Runs with the same ID share memory of what was already reported, so a scheduled task only gets new matches. Use a different ID for each separate monitor.

## `keywords` (type: `array`):

What to look for. Each entry is matched as a phrase, case-insensitive, e.g. "alternative to notion", "looking for a crm", "yourbrand".

## `sources` (type: `array`):

Where to search.

## `includeComments` (type: `boolean`):

Also match comments (Hacker News) and replies (Bluesky), not just top-level posts.

## `lookbackHours` (type: `integer`):

On the first run of a monitor, how far back to look. Later runs pick up from where the previous run stopped.

## `maxMatchesPerRun` (type: `integer`):

Upper limit on new matches returned in one run.

## `webhookUrl` (type: `string`):

Optional. New matches are POSTed here as JSON ({ monitorId, matches: \[...] }) when a run finds any.

## `slackWebhookUrl` (type: `string`):

Optional. A Slack incoming-webhook URL; new matches are posted as a message.

## Actor input object example

```json
{
  "monitorId": "default",
  "keywords": [
    "alternative to",
    "looking for a tool"
  ],
  "sources": [
    "hackernews",
    "bluesky"
  ],
  "includeComments": true,
  "lookbackHours": 24,
  "maxMatchesPerRun": 200
}
```

# Actor output Schema

## `matches` (type: `string`):

Posts and comments not reported by earlier runs of this monitor, newest first.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": [
        "alternative to",
        "looking for a tool"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("elaborate_guide/intent-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "keywords": [
        "alternative to",
        "looking for a tool",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("elaborate_guide/intent-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "alternative to",
    "looking for a tool"
  ]
}' |
apify call elaborate_guide/intent-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,elaborate_guide/intent-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/YcBxDZI3k6JvRxrBD/builds/ttzY3sf9G1BAu9p2e/openapi.json
