Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Sales Client Sourcing

ASecurity

9-step sales client sourcing pipeline — turn a workshop/event satisfaction survey into an enriched outbound funnel with company website, background, tailored 陌生開發 strategy, Hot Lead flag, and Well-Known firm flag. Operates in BATCH on a WHOLE survey sheet and writes back only new columns — it creates no CRM records and drafts no email. For ONE person's row — or a single DM, website enquiry, or business card — hand that signal to sales-outbound instead, which creates the contact + deal and dra...

20 stars
0 votes
0 copies
1 views
Added 9/19/2026
ai-agentsgobashgit

Works with

climcp

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add peter-tu-zynkr/zynkr-skill-builder --skill sales-client-sourcing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sales Client Sourcing?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Sales Client Sourcing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/peter-tu-zynkr-sales-client-sourcing/badge)](https://www.skillsdirectory.com/skills/peter-tu-zynkr-sales-client-sourcing)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: sales-client-sourcing
sheetId: "2.01"
description: "9-step sales client sourcing pipeline — turn a workshop/event satisfaction survey into an enriched outbound funnel with company website, background, tailored 陌生開發 strategy, Hot Lead flag, and Well-Known firm flag. Operates in BATCH on a WHOLE survey sheet and writes back only new columns — it creates no CRM records and drafts no email. For ONE person's row — or a single DM, website enquiry, or business card — hand that signal to sales-outbound instead, which creates the contact + deal and drafts the reply. Natural pairing: run this skill to triage the sheet, then sales-outbound on each Hot Lead row."
category: sales-consultant
project: sales-client-sourcing
platform: claude
status: Done
author: Peter Tu
input: "Google Sheet of survey participants — each row has company name, AI challenges, topic interests, and attend-motivation signals"
process: "Header auto-detection → generic-name filter → output column provisioning → formula writes (Hot Lead / 平均分數) → parallel WebSearch enrichment → strategy synthesis weaving challenges + interests → sort-safe write-back → Well-Known judgment → run summary"
output: "Same sheet + 5–7 new columns: 官網, 公司背景, 陌生開發策略, Hot Lead?, 知名企業? (and optionally 有普通?, 平均分數); plus a 'needs follow-up' list for unknowns"
synergy: []
house-style: bound

---

# Sales Client Sourcing

```bash
npx skills add https://github.com/peter-tu-zynkr/zynkr-skill-builder --skill sales-client-sourcing
```

Turn a post-event satisfaction survey into a tier-1 BD outbound funnel in one pass. Use this skill after any workshop, public class, or speaking event where you've collected attendee responses with company name + AI pain points + topic interests, and you want each row enriched with company context and a tailored cold-outbound (陌生開發) angle. Trigger on phrases like "處理活動問卷", "幫我做 BD 名單", "把問卷變成陌生開發清單", "process survey for BD", or "/sales-client-sourcing".

**Not this skill when — you have ONE person, not a sheet.** A single feedback row, DM,
website enquiry or business card goes to `/sales-outbound`, which writes the contact +
deal into the CRM and drafts the reply. This skill only enriches sheet columns; it never
touches the CRM or Gmail. They pair naturally: triage the whole sheet here, then run
`/sales-outbound` on each Hot Lead row.

---

## Step 0 — Load Config

Read the config file at:
`./sales-client-sourcing-config.md`

Store:
- `SHEET_ID` — Google Sheet ID
- `SHEET_TAB` — sheet tab name (default: first tab)
- `HEADER_HINTS` — fuzzy-match keyword lists per role
- `HOT_LEAD_SIGNALS` — regex phrases that fire the Hot Lead flag
- `GENERIC_PATTERNS` — company-name skip list
- `ADD_SATISFACTION_COLUMNS` — boolean; whether to also write 有普通? + 平均分數
- `SATISFACTION_SCORE_COLUMNS` — Likert (1–5) columns; auto-detect if blank

**If `SHEET_ID` is `TBD`:**
```
⚠️  Google Sheet ID not configured yet.
Please paste the Google Sheet URL or ID before continuing.
```
Wait for user input. Update `SHEET_ID` in memory for this session.

---

## Step 1 — Header Auto-Detection

Display:
```
---------------------------------------------
🎯 Sales Client Sourcing
---------------------------------------------
Phase: Header Detection
---------------------------------------------
```

Read row 1 with `mcp__google-workspace__read_sheet_values`:
- `user_google_email`: `<your-google-workspace-account>`
- `spreadsheet_id`: `SHEET_ID`
- `range`: `[SHEET_TAB]!A1:Z1`

Fuzzy-match each header cell to one of these roles using `HEADER_HINTS`:
- `company_col` — required
- `challenges_col` — required (the J-column equivalent)
- `topics_col` — required (the K-column equivalent)
- `attend_motivation_col` — required for Hot Lead detection
- `participant_name_col` — optional

Store as `COL_MAP`. Display:
```
Detected columns:
  公司名稱        → Column B
  參加原因        → Column C
  AI 挑戰         → Column J
  感興趣議題      → Column K
  學員姓名        → (not detected)

Type [OK] to proceed, or [SET role=X] to override (e.g. SET company=B).
```

Accept overrides until user types `OK`. If a required role can't be matched and the user can't supply it, halt with a clear error.

---

## Step 2 — Generic-Name Filter

Read the full company column with `mcp__google-workspace__read_sheet_values`:
- `range`: `[SHEET_TAB]![company_col]2:[company_col]`

For each row, classify:
- **`generic`** if the cell value (trimmed, lowercased) matches any `GENERIC_PATTERNS` entry, is blank, or is purely numeric.
- **`searchable`** otherwise.

Build `ROWS[]` — one object per row with `{sheet_row, company_name, classification}`.

Display:
```
Survey rows: [N] total
  Searchable: [N1]
  Generic (will skip enrichment): [N2]
```

---

## Step 3 — Output Column Provisioning

Identify the next available empty column block at the right edge of the data. Write headers using `mcp__google-workspace__modify_sheet_values`:
- `range`: `[SHEET_TAB]![first_new_col]1:[last_new_col]1`
- `value_input_option`: `USER_ENTERED`

Always-on headers:
- `官網`
- `公司背景`
- `陌生開發策略`
- `Hot Lead?`
- `知名企業?`

Conditional headers (only if `ADD_SATISFACTION_COLUMNS` is `true` AND not already present):
- `有普通?`
- `平均分數`

Store column letters as `OUT.website_col`, `OUT.background_col`, `OUT.strategy_col`, `OUT.hot_lead_col`, `OUT.well_known_col`, `OUT.has_average_col`, `OUT.avg_score_col`.

---

## Step 4 — Formula Writes

### 4a — Hot Lead formula

Write to row 2 of `OUT.hot_lead_col` using `mcp__google-workspace__modify_sheet_values` (`value_input_option: USER_ENTERED`):

```
=ARRAYFORMULA(IF(LEN(A2:A)=0,"",IF(REGEXMATCH([attend_motivation_col]2:[attend_motivation_col]&"","[HOT_LEAD_SIGNALS_PIPE_JOINED]"),"Y","N")))
```

Substitute `[attend_motivation_col]` with the detected column letter, and `[HOT_LEAD_SIGNALS_PIPE_JOINED]` with the config's `HOT_LEAD_SIGNALS` joined by `|`. Example produced today:
```
=ARRAYFORMULA(IF(LEN(A2:A)=0,"",IF(REGEXMATCH(C2:C&"","評估是否適合在公司內部安排類似課程|評估未來參加公開班課程的可能性"),"Y","N")))
```

### 4b — Satisfaction formulas (if `ADD_SATISFACTION_COLUMNS`)

Resolve `SATISFACTION_SCORE_COLUMNS`. If blank, auto-detect: scan row 2 of all columns for Likert tokens (`非常滿意`, `滿意`, `普通`, `不滿意`, `非常不滿意`); the contiguous block is the Likert range. Store as `LIKERT_RANGE` (e.g. `D2:H`).

Write to row 2 of `OUT.has_average_col`:
```
=ARRAYFORMULA(IF(LEN(A2:A)=0,"",IF(MMULT(([LIKERT_RANGE]="普通")*1,SEQUENCE(COLUMNS([LIKERT_RANGE]),1,1,0))>0,"Y","N")))
```

Write to row 2 of `OUT.avg_score_col`:
```
=ARRAYFORMULA(IF(LEN(A2:A)=0,"",IFERROR(ROUND(MMULT(([LIKERT_RANGE]="非常滿意")*5+([LIKERT_RANGE]="滿意")*4+([LIKERT_RANGE]="普通")*3+([LIKERT_RANGE]="不滿意")*2+([LIKERT_RANGE]="非常不滿意")*1,SEQUENCE(COLUMNS([LIKERT_RANGE]),1,1,0))/MMULT((([LIKERT_RANGE]="非常滿意")+([LIKERT_RANGE]="滿意")+([LIKERT_RANGE]="普通")+([LIKERT_RANGE]="不滿意")+([LIKERT_RANGE]="非常不滿意"))*1,SEQUENCE(COLUMNS([LIKERT_RANGE]),1,1,0)),2),"")))
```

Both formulas propagate automatically — no fill-down needed.

---

## Step 5 — Company Enrichment

Display:
```
---------------------------------------------
Phase: Company Enrichment ([N1] searchable rows)
---------------------------------------------
```

Initialize `ENRICHMENT_CACHE = {}` and `UNKNOWNS = []`.

Read full challenges + topics columns so the strategy synthesis (Step 6) has the participant context:
```
mcp__google-workspace__read_sheet_values
  range: [SHEET_TAB]![company_col]2:[topics_col]
```

For each unique company name in the `searchable` set, in **parallel batches of 8**:

1. Run a single WebSearch: `"[company name]" 台灣 公司 官網`
2. Parse top results:
   - **Accept** the company's own domain (typical patterns: `*.com.tw`, `*.com`, `*.org.tw`, `*.gov.tw`, `*.edu.tw`, `*.ai`).
   - **Reject** directory domains: `twincn.com`, `iyp.com.tw`, `alphaloan.co`, `findcompany.com.tw`, `1111.com.tw`, `104.com.tw`, `518.com.tw`, `taiwantrade.com`, `dnb.com`, `companys.com.tw`, `twfile.com`, `business.com.tw`, `aibee.com.tw`, `costring.com`, `1111人力銀行`, any other generic lookup site.
3. Compose 1-line `company_background`: industry + scale (上市/上櫃/SME/外商/NPO/政府) + location + founding year if obvious + parent group if applicable.
4. **Move on within one search attempt if nothing useful** — push `{company_name, reason}` to `UNKNOWNS[]` and leave `website` as `""`.
5. Store `ENRICHMENT_CACHE[company_name] = {website, background}`.

This caches duplicates (e.g. 程曦資訊 appearing in 4 rows hits WebSearch only once).

For well-known brands the assistant recognizes confidently, the WebSearch step can be skipped and the URL written directly — but only for unambiguous cases (stock-listed Taiwan firms, major government bodies, household-name international brands).

---

## Step 6 — Strategy Synthesis

For each `searchable` row, generate `陌生開發策略` (~120–180 chars) by composing:

1. **Industry anchor** — pull from `company_background` (e.g. "半導體製造", "金融業", "電商").
2. **Challenge → angle mapping** (from challenges column):
   - `公司預算或資源不足` → 分階段付費 / 公開班共學群 / Demo 試水
   - `缺乏明確的導入策略或規劃方向` → AI 導入路線圖 / leadership briefing
   - `AI 工具種類繁多,難以判斷適合選用的工具` → tool selection consulting / 推薦清單
   - `資料安全與隱私疑慮` → 本地部署 Llama / 私有雲 LLM / 閉環 Demo
   - `員工/同事對 AI 學習或使用的接受度較低` → Change Mgmt 工作坊 / 漸進式內訓
   - `目前尚未遇到明顯障礙` → 進階課程 / Agent 工作流
3. **Topic → concrete proposal** (from topics column):
   - `AI 自動化` → 工作流程 RAG / 文件自動產製
   - `客製化 AI / LINE Bot` → LINE Bot 接客 / 內部知識庫
   - `AI Agent` → 跨工具整合 Agent / 任務自動執行
   - `Vibe Coding` → 內部工具快速打造
   - `Prompt 指令設計` → Prompt 模板庫
   - `Persona 設定` → 客戶/員工 Persona 應用
   - `AI 內容生成` / `AI 視覺` → 文案生成 / 廣告素材
4. **Hot Lead emphasis** — if the row's Hot Lead flag would fire (check `attend_motivation_col` against `HOT_LEAD_SIGNALS`), append "建議主動聯繫" + 內訓提案 / 公開班報名邀請.

Reference template library at `./references/strategy-templates.md` for industry-specific phrasings.

Store strategy in `ENRICHMENT_CACHE[company_name].strategies[sheet_row]` — keyed per row because same company in different rows may have different J/K answers.

---

## Step 7 — Write-Back with Sort Safety

**Critical:** Re-read column B (the company column) immediately before writing, because the sheet may have been sorted while enrichment was running.

```
mcp__google-workspace__read_sheet_values
  range: [SHEET_TAB]![company_col]2:[company_col]
```

For each current row in the re-read company column:
- Look up `ENRICHMENT_CACHE[current_company_name]`
- Append to the output 2D array: `[website, background, strategy_for_this_row, "", ""]` (Hot Lead and Well-Known are left empty here — Hot Lead is formula-driven, Well-Known is written in Step 8)
- For `generic` rows, append `["", "", "", "", ""]`

Write the 2D array in **chunks of ≤55 rows** to avoid oversized payloads:
```
mcp__google-workspace__modify_sheet_values
  range: [SHEET_TAB]![OUT.website_col]2:[OUT.well_known_col]56
  value_input_option: USER_ENTERED
  values: [chunk 1]
```
Repeat for subsequent chunks.

---

## Step 8 — Well-Known Flag

Pass the full `ENRICHMENT_CACHE` (`{company_name → background}` map) through a single judgment pass. Mark `Y` for:
- Listed companies (上市/上櫃)
- Recognizable international brands
- Government bodies (縣市政府, 部會)
- Major schools/universities (≥1,000 enrollment or well-known prep schools)
- Big NPOs (national-scale charities, foundations)

Default to `N` for SMEs, niche-domain firms, and unknowns.

Re-read company column once more (in case of more sorting), build the Well-Known column array in current row order, write:
```
mcp__google-workspace__modify_sheet_values
  range: [SHEET_TAB]![OUT.well_known_col]2:[OUT.well_known_col][last_row]
  value_input_option: USER_ENTERED
  values: [[Y/N], [Y/N], ...]
```

---

## Step 9 — Run Summary

Display:
```
=============================================
🎯 Sales Client Sourcing — Complete
=============================================

Total rows:       [N]
Searchable:       [N1]
Generic (skipped):[N2]

Hot Leads:        [count] (filter R = Y)
Well-Known:       [count] (filter S = Y)
Tier-1 (both):    [count] (filter R = Y AND S = Y) ← your priority list

Unknowns (need manual follow-up):
  - guceu (×2 rows) — likely typo or internal code
  - eport — too generic
  - [other unknowns...]

Google Sheet: https://docs.google.com/spreadsheets/d/[SHEET_ID]
=============================================
```

---

## Progress Indicator

Show this line at the top of each phase:

```
🎯 Config → Headers → Filter → Provision → Formulas → Enrich → Strategy → Write → Brand → Done
```

Use `▶` for current phase, `✓` for completed, `○` for upcoming.

---

## Error Handling

- **Header detection fails** for a required role → prompt the user to specify the column letter manually (e.g. `SET challenges=J`).
- **WebSearch returns only directory domains** → leave website blank, add to `UNKNOWNS[]` with reason `"no official site found"`; do NOT keep retrying.
- **WebSearch returns ambiguous name** (e.g. multiple unrelated companies) → leave website blank, note ambiguity in `UNKNOWNS[]`, write `(可能為 X 或 Y)` in background.
- **Google Sheets payload too large** → automatically halve the chunk size and retry.
- **Sheet sorted during run** → write-back step's re-read (Step 7 + Step 8) handles this transparently; no user action needed.
- **Re-run on already-enriched sheet** → detect existing headers (官網/公司背景/陌生開發策略) and ask user whether to skip, refresh-all, or refresh-only-blanks.
- Never silently skip a step — always surface errors clearly.

## House style

Writing style is **not owned by this file**. The house voice lives in two Google Docs under
`[@] 寫作指南` (`12DBdFz3SK22ie9im_ThFMI7IBRXsTZsV`), read at runtime:

- 《[2.0] Zynkr 通用風格指南 House Voice》 `10bOIQwRm9Pxwgct4hlwCwK_B4Pipai1HqBPZKzyRHSE` —
  the universal core, plus the addendum for this surface
- 《[3.2] 禁用詞清單 Forbidden Words》 `1N5sHLP4qzmmhpCGsi6KElxi1z0MFe4QZ0Q_35T10Uyg`

Read both before producing client- or reader-facing text, and scan the draft against 《[3.2]》
before handing it over. If Drive is unreachable, say so in the output rather than proceeding
unchecked. Never re-implement either list inside this file.

Attribution

peter-tu-zynkrpeter-tu-zynkr
View sourceMore from peter-tu-zynkr →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

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

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1066601 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

686011 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

651 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →