概要
このワークフローは、定期的にRedditで自社ブランド、製品、または選択したキーワードのメンションを検索します。新しいメンションが見つかると、投稿タイトル、サブレディット、スコア、直接リンクを含むSlackメッセージにフォーマットします。チームはこれを使用して、顧客のフィードバック、競合のメンション、コミュニティの議論がバイラルになる前にキャッチします。
トリガー
Cronスケジュール(4時間ごと)
スケジュール
4時間ごとに実行
ワークフローのステップ
ブランドキーワードを定義する
Redditで監視するブランド名、製品名、競合名のリストを設定します。
Scavio経由でRedditを検索
各キーワードに対してプラットフォームredditでScavio APIを呼び出し、新着順に並べ替えます。
新しいメンションをフィルタリング
結果を以前の実行で保存された既視の投稿IDリストと比較します。
Slackメッセージをフォーマット
投稿タイトル、サブレディット、投票数、パーマリンクを含むSlack Block Kitメッセージを作成します。
Slackに投稿
フォーマットされたメッセージをWebhook経由で設定されたSlackチャンネルに送信します。
既視リストを更新
新しい投稿IDを既視リストに追加して、再びアラートされないようにします。
Python実装
import requests
import json
from pathlib import Path
API_KEY = "your_scavio_api_key"
SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
def search_reddit(query: str) -> list[dict]:
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "reddit", "query": query},
timeout=15,
)
res.raise_for_status()
return res.json().get("organic", [])
def send_slack(mentions: list[dict]):
blocks = [{"type": "header", "text": {"type": "plain_text", "text": "New Reddit Mentions"}}]
for m in mentions[:10]:
blocks.append({
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"*<{m['link']}|{m['title']}>*\nr/{m.get('subreddit', 'unknown')} | score: {m.get('score', 0)}",
},
})
requests.post(SLACK_WEBHOOK, json={"blocks": blocks}, timeout=10)
def run():
keywords = ["your-brand", "your-product"]
seen_path = Path("seen_reddit.json")
seen = set(json.loads(seen_path.read_text())) if seen_path.exists() else set()
new_mentions = []
for kw in keywords:
results = search_reddit(kw)
for r in results:
post_id = r.get("link", "")
if post_id and post_id not in seen:
new_mentions.append(r)
seen.add(post_id)
if new_mentions:
send_slack(new_mentions)
print(f"Alerted {len(new_mentions)} new mentions")
else:
print("No new mentions")
seen_path.write_text(json.dumps(list(seen)))
if __name__ == "__main__":
run()JavaScript実装
const API_KEY = "your_scavio_api_key";
const SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL";
async function searchReddit(query) {
const res = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST",
headers: {
"x-api-key": API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({ platform: "reddit", query }),
});
if (!res.ok) throw new Error(`scavio ${res.status}`);
const data = await res.json();
return data.organic ?? [];
}
async function sendSlack(mentions) {
const blocks = [
{ type: "header", text: { type: "plain_text", text: "New Reddit Mentions" } },
];
for (const m of mentions.slice(0, 10)) {
blocks.push({
type: "section",
text: {
type: "mrkdwn",
text: `*<${m.link}|${m.title}>*\nr/${m.subreddit ?? "unknown"} | score: ${m.score ?? 0}`,
},
});
}
await fetch(SLACK_WEBHOOK, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ blocks }),
});
}
async function run() {
const fs = await import("fs/promises");
const keywords = ["your-brand", "your-product"];
let seen = new Set();
try {
seen = new Set(JSON.parse(await fs.readFile("seen_reddit.json", "utf8")));
} catch {}
const newMentions = [];
for (const kw of keywords) {
const results = await searchReddit(kw);
for (const r of results) {
if (r.link && !seen.has(r.link)) {
newMentions.push(r);
seen.add(r.link);
}
}
}
if (newMentions.length) {
await sendSlack(newMentions);
console.log(`Alerted ${newMentions.length} new mentions`);
} else {
console.log("No new mentions");
}
await fs.writeFile("seen_reddit.json", JSON.stringify([...seen]));
}
run();使用プラットフォーム
任意のサブレディットからのコミュニティ、投稿、スレッドコメント