claude-home/productivity/n8n/workflows/kofi-implementation-notes.md
Cal Corum c8dcf2b5ee CLAUDE: Add productivity tools with n8n workflow automation
- Add CONTEXT.md with ADHD-optimized task management patterns
- Add troubleshooting guide for productivity tools
- Add n8n workflow documentation including Ko-fi integration
- Document n8n at LXC 210 (10.10.0.210)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 00:48:28 -06:00

14 KiB

Ko-fi → Paper Dynasty Implementation Notes

Date: 2025-11-13 Status: Working in pddev, ready for production n8n Version: Community (self-hosted)

What We Actually Built

This document captures the real implementation vs. the original plan, including all the gotchas we encountered.


Key Differences from Original Plan

1. No Custom Variables (Enterprise Feature)

Original Plan: Use n8n custom variable KOFI_PRODUCT_MAP for product mapping Actual Implementation: Hardcoded product mapping in "Map Products" Code node

Why: Custom variables are enterprise-only in n8n

Product Mapping (Hardcoded in Code Node):

const PRODUCT_MAP = {
  '61de350207': {  // Ko-fi product ID from URL
    name: 'Premium Pack',
    pack_type_id: 3,
    packs_per_quantity: 1
  },
  '2bdb7a4916': {
    name: 'Standard Pack',
    pack_type_id: 1,
    packs_per_quantity: 1
  },
  '3d7a4935aa': {
    name: 'In-Game Currency',
    type: 'currency',
    needs_manual_review: true  // Not implemented yet
  }
};

2. Team Lookup Split into 3 Nodes

Original Plan: Single "Lookup PD Team" Code node with $http.request() Actual Implementation: 3 separate nodes

Why: fetch() and $http are not available in n8n Code nodes

The 3 Nodes:

  1. Extract Team Abbrev (Code) - Regex extraction only
  2. Lookup Team API (HTTP Request) - API call to PD
  3. Process Team Result (Code) - Parse API response

3. Ko-fi Product Codes

Original Plan: Use Ko-fi's "direct_link_code" custom field Actual Reality: Ko-fi doesn't have custom product codes

Solution: Using Ko-fi's internal product IDs from URLs:

  • https://ko-fi.com/s/61de350207 → ID is 61de350207
  • These IDs appear in webhook's shop_items[].direct_link_code

4. Webhook Domain Configuration

Issue: n8n showed https://n8n.yourdomain.com by default Solution: Environment variables were set correctly, just needed n8n restart:

ssh root@10.10.0.210 "cd /opt/n8n && docker compose down && docker compose up -d"

5. API Request Body Formatting

Issue: Paper Dynasty API rejected stringified JSON Solution: Use {{ $json.pack_requests }} without JSON.stringify() or = prefix

Wrong: ={{ JSON.stringify({"packs": $json.pack_requests}) }} Right: {{ $json.pack_requests }}

6. Discord Notifications

Issue: Empty body caused "Cannot send an empty message" Solution: Always include content field even when using embeds

Minimum working Discord message:

{
  "content": "Message text here",
  "embeds": [...]
}

7. Added Donation Support

Extension: Added Switch node to route by transaction type Routes:

  • Output 0: Shop Order → Grant Packs flow
  • Output 1: Donation → Thank you notification
  • Output 2: Subscription → (Future implementation)
  • Fallback: Unknown types → Return 200 OK

Final Working Architecture

Ko-fi Webhook POST
    ↓
[Webhook: Ko-fi Webhook]
Path: /kofi-pd-purchase
    ↓
[Code: Parse & Validate]
- Parse form data JSON
- Validate Ko-fi token (hardcoded)
    ↓
[Switch: Route by Type]
Value: {{ $json.type }}
    ├─ Output 0: "Shop Order"
    │   ↓
    │   [Code: Extract Team Abbrev]
    │   - Regex: /\b([A-Z]{2,4})\b/
    │   ↓
    │   [HTTP: Lookup Team API]
    │   - URL: pddev.manticorum.com/api/v2/teams?abbrev=...
    │   - Auth: Paper Dynasty API credential
    │   ↓
    │   [Code: Process Team Result]
    │   - Extract team ID and abbrev
    │   ↓
    │   [IF: Team Found?]
    │   ├─ True → [Code: Map Products]
    │   │           - Hardcoded product map
    │   │           - Create pack_requests array
    │   │           ↓
    │   │           [HTTP: Grant Packs]
    │   │           - POST /packs with array
    │   │           ↓
    │   │           [IF: API Success?]
    │   │           ├─ True → [HTTP: Discord Success]
    │   │           └─ False → [HTTP: Discord Error]
    │   │
    │   └─ False → [HTTP: Discord Manual Review]
    │
    ├─ Output 1: "Donation"
    │   ↓
    │   [HTTP: Discord Thank You]
    │   - Notification for manual thanks
    │
    └─ Fallback: Other types
        ↓
        [Return 200 OK]

Current Configuration

Environment

  • Testing: pddev.manticorum.com (Paper Dynasty Dev)
  • Production: pd.manticorum.com (not yet deployed)

Credentials Created

  1. Paper Dynasty API (Header Auth)

    • Header: Authorization
    • Value: Bearer Tp3aO3jhYve5NJF1IqOmJTmk
  2. Discord Webhook (not used as credential)

    • URL hardcoded in HTTP Request nodes
    • Webhook: 1438578498108133488/MGx1zyAa1ewzVy3RqCsH50ZJUiVvT5J5Vl2jExGIkIsu6v0x8A9J3-ruRftClPEq91ej

Ko-fi Settings

  • Verification Token: 44d1f957-ac15-497e-8306-4dc667de55d1
  • Webhook URL (test): https://n8n.manticorum.com/webhook-test/kofi-pd-purchase
  • Webhook URL (prod): https://n8n.manticorum.com/webhook/kofi-pd-purchase

Products Configured

Ko-fi ID Name PD Pack Type Quantity
61de350207 Premium Pack 3 1 per qty
2bdb7a4916 Standard Pack 1 1 per qty
3d7a4935aa In-Game Currency N/A Manual review

Testing Results

Successful Test (2025-11-13)

  • Webhook received and parsed
  • Token validated
  • Team "SKB" found via message extraction
  • Product mapped (2bdb7a4916 → 5 standard packs)
  • API call succeeded (201 Created)
  • 5 packs granted to team SKB in pddev
  • Discord success notification sent

Test Command Used

curl -X POST 'https://n8n.manticorum.com/webhook-test/kofi-pd-purchase' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'data={
    "verification_token": "44d1f957-ac15-497e-8306-4dc667de55d1",
    "message_id": "test-001",
    "timestamp": "2025-11-13T12:00:00Z",
    "type": "Shop Order",
    "from_name": "Test Customer",
    "message": "SKB",
    "amount": "5.00",
    "email": "test@example.com",
    "currency": "USD",
    "kofi_transaction_id": "test-001",
    "shop_items": [
      {
        "direct_link_code": "2bdb7a4916",
        "variation_name": "Standard Pack",
        "quantity": 5
      }
    ],
    "discord_userid": null
  }'

Known Limitations

1. No Discord User ID Support Yet

Status: Code is in place but untested Why: Test payload used discord_userid: null Todo: Test with real Discord-linked Ko-fi account

2. Currency Product Not Implemented

Status: Routed to manual review Reason: Paper Dynasty doesn't have currency system yet Todo: Implement currency granting when PD adds support

3. Subscription Type Not Handled

Status: Returns 200 OK but does nothing Reason: Decided to implement shop orders and donations first Todo: Add subscription tier handling

4. Single Discord Channel

Status: All notifications go to "cals-hidey-hole" Todo: Consider separate channels for success/errors/reviews

5. Hardcoded Configuration

Status: All settings hardcoded in Code nodes Why: Community edition limitations Impact: Must edit code nodes to change products, tokens, or URLs Mitigation: Well-documented code with clear comments


Production Deployment Checklist

Before going live with production:

  • Update all API URLs from pddev to prod:

    • "Lookup Team API" node URL
    • "Grant Packs" node URL
  • Update Ko-fi webhook URL:

    • Change from /webhook-test/ to /webhook/
    • Configure in Ko-fi dashboard
  • Activate workflow:

    • Toggle "Active" switch in n8n
  • Test with real Ko-fi purchase:

    • Create $0.01 test product
    • Make test purchase
    • Verify packs granted in production
    • Verify Discord notification
  • Monitor first 10 transactions:

    • Watch Discord for notifications
    • Check n8n execution logs
    • Verify pack distribution accuracy
  • Document any issues encountered


Troubleshooting Guide

Webhook Not Triggering

Symptoms: n8n shows "Waiting for trigger event" but nothing happens Solutions:

  1. Verify workflow is Active (green toggle)
  2. Check webhook path matches Ko-fi configuration
  3. Test with cURL to isolate issue
  4. Check n8n logs: ssh root@10.10.0.210 "cd /opt/n8n && docker compose logs -f n8n"

Token Validation Failing

Symptoms: Workflow stops at "Parse & Validate" with error Solutions:

  1. Verify token in Code node matches Ko-fi dashboard exactly
  2. Check for extra spaces or quotes
  3. Re-copy token from Ko-fi

Team Not Found

Symptoms: Workflow takes "Team Found? False" path Solutions:

  1. Check message field has valid team abbrev (2-4 uppercase letters)
  2. Test API directly: curl -H "Authorization: Bearer TOKEN" "URL/teams?abbrev=SKB"
  3. Verify team exists in target environment (pddev vs prod)

API Call Failing

Symptoms: "API Success?" takes False path Solutions:

  1. Check HTTP Request body format (no JSON.stringify, no = prefix)
  2. Verify pack_requests is an array in "Map Products" output
  3. Check API credentials are correct
  4. Review full error in node execution data

Discord Notification Not Sending

Symptoms: No Discord message received Solutions:

  1. Verify webhook URL is correct
  2. Test webhook directly with cURL
  3. Check body has content field (required even with embeds)
  4. Verify Discord channel hasn't deleted the webhook

Unknown Product Code

Symptoms: unknown_products array has items, takes manual review path Solutions:

  1. Check Ko-fi product ID matches PRODUCT_MAP keys
  2. Get product ID from Ko-fi product URL: /s/{ID}
  3. Add new product to PRODUCT_MAP in "Map Products" code

Maintenance Tasks

Adding New Products

  1. Get Ko-fi product ID from product URL
  2. Edit "Map Products" Code node
  3. Add entry to PRODUCT_MAP:
'new-product-id': {
  name: 'Product Name',
  pack_type_id: 1,  // 1=Standard, 3=Premium, 8=Team Choice
  packs_per_quantity: 1
}
  1. Save and test

Changing API Endpoints

  1. Edit "Lookup Team API" HTTP Request URL
  2. Edit "Grant Packs" HTTP Request URL
  3. Update "Parse & Validate" API_TOKEN if needed
  4. Test thoroughly before activating

Updating Discord Webhooks

  1. Create new webhook in Discord
  2. Update all Discord HTTP Request node URLs:
    • Discord Success
    • Discord Error
    • Discord Manual Review
    • Discord Thank You
  3. Test each notification type

Rotating Credentials

Ko-fi Token:

  1. Get new token from Ko-fi dashboard
  2. Update in "Parse & Validate" Code node
  3. Test with cURL

Paper Dynasty API Key:

  1. Generate new key in PD admin
  2. Update "Paper Dynasty API" credential in n8n
  3. Test API calls

Future Enhancements

Priority 1 (Next Session)

  • Test Discord user ID → gmid lookup
  • Add Subscription handling
  • Implement currency product logic
  • Test with real Ko-fi purchases

Priority 2 (Nice to Have)

  • Separate Discord channels for different notification types
  • Email notifications for manual reviews
  • Transaction history logging (database or file)
  • Analytics dashboard for pack distributions

Priority 3 (Optimization)

  • Retry logic for failed transactions
  • Batch processing for multiple purchases
  • Scheduled reconciliation job
  • Admin UI for product mapping

Lessons Learned

1. n8n Community vs Enterprise

Community edition is powerful but limited:

  • No custom variables (use hardcoded values in Code nodes)
  • Code nodes can't make HTTP requests (use HTTP Request nodes)
  • Works great for our use case with workarounds

2. Ko-fi Webhook Structure

  • Form-urlencoded with JSON in data field
  • Product codes are internal Ko-fi IDs, not custom
  • shop_items can have multiple items in single order
  • Always validate verification_token

3. Paper Dynasty API Integration

  • Straightforward REST API
  • Expects JSON arrays, not stringified
  • Good error messages
  • Dev environment perfect for testing

4. Discord Webhook Best Practices

  • Always include content field
  • Embeds are great for rich notifications
  • @here mentions work for urgent alerts
  • Test webhooks fail silently if deleted

5. Workflow Development Process

  • Start simple, add complexity gradually
  • Test each node individually
  • Use debug fields (like debug_info) during development
  • Document as you go

Resources

Documentation Created:

  • /productivity/n8n/workflows/kofi-paper-dynasty.md - Original detailed guide
  • /productivity/n8n/workflows/QUICK-START.md - 30-minute setup guide
  • /productivity/n8n/workflows/kofi-testing-guide.md - Testing procedures
  • /productivity/n8n/workflows/kofi-product-mapping-template.json - Product config
  • /productivity/n8n/workflows/kofi-implementation-notes.md - This file

External References:

Test Files:

  • Ko-fi payload structure: /home/cal/Desktop/kofi-integration.md

Change Log

2025-11-13 - Initial Implementation

  • Created complete Ko-fi → Paper Dynasty workflow
  • Working in pddev environment
  • Shop orders fully functional
  • Donation notifications implemented
  • Team identification via message extraction tested
  • Discord notifications for all paths
  • Ready for production deployment

Next Session Goals:

  1. Test Discord user ID lookup
  2. Deploy to production
  3. Make first real Ko-fi purchase
  4. Monitor and iterate

Status: Ready for production deployment