Skip to content
Back to skills

Social Monitor

ASecurity

Mention/keyword sweep on social platforms for [REPLACE: KEYWORDS] — trends, sentiment, top posts

  • 789 stars
  • 0 votes
  • 0 copies
  • 7 views
  • Added September 3, 2026
ai-agentsgoshellbashapi

Works with

  • api

Security analysis

A100/100

Scanned November 9, 2026

npx -y skills add aeonfun/aeon --skill social-monitor --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Social Monitor?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Social Monitor
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aeonfun-social-monitor/badge)](https://www.skillsdirectory.com/skills/aeonfun-social-monitor)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: [REPLACE: SKILL_NAME]
description: Mention/keyword sweep on social platforms for [REPLACE: KEYWORDS] — trends, sentiment, top posts
metadata:
  category: productivity
  var: ""
  tags:
    - social
  requires:
    - XAI_API_KEY?
---

> **${var}** — Optional. Pass alternative keywords (comma-separated) to override the default. If empty, monitors `[REPLACE: KEYWORDS]`.

Today is ${today}. Monitor social mentions of **[REPLACE: KEYWORDS]** and produce a summary.

## Steps

1. **Resolve keywords** - use `${var}` if set, else `[REPLACE: KEYWORDS]`. Split on commas, trim each, lower-case. Each token becomes its own search query, written into its own calls literally (the `<KEYWORD>` below; `<N>` is its position in the list).

2. **Search X** — for each keyword, use the X / xAI search path (project's standard pattern):

   Key check: read the "Keys set for this run" line in your run notes, never a shell test (those are refused and cost a turn). With `XAI_API_KEY` on that line, build the body with a literal `jq -n` filter and pipe it straight into `./secretcurl` (set the Bash tool `timeout` to at least 180000; the live X search takes 30-120s):

   ```bash
   jq -n '{model:"grok-4.7", input:[{role:"user",content:"Search X for posts from the last 24 hours about: <KEYWORD>. Language: [REPLACE: LANGUAGE]. For each post include @handle, the full text, date posted, exact like, repost and reply counts, and the direct link (https://x.com/handle/status/ID). Return as a numbered list."}], tools:[{type:"x_search"}]}' \
     | ./secretcurl -s -o /tmp/social-x-<N>.json -w 'xai http=%{http_code}\n' --max-time 150 -X POST "https://api.x.ai/v1/responses" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer {XAI_API_KEY}" \
     --data-binary @-
   ```

   On `http=200`, read the text with `jq -r '.output[] | select(.type == "message") | .content[] | select(.type == "output_text") | .text' /tmp/social-x-<N>.json`. Without the key, or on a non-2xx code, an empty reply or a timeout, fall back to WebFetch (or a Nitter mirror) and log the true reason.

   Restrict to language `[REPLACE: LANGUAGE]` (e.g. `en`, `fr`, `any`). Drop posts with fewer than `[REPLACE: MIN_LIKES]` likes — that filter is what protects the channel from low-signal noise.

3. **Search Reddit** — for each keyword:

   ```bash
   curl -s -o /tmp/social-reddit-<N>.json -w 'reddit http=%{http_code}\n' -H "User-Agent: aeon/1.0" -G "https://www.reddit.com/search.json" --data-urlencode "q=<KEYWORD>" -d t=day -d restrict_sr=0
   ```

   Reddit's JSON endpoint is keyless. On a non-2xx code (often 429), make a second call with WebFetch on `https://www.reddit.com/search.json?q=<KEYWORD>&t=day`.

4. **Score and pick top 5 per platform** — score on engagement (likes, comments, score) × recency (last 24h gets full marks). Drop reposts and obvious bot accounts (handles like `*_bot`, account age < 7 days with > 100 posts).

5. **Tag sentiment** — for the top 10 posts overall, label each `positive` / `neutral` / `negative` based on tone of the post text. Keep this lightweight — one-token classification, no nested reasoning.

6. **Write `output/articles/[REPLACE: SKILL_NAME]-${today}.md`**:
   ```markdown
   # [REPLACE: KEYWORDS] — ${today}

   ## Volume
   - X: N posts (vs 7d avg M)
   - Reddit: N posts (vs 7d avg M)

   ## Sentiment
   positive: X · neutral: Y · negative: Z

   ## Top posts
   1. [Author · platform · timestamp]
      "Excerpt or paraphrase."
      → URL

   2. ...
   ```

7. **Notify** via `./notify` with a 2-3 line summary: `*[REPLACE: KEYWORDS] — ${today}* · N posts · sentiment skews positive/negative · top: <one-line title>. Full digest: <url>`. Silent on quiet days (volume < 25% of 7d average AND no negative-sentiment spike).

8. **Log** to `memory/logs/${today}.md`:
   ```
   ## [REPLACE: SKILL_NAME]
   - **Volume**: x_posts=N, reddit_posts=N, vs_7d_avg=Δ%
   - **Sentiment**: pos=X, neu=Y, neg=Z
   - **Status**: SOCIAL_OK | SOCIAL_QUIET | SOCIAL_SPIKE (vol > 2x avg) | SOCIAL_DEGRADED
   ```

## Network note

X / xAI requires `XAI_API_KEY`; a bare `$XAI_API_KEY` on a `curl` line is refused by the Bash analyzer, so call `./secretcurl` with the `{XAI_API_KEY}` placeholder (the key is injected via `requires:`). Reddit's JSON endpoint is keyless but rate-limited per IP — `WebFetch` is the fallback when `curl` returns 429.

**Shell shape.** Each Bash call is one allowed command (pipes are fine). The run refuses a call that sets a variable (`KEYWORDS=...`), uses `if` / `for`, tests a key, joins commands with `;`, `&&` or `||`, redirects into a file (`> .reddit-cache.json`), or puts a shell variable on a `./secretcurl` line (`-d "$PAYLOAD"`, `$KEYWORD`), and each refusal costs a model turn. So make one call per keyword with the keyword written in literally, pipe each request body into `./secretcurl ... --data-binary @-`, save replies with `-o /tmp/<file>`, and write the article and the log with Write/Edit.

## Constraints

- **Bot filter** is critical. New accounts with high posting velocity dominate any keyword and are almost always inauthentic. Strict drop.
- **Volume is more honest than sentiment**. A `SPIKE` (volume > 2x 7d avg) is a real signal; sentiment shifts within normal volume often aren't.
- **Engagement filters scale**. `MIN_LIKES = [REPLACE: MIN_LIKES]` is a starting threshold — raise it as the topic gains attention so noise stays out.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.