Token导航 LogoToken导航

Agent Skill · 效率

lead-scorer-pro(首席得分手专业版)

lead-scorer-pro 用于辅助安全审计、权限检查和凭据风险排查,适合在 OpenClaw 中需要复核安全边界、认证流程或敏感配置时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

lead-scorer-pro 是效率类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为需要联网;许可证为 MIT-0,第三方扫描有提醒项,按安装量在效率类的 21,003 个 Skill 里排第 5,268。

总安装 11,328周安装 472GitHub Stars 公开资料未说明下载 3,776核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:lead-scorer-pro(首席得分手专业版)
来源仓库:https://github.com/maverick-software/lead-scorer-pro
安装命令:
openclaw skills install lead-scorer-pro
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

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

ClawHubOpenClaw
openclaw skills install lead-scorer-pro

这个 Skill 是做什么的

效率类 Skill 把重复的整理、汇总、转换工作交给助手完成,减少手工复制粘贴。

根据审核信号为网站线索打分并分配优先级等级。适合用于线索质量分级与自动化处理流程。输出结果可写入指定格式供后续使用。lead-scorer-pro 属于效率类 Skill,可作为该场景下的辅助能力补充。安装命令:openclaw skills install lead-scorer-pro。

需确认是否具备写入选定存储路径的权限。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install lead-scorer-pro;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

lead-scorer-pro 怎么安装?

在终端执行 openclaw skills install lead-scorer-pro。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

lead-scorer-pro 支持哪些 AI 工具?

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

lead-scorer-pro 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

lead-scorer-pro 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

lead-scorer-pro 用的人多吗?

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

lead-scorer-pro 安全吗?

第三方扫描有提醒项,说明存在需要人工确认的行为。安装前请打开源码看清它读了什么、联网到哪里。

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

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。

先想清楚的地方

  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

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

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

效率类 Skill 对比

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

GitHub 代码协作 · OpenClaw

7,632,918545需要联网MIT-0通过
nano-pdf

Nano PDF 文档 · OpenClaw

4,249,476231需要联网MIT-0通过
auto-updater

自动更新程序 · OpenClaw

2,964,063386操作浏览器MIT-0通过
video-frames

视频帧 · OpenClaw

2,621,304112需要联网MIT-0通过
gemini

Gemini 助手 · OpenClaw

2,547,39648需要联网MIT-0有提醒
lead-scorer-pro

首席得分手专业版 · 本页

11,328—需要联网MIT-0有提醒

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

SKILL.md 原文

name
lead-scorer
description
Score a website lead 0–100 based on audit signals from the website-auditor skill, assign a priority tier (Hot/Warm/Lukewarm/Cold), and write the result to a Google Sheet. Applies a weighted rubric across 8 audit dimensions. Use as the final step in the lead list building pipeline after website-auditor and contact-enrichment have run. Requires GOOGLE_SHEET_NAME and GOOGLE_CREDS_FILE for Google Sheets output.
metadata
requires
packages
[gspread, google-auth]
optionalEnv
[GOOGLE_SHEET_NAME, GOOGLE_CREDS_FILE]

Lead Scorer Skill

Takes a completed audit dict → applies scoring rubric → assigns tier → writes row to Google Sheet.

Scoring Rubric (0–100 scale)

Higher score = hotter lead = more likely to need a new website.

SCORING_RUBRIC = [
    # Signal                            Condition                           Points
    ("dead_site",        lambda a: a.get("status_code") in ("DEAD","TIMEOUT","SSL_ERROR"), 40),
    ("copyright_5plus",  lambda a: (a.get("years_outdated") or 0) >= 5,    35),
    ("pagespeed_low",    lambda a: 0 < (a.get("pagespeed_mobile") or 101) < 50, 30),
    ("copyright_3to4",   lambda a: 3 <= (a.get("years_outdated") or 0) < 5, 25),
    ("no_ssl",           lambda a: not a.get("has_ssl"),                    25),
    ("not_mobile",       lambda a: not a.get("is_mobile_friendly"),         20),
    ("outdated_cms",     lambda a: a.get("has_outdated_cms"),               20),
    ("no_contact_found", lambda a: not a.get("primary_email") and not a.get("primary_phone"), 20),
    ("pagespeed_mid",    lambda a: 50 <= (a.get("pagespeed_mobile") or 101) < 70, 15),
    ("table_layout",     lambda a: "table_layout" in (a.get("design_signals") or []), 15),
    ("copyright_1to2",   lambda a: 1 <= (a.get("years_outdated") or 0) < 3, 10),
    ("no_open_graph",    lambda a: "no_open_graph" in (a.get("design_signals") or []), 10),
    ("flash_detected",   lambda a: "flash_detected" in (a.get("design_signals") or []), 20),
    ("uses_frames",      lambda a: "uses_frames" in (a.get("design_signals") or []), 20),
    ("no_meta_desc",     lambda a: "no_meta_description" in (a.get("design_signals") or []), 5),
    ("no_favicon",       lambda a: "no_favicon" in (a.get("design_signals") or []), 5),
    ("font_tags",        lambda a: "font_tags" in (a.get("design_signals") or []), 10),
    ("heavy_inline",     lambda a: "heavy_inline_styles" in (a.get("design_signals") or []), 8),
]

Scoring Function

def score_lead(audit: dict) -> dict:
    """
    Apply rubric to audit dict.
    Returns audit dict + score + tier + issues list + tier emoji.
    """
    score = 0
    issues = []
    matched_rules = []
    
    for rule_name, condition, points in SCORING_RUBRIC:
        try:
            if condition(audit):
                score += points
                matched_rules.append(f"{rule_name} (+{points})")
                issues.append(ISSUE_LABELS.get(rule_name, rule_name))
        except Exception:
            pass
    
    # Cap at 100
    score = min(score, 100)
    
    # Assign tier
    if score >= 80:
        tier = "🔥 Hot"
        tier_code = "hot"
    elif score >= 50:
        tier = "🟡 Warm"
        tier_code = "warm"
    elif score >= 25:
        tier = "🔵 Lukewarm"
        tier_code = "lukewarm"
    else:
        tier = "⚪ Cold"
        tier_code = "cold"
    
    return {
        **audit,
        "lead_score": score,
        "tier": tier,
        "tier_code": tier_code,
        "issues": issues,
        "score_breakdown": matched_rules
    }

# Human-readable issue labels
ISSUE_LABELS = {
    "dead_site":        "Site is dead/unreachable",
    "copyright_5plus":  f"Copyright {'{years}'} years old",
    "copyright_3to4":   "Copyright 3–4 years old",
    "copyright_1to2":   "Copyright 1–2 years old",
    "pagespeed_low":    "PageSpeed score under 50 (mobile)",
    "pagespeed_mid":    "PageSpeed score 50–69 (mobile)",
    "no_ssl":           "No SSL / HTTPS",
    "not_mobile":       "Not mobile responsive",
    "outdated_cms":     "Outdated CMS or tech stack",
    "no_contact_found": "No contact info found on site",
    "table_layout":     "Table-based layout (pre-2010 design)",
    "no_open_graph":    "No social meta tags",
    "flash_detected":   "Flash / Silverlight detected",
    "uses_frames":      "Uses HTML frames",
    "no_meta_desc":     "Missing meta description",
    "no_favicon":       "No favicon",
    "font_tags":        "Font tags detected (ancient HTML)",
    "heavy_inline":     "Heavy inline CSS styles",
}

Google Sheets Integration

import gspread
from google.oauth2.service_account import Credentials
from datetime import datetime
import os

SHEET_COLUMNS = [
    "Date Found", "Business Name", "URL", "Lead Score", "Tier",
    "Primary Email", "All Emails", "Phone", "Copyright Year",
    "Tech Stack", "PageSpeed (Mobile)", "Has SSL", "Mobile Friendly",
    "Issues Found", "Score Breakdown", "Status", "Notes"
]

def get_sheet(sheet_name: str = None, creds_file: str = None):
    """Authenticate and return the target Google Sheet."""
    sheet_name = sheet_name or os.environ.get("GOOGLE_SHEET_NAME", "Website Leads")
    creds_file = creds_file or os.environ.get("GOOGLE_CREDS_FILE", "credentials.json")
    
    scopes = [
        "https://www.googleapis.com/auth/spreadsheets",
        "https://www.googleapis.com/auth/drive"
    ]
    creds = Credentials.from_service_account_file(creds_file, scopes=scopes)
    client = gspread.authorize(creds)
    
    try:
        sheet = client.open(sheet_name).sheet1
    except gspread.SpreadsheetNotFound:
        # Create the sheet if it doesn't exist
        spreadsheet = client.create(sheet_name)
        spreadsheet.share(None, perm_type="anyone", role="writer")
        sheet = spreadsheet.sheet1
        # Write headers
        sheet.append_row(SHEET_COLUMNS)
        print(f"Created new sheet: {sheet_name}")
    
    return sheet

def ensure_headers(sheet):
    """Make sure the header row exists."""
    first_row = sheet.row_values(1)
    if not first_row or first_row[0] != "Date Found":
        sheet.insert_row(SHEET_COLUMNS, index=1)

def lead_to_row(lead: dict) -> list:
    """Convert a scored lead dict to a sheet row."""
    return [
        datetime.now().strftime("%Y-%m-%d"),
        lead.get("business_name", ""),
        lead.get("url", ""),
        lead.get("lead_score", 0),
        lead.get("tier", ""),
        lead.get("primary_email", ""),
        ", ".join(lead.get("emails", [])),
        lead.get("primary_phone", ""),
        lead.get("copyright_year", ""),
        ", ".join(lead.get("tech_stack", [])[:3]),          # Top 3 techs
        lead.get("pagespeed_mobile", ""),
        "✅" if lead.get("has_ssl") else "❌",
        "✅" if lead.get("is_mobile_friendly") else "❌",
        " | ".join(lead.get("issues", [])[:5]),             # Top 5 issues
        " | ".join(lead.get("score_breakdown", [])[:5]),
        "New",
        ""
    ]

def write_lead_to_sheet(lead: dict, sheet=None) -> bool:
    """Score the lead and write it to the Google Sheet."""
    if sheet is None:
        sheet = get_sheet()
    ensure_headers(sheet)
    
    scored = score_lead(lead)
    row = lead_to_row(scored)
    
    try:
        sheet.append_row(row, value_input_option="USER_ENTERED")
        return True
    except Exception as e:
        print(f"Sheet write error: {e}")
        return False

def write_leads_batch(leads: list[dict], sheet=None) -> int:
    """Write multiple leads at once. Returns count written."""
    if sheet is None:
        sheet = get_sheet()
    ensure_headers(sheet)
    
    rows = []
    for lead in leads:
        scored = score_lead(lead)
        if scored.get("lead_score", 0) >= 0:  # Always write (filter upstream)
            rows.append(lead_to_row(scored))
    
    if rows:
        sheet.append_rows(rows, value_input_option="USER_ENTERED")
    
    return len(rows)

Apply Conditional Formatting (Color by Tier)

def apply_conditional_formatting(spreadsheet_id: str, creds_file: str = None):
    """
    Apply color-coding to the sheet based on Lead Score in column D.
    Requires google-api-python-client (pip install google-api-python-client).
    """
    from googleapiclient.discovery import build
    from google.oauth2.service_account import Credentials
    
    creds_file = creds_file or os.environ.get("GOOGLE_CREDS_FILE", "credentials.json")
    scopes = ["https://www.googleapis.com/auth/spreadsheets"]
    creds = Credentials.from_service_account_file(creds_file, scopes=scopes)
    service = build("sheets", "v4", credentials=creds)
    
    rules = [
        # 🔥 Hot (≥80) — red background
        {"ranges": [{"sheetId": 0, "startRowIndex": 1, "endRowIndex": 1000,
                     "startColumnIndex": 0, "endColumnIndex": 17}],
         "booleanRule": {
             "condition": {"type": "NUMBER_GREATER_THAN_EQ",
                           "values": [{"userEnteredValue": "80"}]},
             "format": {"backgroundColor": {"red": 1.0, "green": 0.8, "blue": 0.8}}
         }},
        # 🟡 Warm (50–79) — yellow background
        {"ranges": [{"sheetId": 0, "startRowIndex": 1, "endRowIndex": 1000,
                     "startColumnIndex": 0, "endColumnIndex": 17}],
         "booleanRule": {
             "condition": {"type": "NUMBER_BETWEEN",
                           "values": [{"userEnteredValue": "50"}, {"userEnteredValue": "79"}]},
             "format": {"backgroundColor": {"red": 1.0, "green": 0.95, "blue": 0.7}}
         }},
        # 🔵 Lukewarm (25–49) — blue background
        {"ranges": [{"sheetId": 0, "startRowIndex": 1, "endRowIndex": 1000,
                     "startColumnIndex": 0, "endColumnIndex": 17}],
         "booleanRule": {
             "condition": {"type": "NUMBER_BETWEEN",
                           "values": [{"userEnteredValue": "25"}, {"userEnteredValue": "49"}]},
             "format": {"backgroundColor": {"red": 0.8, "green": 0.9, "blue": 1.0}}
         }},
    ]
    
    # The "D" column (index 3) is used for conditional formatting range
    body = {"requests": [{"addConditionalFormatRule": {"rule": r, "index": i}}
                         for i, r in enumerate(rules)]}
    service.spreadsheets().batchUpdate(spreadsheetId=spreadsheet_id, body=body).execute()
    print("Conditional formatting applied ✅")

Full Pipeline Usage Example

# Putting it all together
from lead_list_builder import run_pipeline

results = run_pipeline(
    niche="landscaping",
    city="Portland OR",
    limit=25,
    min_score=30,
    sheet_name="Portland Landscaping Leads"
)

# Output:
# ✅ Scan complete.
# URLs scanned: 38
# Leads written: 25
# 🔥 Hot: 8 | 🟡 Warm: 11 | 🔵 Lukewarm: 6 | ⚪ Cold: 13

Score Interpretation Guide

ScoreTierMeaningAction
80–100🔥 HotSite is dead, ancient, or totally brokenCall or email today
50–79🟡 WarmMultiple serious issues, clear needFollow up this week
25–49🔵 LukewarmSome issues, may be open to upgradeLow-priority outreach
0–24⚪ ColdSite is decent, not a strong prospectSkip or archive

平台分布

OpenClaw

93.8%
按下载量换算3,542

安全审计

VirusTotal

可疑

ClawScan

可疑

Static analysis

未展示

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

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

继续浏览同类 Skills