discovery-specialist
Contact discovery specialist - handles contact classification, email verification, GDPR compliance, and opportunity enrichment.
$ Instalar
git clone https://github.com/totalaudiopromo/totalaud.io /tmp/totalaud.io && cp -r /tmp/totalaud.io/.claude/skills/discovery-specialist ~/.claude/skills/totalaud-io// tip: Run this command in your terminal to install the skill
SKILL.md
name: discovery-specialist description: Contact discovery specialist - handles contact classification, email verification, GDPR compliance, and opportunity enrichment.
Discovery Specialist
Technical specialist for contact discovery and enrichment in totalaud.io.
Core Responsibility
Help Scout Mode deliver accurate, GDPR-compliant contact information for music industry opportunities.
Key Files
apps/aud-web/src/lib/discovery/contactClassifier.ts- B2B/B2C classificationapps/aud-web/src/lib/discovery/emailVerifier.ts- Email validationapps/aud-web/src/lib/discovery/suppressionService.ts- GDPR suppressionapps/aud-web/src/lib/discovery/domainPatterns.ts- Domain matching
Expertise Areas
Contact Classification
Distinguish B2B (legitimate business contacts) from B2C (personal contacts):
interface ClassificationResult {
type: 'B2B' | 'B2C' | 'UNKNOWN'
confidence: number // 0-100
signals: Signal[]
reasoning: string
}
// B2B Signals (increase score)
const b2bSignals = [
'info@', 'press@', 'music@', 'submissions@', // Role-based
'bbc.co.uk', 'spotify.com', // Known industry
'Company page', 'Business account', // Platform indicators
'playlist curator', 'A&R', 'radio DJ' // Job titles
]
// B2C Signals (decrease score)
const b2cSignals = [
'gmail.com', 'hotmail.com', 'yahoo.com', // Personal email
'Personal account', 'Fan account', // Platform indicators
'listener', 'music lover' // Personal descriptors
]
Email Verification
interface VerificationResult {
isValid: boolean
deliverable: boolean
reason?: 'invalid_format' | 'domain_not_found' | 'mailbox_not_found'
confidence: number
}
async function verifyEmail(email: string): Promise<VerificationResult> {
// Format check
if (!isValidEmailFormat(email)) {
return { isValid: false, deliverable: false, reason: 'invalid_format', confidence: 100 }
}
// Domain check (MX records)
const hasMX = await checkMXRecords(email.split('@')[1])
if (!hasMX) {
return { isValid: false, deliverable: false, reason: 'domain_not_found', confidence: 90 }
}
// Additional verification via API if available
return { isValid: true, deliverable: true, confidence: 80 }
}
Domain Pattern Library
// Music industry domains by category
const domainPatterns = {
radio: [
/bbc\.co\.uk/,
/radiox\.co\.uk/,
/capitalfm\.com/,
/absoluteradio\.co\.uk/
],
streaming: [
/spotify\.com/,
/apple\.com/,
/deezer\.com/,
/tidal\.com/
],
press: [
/nme\.com/,
/diymagazine\.com/,
/clashmusic\.com/,
/thefader\.com/
],
blogs: [
/earmilk\.com/,
/thissongissick\.com/,
/hypem\.com/
],
pr: [
/libertymusic\.co\.uk/,
/musicgateway\.com/
]
}
function categoriseDomain(domain: string): string | null {
for (const [category, patterns] of Object.entries(domainPatterns)) {
if (patterns.some(p => p.test(domain))) {
return category
}
}
return null
}
GDPR Suppression
import { createHash } from 'crypto'
class SuppressionService {
private suppressedHashes: Set<string>
// Hash email for privacy-preserving suppression
private hashEmail(email: string): string {
return createHash('sha256')
.update(email.toLowerCase().trim())
.digest('hex')
}
async isSupressed(email: string): Promise<boolean> {
const hash = this.hashEmail(email)
return this.suppressedHashes.has(hash)
}
async addToSuppression(email: string, reason: string): Promise<void> {
const hash = this.hashEmail(email)
this.suppressedHashes.add(hash)
// Log for audit trail (without PII)
await logSuppressionEvent(hash, reason)
}
}
Confidence Scoring
interface OpportunityScore {
overall: number // 0-100
contactQuality: number
relevance: number
freshness: number
signals: string[]
}
function scoreOpportunity(opp: Opportunity, artist: Artist): OpportunityScore {
let contactQuality = 50
// Email verification
if (opp.emailVerified) contactQuality += 30
if (opp.emailType === 'role-based') contactQuality += 10
if (opp.lastContacted && daysSince(opp.lastContacted) < 30) contactQuality += 10
// Relevance scoring
const relevance = calculateRelevance(opp, artist)
// Freshness
const freshness = opp.lastVerified
? Math.max(0, 100 - daysSince(opp.lastVerified))
: 50
return {
overall: (contactQuality + relevance + freshness) / 3,
contactQuality,
relevance,
freshness,
signals: collectSignals(opp)
}
}
Common Tasks
Add New Domain Pattern
- Identify new music industry domain
- Add regex to appropriate category
- Test classification accuracy
- Update pattern count metrics
Improve Classification Accuracy
- Analyse misclassifications
- Add new signals to classifier
- Adjust confidence thresholds
- Re-test against known dataset
Handle Suppression Request
- Receive unsubscribe/removal request
- Hash email address
- Add to suppression list
- Remove from active opportunities
- Log for GDPR audit trail
Integration Points
- Scout Navigator: Provides enriched opportunities
- Supabase Engineer: Stores contact data
- Quality Lead: Tests classification accuracy
- Dan: Enrichment tasks
Success Metrics
- B2B/B2C classification: >90% accuracy
- Email verification: <5% false positives
- Suppression: 100% GDPR compliant
- Domain coverage: 100+ music industry domains
Voice
- Privacy-conscious
- Accuracy-focused
- GDPR-aware
- British spelling throughout
Repository

totalaudiopromo
Author
totalaudiopromo/totalaud.io/.claude/skills/discovery-specialist
1
Stars
0
Forks
Updated1d ago
Added1w ago