Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

Email Campaign Management

v1.0.0

Complete workflow for email marketing campaigns with conversion tracking and trial activation. Use when (1) Creating email campaigns, (2) Sending campaign em...

0· 113·1 current·1 all-time
byToby Morning@urbantech

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for urbantech/email-campaign-management.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "Email Campaign Management" (urbantech/email-campaign-management) from ClawHub.
Skill page: https://clawhub.ai/urbantech/email-campaign-management
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install email-campaign-management

ClawHub CLI

Package manager switcher

npx clawhub@latest install email-campaign-management
Security Scan
VirusTotalVirusTotal
Suspicious
View report →
OpenClawOpenClaw
Suspicious
medium confidence
Purpose & Capability
The name/description (email campaigns, tracking, trial activation) aligns with the actions in SKILL.md: building SQL schema, sending email via Resend, tracking clicks, and activating trials. Requiring a Resend API and DB access is expected for this purpose. However, the skill fails to declare any required environment variables or configuration for the Resend API key or database connections, which is inconsistent with its functionality.
!
Instruction Scope
SKILL.md instructs executing SQL (SELECT, INSERT, UPDATE) against users/subscriptions tables and performing trial activations (writing tier/status/trial_ends_at). It also contains runnable Python examples that read RESEND_API_KEY and call external API endpoints. These instructions direct reads and sensitive writes to a database and calls to an external service; the doc offers no guardrails (no mention of targeting a staging DB, transactional safety, idempotency checks, or explicit consent). That broad filesystem/DB/write scope is significant and not constrained by the skill metadata.
Install Mechanism
Instruction-only skill with no install spec and no code files. This minimizes installation risk because nothing is downloaded or written to disk by an installer.
!
Credentials
The SKILL.md references RESEND_API_KEY (via os.getenv) and implicitly requires DB connection/cursor/credentials for cur.execute, but requires.env and primary credential fields are empty. This mismatch is disproportionate: the skill needs secrets (API key and DB credentials) to function but asks for none in metadata. That omission prevents proper least-privilege review and may cause a user to unknowingly grant broad credentials to the agent.
Persistence & Privilege
always is false and autonomous invocation is allowed (default). Autonomous execution combined with instructions that perform database writes and external API calls increases potential impact, but autonomous invocation alone is normal. Still, because the skill performs privileged operations in its instructions, administrators should be cautious about allowing it to run without manual oversight.
What to consider before installing
This skill appears to do what it says (send emails, track clicks, activate trials) but the SKILL.md expects an API key and direct database access while the skill metadata declares no required secrets—this is the main red flag. Before installing or enabling: (1) ask the publisher to explicitly list required environment variables (RESEND_API_KEY, DB connection string/credentials) in the metadata; (2) do not give it production DB credentials—test first in a staging environment with limited-scope credentials; (3) ensure the RESEND_API_KEY is scoped/rotated and has rate limits applied; (4) require human approval or code review before the skill performs writes that change subscriptions or activate trials; (5) review all SQL for safety (injection, correct WHERE clauses, transactional semantics) and add logging/undo capability; (6) prefer providing least-privilege, role-scoped DB accounts and a separate email-sending API key scoped to the campaign sender. If the publisher cannot provide clear, matching metadata and safety controls, treat this skill as risky and avoid granting it access to sensitive credentials or production systems.

Like a lobster shell, security has layers — review code before you run it.

latestvk97bf28khxrp0vma6jybj2zz9183g5jn
113downloads
0stars
1versions
Updated 1mo ago
v1.0.0
MIT-0

Email Campaign Management - Complete Workflow

Purpose: Reusable workflow for creating, tracking, and managing email marketing campaigns with conversion tracking, reminder emails, and trial activation.

Scope: Growth marketing, email campaigns, conversion tracking, trial activation, campaign analytics


Campaign Database Schema

campaigns table

CREATE TABLE campaigns (
    id UUID PRIMARY KEY,
    campaign_id VARCHAR(255) UNIQUE NOT NULL,  -- e.g., "ny2026", "summer2026"
    name VARCHAR(255) NOT NULL,
    description TEXT,
    trial_days INTEGER,
    tier VARCHAR(50),  -- ENTERPRISE, SCALE, etc.
    plan_name TEXT,
    offer_expires_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

campaign_clicks table

CREATE TABLE campaign_clicks (
    id UUID PRIMARY KEY,
    campaign_id VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    click_source VARCHAR(100),  -- e.g., "cta_button", "events_click"
    utm_source VARCHAR(100),
    utm_medium VARCHAR(100),
    utm_campaign VARCHAR(100),
    converted BOOLEAN DEFAULT FALSE,
    converted_at TIMESTAMP,
    user_id UUID,
    created_at TIMESTAMP DEFAULT NOW()
);

Campaign Statistics Query Patterns

Get Campaign Overview

SELECT
    COUNT(*) as total_clicks,
    COUNT(DISTINCT email) as unique_users,
    COUNT(CASE WHEN converted = TRUE THEN 1 END) as converted_count,
    COUNT(CASE WHEN converted = FALSE THEN 1 END) as pending_count,
    ROUND(100.0 * COUNT(CASE WHEN converted = TRUE THEN 1 END) / COUNT(*), 2) as conversion_rate
FROM campaign_clicks
WHERE campaign_id = 'campaign-id-here';

Get Registered vs Non-Registered

SELECT
    COUNT(CASE WHEN u.id IS NOT NULL THEN 1 END) as registered_users,
    COUNT(CASE WHEN u.id IS NULL THEN 1 END) as non_registered_users,
    COUNT(CASE WHEN s.tier != 'free' AND s.status = 'active' THEN 1 END) as already_paid_users
FROM campaign_clicks cc
LEFT JOIN users u ON u.email = cc.email
LEFT JOIN subscriptions s ON s.user_id = u.id
WHERE cc.campaign_id = 'campaign-id-here'
  AND cc.converted = FALSE;

Resend API Integration

Rate Limiting (CRITICAL)

Resend Free Tier: 2 requests per second (NOT 100/minute!)

Correct Implementation:

import time

RATE_LIMIT_DELAY = 0.5  # 2 emails per second

for email in emails:
    send_email(email)
    if i < len(emails):
        time.sleep(RATE_LIMIT_DELAY)  # Wait 0.5 seconds

WRONG Implementation (causes 429 errors):

# DON'T DO THIS - sends too fast
RATE_LIMIT = 100  # emails per minute
for email in emails:
    send_email(email)
    # Only pause every 100 emails - TOO LATE!
    if i % RATE_LIMIT == 0:
        time.sleep(60)

Email Sending Function

import os
import requests

RESEND_API_KEY = os.getenv("RESEND_API_KEY")
RESEND_API_URL = "https://api.resend.com/emails"
FROM_EMAIL = "no-reply@ainative.studio"

def send_campaign_email(email: str, campaign_id: str, template_html: str):
    """Send campaign email via Resend."""

    # Replace template variables
    html = template_html.replace("{{email}}", email)
    html = html.replace("{{campaign_id}}", campaign_id)

    payload = {
        "from": FROM_EMAIL,
        "to": [email],
        "subject": "Your campaign subject here",
        "html": html,
        "tags": [
            {"name": "campaign", "value": campaign_id},
            {"name": "type", "value": "reminder"}
        ]
    }

    response = requests.post(
        RESEND_API_URL,
        headers={
            "Authorization": f"Bearer {RESEND_API_KEY}",
            "Content-Type": "application/json"
        },
        json=payload,
        timeout=10
    )

    if response.status_code in [200, 201]:
        return True, response.json().get("id")
    else:
        return False, response.text

Trial Activation Workflow

Activate Trial (CRITICAL: Use UPPERCASE Enums)

def activate_trial(user, campaign_id: str, trial_days: int, plan_name: str):
    """Activate ENTERPRISE trial for user."""

    trial_end = datetime.utcnow() + timedelta(days=trial_days)

    # CRITICAL: PostgreSQL enums are UPPERCASE
    # 'enterprise' → 'ENTERPRISE'
    # 'active' NOT 'trial' (trial status doesn't exist)

    if user['subscription_id']:
        # Update existing subscription
        cur.execute("""
            UPDATE subscriptions
            SET tier = 'ENTERPRISE',
                status = 'active',
                trial_ends_at = %s,
                plan_name = %s,
                plan_price = 0,
                current_period_end = %s,
                updated_at = NOW()
            WHERE id = %s
        """, (trial_end, plan_name, trial_end, user['subscription_id']))
    else:
        # Create new subscription
        cur.execute("""
            INSERT INTO subscriptions (
                user_id, tier, status,
                trial_ends_at, plan_name, plan_price,
                billing_email, start_date,
                current_period_start, current_period_end,
                max_users, max_projects, monthly_token_limit,
                max_ai_requests_per_day, max_models,
                created_at, updated_at
            ) VALUES (
                %s, 'ENTERPRISE', 'active',
                %s, %s, 0,
                %s, NOW(),
                NOW(), %s,
                10, 15, 1000000,
                10000, 100,
                NOW(), NOW()
            )
        """, (
            str(user['user_id']),
            trial_end,
            plan_name,
            user['email'],
            trial_end
        ))

    # Mark click as converted
    cur.execute("""
        UPDATE campaign_clicks
        SET converted = TRUE,
            converted_at = NOW(),
            user_id = %s
        WHERE id = %s
    """, (str(user['user_id']), user['click_id']))

    conn.commit()

Common Pitfalls & Solutions

PITFALL 1: Case-Sensitive Enums

Problem: 'enterprise' fails with "invalid input value for enum" Solution: Always use UPPERCASE: 'ENTERPRISE', 'SCALE', 'FREE'

PITFALL 2: Invalid Status Values

Problem: Using status = 'trial' (doesn't exist) Solution: Use status = 'active' with trial_ends_at field

PITFALL 3: Rate Limiting Too High

Problem: Setting rate limit to 100/minute causes 429 errors Solution: Use 2 per second (0.5s delay between sends)

PITFALL 4: Missing Organization ID

Problem: Some users don't have organization_id, causing NULL constraint errors Solution: Check if organization_id exists before INSERT, use separate query if NULL

PITFALL 5: Hardcoded Email in Templates

Problem: Test email in production template Solution: Use {{email}} template variable, replace at send time

PITFALL 6: Not Closing DB Connections

Problem: "too many clients already" error Solution: Always use try/finally to close connections


Email Template Requirements

Template Structure

All campaign email templates MUST be stored in:

src/backend/app/services/templates/{campaign_id}_{type}.html

Example filenames:

  • ny2026_gift.html - Initial campaign email
  • ny2026_reminder.html - Reminder for non-registered users
  • summer2026_welcome.html - Welcome email

Required Template Variables

<!-- Email parameter for personalized links -->
<a href="https://www.ainative.studio/register?gift={{campaign_id}}&email={{email}}">
    Claim Your Trial
</a>

Styling Standards (Dark Theme)

/* Base colors */
body {
    font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background-color: #131726;
}

.email-container {
    background-color: #22263c;
    border-radius: 16px;
}

/* Header gradient */
.header {
    background: linear-gradient(135deg, #4B6FED 0%, #5867EF 100%);
    padding: 50px 40px;
}

/* CTA Button */
.cta-button {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: #ffffff;
    padding: 18px 48px;
    border-radius: 12px;
}

Quick Reference Commands

Check Campaign Stats

railway run -s "AINative- Core -Production" psql -c "
SELECT
    COUNT(*) as total_clicks,
    COUNT(DISTINCT email) as unique_users,
    COUNT(CASE WHEN converted THEN 1 END) as converted
FROM campaign_clicks
WHERE campaign_id = 'your-campaign-id';
"

Send Reminder Campaign

railway run -s "AINative- Core -Production" \
  python3 scripts/send_{campaign_id}_reminder.py --yes

End-to-End Campaign Checklist

  • Create campaign record in database
  • Add campaign to backend VALID_CAMPAIGNS config
  • Create email templates (gift + reminder)
  • Test email send to yourself
  • Deploy backend changes to Railway
  • Launch initial campaign
  • Monitor click tracking (first 24h)
  • Check conversion rate (day 3)
  • Send reminder emails (day 7)
  • Activate trials for registered users
  • Generate final campaign report

Comments

Loading comments...