# Bluesky Keyword Monitor (`tidyrows/my-actor`) Actor

Monitors Bluesky for your chosen keywords and returns only posts you haven't seen before — perfect for ongoing brand and topic alerts without digging through duplicate results every run.

- **URL**: https://apify.com/tidyrows/my-actor.md
- **Developed by:** [ajshe asllani](https://apify.com/tidyrows) (community)
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bluesky Keyword Monitor

Tracks keywords on [Bluesky](https://bsky.app) and alerts you only to
**new** posts you haven't seen before — built for ongoing brand and topic
monitoring, not one-off scraping.

### What it does

Give it a list of keywords (a brand name, product, competitor, or topic).
Every time it runs, it:

1. Searches Bluesky for each keyword.
2. Filters out posts older than your chosen lookback window and, optionally,
   posts with too few likes.
3. Checks each matching post against a running memory of posts it has
   already shown you.
4. Returns **only the posts you haven't seen yet**.

Run it on a schedule (see below) and point it — or the dataset it produces
— at your alerting/notification tool of choice, and you get a running feed
of new mentions instead of a pile of duplicates to sift through by hand.

### Why "only new posts" matters

A normal keyword scraper returns everything matching your search on every
run — so if you run it every hour, you see the same popular posts over and
over, and it gets harder to spot what's actually new. This Actor keeps a
memory of what it has already shown you, so each run's output is a clean
list of genuinely new mentions. That's what makes it usable as a
monitoring/alerting tool rather than a one-time export.

### Input options

| Field | What it does | Default |
|---|---|---|
| **Search terms** | Keywords/phrases to watch, searched separately | `["Apify"]` |
| **Max posts per term** | How many recent matches to check, per term, per run | `50` |
| **Lookback window (hours)** | Ignore posts older than this | `24` |
| **Minimum likes** | Skip low-engagement posts | `0` |

### Example output

Each new post becomes one row in the Actor's dataset:

| postUrl | authorHandle | text | createdAt | likeCount | matchedTerm |
|---|---|---|---|---|---|
| bsky.app/profile/jane.bsky.social/post/abc123 | jane.bsky.social | "Just tried Apify for a scraping project, works great" | 2026-09-13T14:02:00Z | 12 | Apify |
| bsky.app/profile/devtools.bsky.social/post/xyz789 | devtools.bsky.social | "Anyone compared Apify vs writing your own scrapers?" | 2026-09-13T15:41:00Z | 4 | Apify |

(Full rows also include `authorDisplayName`, `repostCount`, and
`replyCount`.)

### Suggested schedule

- **Brand/reputation monitoring** (time-sensitive): every 30–60 minutes,
  with a lookback window of 1–2 hours.
- **General topic tracking** (less urgent): every 4–6 hours, with a
  lookback window of 24 hours.

Keep the lookback window comfortably longer than your run interval — that
way, if a single run runs late or fails, you won't miss posts that fell in
the gap.

### Bluesky login (one-time setup)

Bluesky blocks anonymous searches from cloud servers, so this Actor needs
to log in with a real account to read public posts. It only ever reads —
it never posts, follows, or likes anything.

1. Sign in to [bsky.app](https://bsky.app) (create a free account if you
   don't have one).
2. Go to **Settings → Privacy and Security → App Passwords**.
3. Click **Add App Password**, name it something like "keyword-monitor",
   and copy the generated password (looks like `xxxx-xxxx-xxxx-xxxx`).
4. Paste your handle (e.g. `yourname.bsky.social`) into the **Bluesky
   handle** field, and the app password into **Bluesky app password**.

Never use your real account password — only an app password, which can be
revoked at any time from the same settings page without affecting your
normal login.

### Notes

- The Actor remembers post IDs across runs so it never shows you the same
  post twice; that memory is capped at the 5,000 most recently seen posts.

# Actor input Schema

## `blueskyHandle` (type: `string`):

Your Bluesky handle, e.g. yourname.bsky.social. Bluesky requires a logged-in account for automated search (anonymous requests from cloud servers get blocked) -- this account is only used to read public posts, nothing is ever posted from it.

## `blueskyAppPassword` (type: `string`):

An App Password from your Bluesky account (Settings → Privacy and Security → App Passwords). Do NOT use your real account password -- an app password can be revoked at any time without affecting your login.

## `searchTerms` (type: `array`):

Keywords or phrases to watch for on Bluesky. Each one is searched separately. Works out of the box with the example term below.

## `maxPostsPerTerm` (type: `integer`):

How many of the most recent matching posts to look at for each search term, per run. Higher values catch more but take longer and use more compute.

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

Ignore posts older than this many hours. Keep this a bit longer than your run schedule (e.g. 24h lookback for a run that fires every few hours) so a slow run never leaves a gap.

## `minLikes` (type: `integer`):

Skip posts with fewer likes than this. Leave at 0 to keep everything. Useful for filtering out low-signal noise on very common keywords.

## Actor input object example

```json
{
  "searchTerms": [
    "Apify"
  ],
  "maxPostsPerTerm": 50,
  "lookbackHours": 24,
  "minLikes": 0
}
```

# Actor output Schema

## `newPosts` (type: `string`):

Each item is one new post matching a search term: the post URL, author, text, engagement counts, creation time, and which search term matched it.

# 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 = {
    "searchTerms": [
        "Apify"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tidyrows/my-actor").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 = { "searchTerms": ["Apify"] }

# Run the Actor and wait for it to finish
run = client.actor("tidyrows/my-actor").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 '{
  "searchTerms": [
    "Apify"
  ]
}' |
apify call tidyrows/my-actor --silent --output-dataset

```

## MCP server setup

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

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/b7ux2x9IoZGMn803j/builds/hJpYFJRtaMUYSWQvh/openapi.json
