Token导航 LogoToken导航

Agent Skill · 待分类

spam-prevention(垃圾邮件预防)

spam-prevention 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

spam-prevention 是待分类类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为操作浏览器;许可证信息还不明确,第三方扫描已通过,按安装量在待分类类的 11,208 个 Skill 里排第 4,655。

总安装 705周安装 12GitHub Stars 公开资料未说明下载 97核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:spam-prevention(垃圾邮件预防)
来源仓库:https://github.com/hwatkins/my-skills
仓库路径:skills/spam-prevention
安装命令:
npx skills add https://github.com/hwatkins/my-skills --skill spam-prevention
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/hwatkins/my-skills --skill spam-prevention

这个 Skill 是做什么的

这个 Skill 的分类还没最终确定,用法以来源仓库的说明为准。

spam-prevention 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态、代码变更或协作事项进行整理。

通过 npx skills add 命令从指定 GitHub 仓库安装,需结合原始 README 核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写操作。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/spam-prevention

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/hwatkins/my-skills --skill spam-prevention;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要操作浏览器,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

spam-prevention 怎么安装?

在终端执行 npx skills add https://github.com/hwatkins/my-skills --skill spam-prevention。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

spam-prevention 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

spam-prevention 需要什么权限?

权限级别是操作浏览器。该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

spam-prevention 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

spam-prevention 用的人多吗?

公开数据是累计安装 705 次,近一周安装 12 次,下载 97 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

spam-prevention 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理待分类类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

待分类类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
infsh-cli

infsh CLI · Codex、Claude

4,374,576382权限未标注未明确未收录
ai-video-generation

AI 视频生成 · Codex、Claude

4,313,376382调用外部服务未明确有提醒
lark-openapi-explorer

云雀 OpenAPI 浏览器 · Codex、Claude

2,064,1209,011需要联网未明确有提醒
lark-workflow-standup-report

Lark 工作流程站立报告 · Codex、Claude

2,041,6328,978需要联网未明确通过
use-my-browser

使用我的浏览器 · Codex、Claude

1,848,49140操作浏览器未明确未通过
spam-prevention

垃圾邮件预防 · 本页

705—操作浏览器未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Spam & Bot Prevention for SaaS

Expert guidance for preventing spam signups, bot accounts, and abuse of registration and trial flows in SaaS applications.

Core Principles

  • Layer defenses — no single technique stops all spam; combine multiple signals
  • Minimize friction for real users — invisible protections first, visible challenges only when needed
  • Fail closed on high-risk signals — block or queue for review rather than letting spam through
  • Monitor and adapt — spammers evolve; your defenses must too

Defense Layers (Priority Order)

Layer 1: Invisible Protections (Zero Friction)

These run silently — real users never notice them.

Honeypot Fields

Add hidden form fields that real users won't fill in but bots will.

<!-- Hidden from real users via CSS -->
<div style="position: absolute; left: -9999px;" aria-hidden="true">
  <label for="website">Website</label>
  <input type="text" name="website" id="website" tabindex="-1" autocomplete="off" />
</div>
# Server-side: reject if honeypot field has a value
def create(conn, %{"user" => user_params}) do
  if user_params["website"] && user_params["website"] != "" do
    # Bot detected — return fake success (don't reveal detection)
    conn
    |> put_flash(:info, "Check your email to confirm your account.")
    |> redirect(to: ~p"/")
  else
    # Real signup flow
    Accounts.register_user(user_params)
  end
end
Time-Based Detection

Bots submit forms instantly. Real users take time.

# Add a hidden timestamp field
def new(conn, _params) do
  token = Phoenix.Token.sign(conn, "form_time", System.system_time(:second))
  render(conn, :new, form_token: token)
end

def create(conn, %{"form_token" => token} = params) do
  case Phoenix.Token.verify(conn, "form_time", token, max_age: 3600) do
    {:ok, timestamp} ->
      elapsed = System.system_time(:second) - timestamp
      if elapsed < 3 do
        # Submitted in under 3 seconds — likely bot
        fake_success_response(conn)
      else
        real_signup(conn, params)
      end
    {:error, _} ->
      fake_success_response(conn)
  end
end
JavaScript Challenge

Many bots don't execute JavaScript. Require a JS-generated token.

// On page load, generate a token after a delay
setTimeout(() => {
  document.getElementById('js_token').value = btoa(Date.now().toString());
}, 1000);
# Server: reject if js_token is missing or invalid
if is_nil(params["js_token"]) or params["js_token"] == "" do
  fake_success_response(conn)
end

Layer 2: Email Verification

Disposable Email Blocking

Block known throwaway email domains.

# Use a library like `disposable_email_domains` or maintain your own list
@disposable_domains File.read!("priv/disposable_domains.txt")
  |> String.split("\n", trim: true)
  |> MapSet.new()

def validate_email_domain(changeset) do
  validate_change(changeset, :email, fn :email, email ->
    domain = email |> String.split("@") |> List.last() |> String.downcase()
    if MapSet.member?(@disposable_domains, domain) do
      [email: "please use a permanent email address"]
    else
      []
    end
  end)
end

Sources for disposable domain lists:

  • disposable-email-domains (community-maintained, 100k+ domains)
  • Services: Kickbox, ZeroBounce, NeverBounce (API-based, real-time)
Email Confirmation Flow

Require email verification before activating accounts.

def register_user(attrs) do
  %User{}
  |> User.registration_changeset(attrs)
  |> Ecto.Changeset.put_change(:confirmed_at, nil)
  |> Repo.insert()
  |> case do
    {:ok, user} ->
      deliver_confirmation_email(user)
      {:ok, user}
    error -> error
  end
end

# Don't allow login until confirmed
def get_user_by_email_and_password(email, password) do
  user = Repo.get_by(User, email: email)
  if user && user.confirmed_at && User.valid_password?(user, password) do
    user
  end
end
MX Record Validation

Verify the email domain actually has mail servers.

def valid_mx_record?(email) do
  domain = email |> String.split("@") |> List.last()
  case :inet_res.lookup(to_charlist(domain), :in, :mx) do
    [] -> false
    _records -> true
  end
end

Layer 3: Rate Limiting

IP-Based Rate Limiting
# Using Hammer (Elixir rate limiter)
def create(conn, params) do
  ip = conn.remote_ip |> :inet.ntoa() |> to_string()

  case Hammer.check_rate("signup:#{ip}", 60_000, 5) do
    {:allow, _count} ->
      real_signup(conn, params)
    {:deny, _limit} ->
      conn
      |> put_status(429)
      |> put_flash(:error, "Too many signup attempts. Please try again later.")
      |> render(:new)
  end
end
Fingerprint-Based Rate Limiting

IP alone isn't enough — use browser fingerprinting for additional signal.

// Client-side: generate a fingerprint hash
// Use a library like FingerprintJS (free tier available)
import FingerprintJS from '@fingerprintjs/fingerprintjs';
const fp = await FingerprintJS.load();
const result = await fp.get();
document.getElementById('fp').value = result.visitorId;
# Server: rate limit per fingerprint too
case Hammer.check_rate("signup:fp:#{params["fp"]}", 86_400_000, 3) do
  {:allow, _} -> proceed()
  {:deny, _} -> block()
end

Layer 4: CAPTCHA (Visible Friction)

Use only when invisible layers aren't enough, or as escalation for suspicious behavior.

Progressive CAPTCHA

Don't show CAPTCHA to everyone — only when risk signals are present.

def needs_captcha?(conn, params) do
  ip = conn.remote_ip |> :inet.ntoa() |> to_string()

  cond do
    # High signup rate from this IP
    Hammer.check_rate_inc("signup_check:#{ip}", 3_600_000, 10) == {:deny, 10} -> true
    # Disposable email domain
    disposable_email?(params["email"]) -> true
    # Missing JS token (possible bot)
    is_nil(params["js_token"]) -> true
    # Default: no captcha needed
    true -> false
  end
end

CAPTCHA Options (ranked by UX):

  1. Cloudflare Turnstile — invisible/managed, free, privacy-friendly
  2. hCaptcha — privacy-focused, pays publishers
  3. ALTCHA — self-hosted, GDPR-compliant, proof-of-work based
  4. reCAPTCHA v3 — invisible scoring (but Google tracking concerns)
  5. reCAPTCHA v2 — checkbox/image challenges (most friction)

Layer 5: Post-Signup Detection

Catch spam that gets through initial defenses.

Behavioral Signals
defmodule MyApp.SpamDetection do
  def spam_score(user) do
    score = 0

    # No profile completed within 24 hours
    score = if is_nil(user.name), do: score + 1, else: score

    # No meaningful actions taken
    score = if user.actions_count == 0 and hours_since_signup(user) > 2,
      do: score + 2, else: score

    # Suspicious email patterns (random strings)
    score = if random_looking_email?(user.email), do: score + 2, else: score

    # Signed up from known VPN/proxy
    score = if vpn_ip?(user.signup_ip), do: score + 1, else: score

    score
  end

  defp random_looking_email?(email) do
    local = email |> String.split("@") |> List.first()
    # High ratio of digits to letters, or very long random strings
    digit_ratio = local |> String.graphemes() |> Enum.count(&(&1 =~ ~r/\d/)) |> Kernel./(String.length(local))
    digit_ratio > 0.5 or String.length(local) > 20
  end
end
Automated Cleanup
# Oban job to clean unconfirmed accounts
defmodule MyApp.Workers.CleanupUnconfirmed do
  use Oban.Worker, queue: :maintenance

  @impl Oban.Worker
  def perform(_job) do
    cutoff = DateTime.utc_now() |> DateTime.add(-72, :hour)

    from(u in User,
      where: is_nil(u.confirmed_at),
      where: u.inserted_at < ^cutoff
    )
    |> Repo.delete_all()

    :ok
  end
end

Implementation Checklist

Minimum Viable Protection (Start Here)

  • Honeypot field on signup form
  • Email confirmation required before account activation
  • Disposable email domain blocking
  • IP-based rate limiting (5 signups/hour per IP)
  • Clean up unconfirmed accounts after 72 hours

Enhanced Protection

  • Time-based form submission detection
  • JavaScript challenge token
  • MX record validation
  • Progressive CAPTCHA (Cloudflare Turnstile)
  • Browser fingerprint rate limiting

Advanced Protection

  • Post-signup behavioral scoring
  • VPN/proxy detection
  • Phone number verification for high-value actions
  • Machine learning anomaly detection
  • Manual review queue for borderline cases

Monitoring & Metrics

Track these to know if your defenses are working:

MetricWhat It Tells You
Signup-to-confirmation rateLow = spam getting through signup
Confirmation-to-activation rateLow = real users having trouble
Signups per IP per hourSpikes = bot attack
Disposable email block rateRising = targeted by spam
CAPTCHA trigger rateToo high = too aggressive; too low = too lenient
False positive rateReal users being blocked (monitor support tickets)

Common Mistakes

  • Blocking too aggressively — false positives lose real customers. Start lenient, tighten based on data.
  • Relying on CAPTCHA alone — bots solve CAPTCHAs. Layer defenses.
  • Revealing detection — don't tell bots they were caught. Return fake success responses.
  • Hardcoding disposable domains — the list grows daily. Use an updated source or API.
  • No monitoring — you won't know defenses failed until spam is everywhere.
  • Blocking VPNs entirely — many legitimate users use VPNs. Use as a signal, not a block.

Related Skills

  • saas-security: Broader security (auth, API protection, account takeover)
  • stripe-integration: Payment verification as anti-spam signal
  • email-sequence: Confirmation and verification email flows

平台分布

Codex

35.44%
按下载量换算34

Claude

31.08%
按下载量换算30

Cursor

19.6%
按下载量换算19

Gemini CLI

10.1%
按下载量换算10

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills