- 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>
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:
- Extract Team Abbrev (Code) - Regex extraction only
- Lookup Team API (HTTP Request) - API call to PD
- 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 is61de350207- 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
-
Paper Dynasty API (Header Auth)
- Header:
Authorization - Value:
Bearer Tp3aO3jhYve5NJF1IqOmJTmk
- Header:
-
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
- Change from
-
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:
- Verify workflow is Active (green toggle)
- Check webhook path matches Ko-fi configuration
- Test with cURL to isolate issue
- 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:
- Verify token in Code node matches Ko-fi dashboard exactly
- Check for extra spaces or quotes
- Re-copy token from Ko-fi
Team Not Found
Symptoms: Workflow takes "Team Found? False" path Solutions:
- Check message field has valid team abbrev (2-4 uppercase letters)
- Test API directly:
curl -H "Authorization: Bearer TOKEN" "URL/teams?abbrev=SKB" - Verify team exists in target environment (pddev vs prod)
API Call Failing
Symptoms: "API Success?" takes False path Solutions:
- Check HTTP Request body format (no JSON.stringify, no = prefix)
- Verify
pack_requestsis an array in "Map Products" output - Check API credentials are correct
- Review full error in node execution data
Discord Notification Not Sending
Symptoms: No Discord message received Solutions:
- Verify webhook URL is correct
- Test webhook directly with cURL
- Check body has
contentfield (required even with embeds) - Verify Discord channel hasn't deleted the webhook
Unknown Product Code
Symptoms: unknown_products array has items, takes manual review path
Solutions:
- Check Ko-fi product ID matches
PRODUCT_MAPkeys - Get product ID from Ko-fi product URL:
/s/{ID} - Add new product to PRODUCT_MAP in "Map Products" code
Maintenance Tasks
Adding New Products
- Get Ko-fi product ID from product URL
- Edit "Map Products" Code node
- 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
}
- Save and test
Changing API Endpoints
- Edit "Lookup Team API" HTTP Request URL
- Edit "Grant Packs" HTTP Request URL
- Update "Parse & Validate" API_TOKEN if needed
- Test thoroughly before activating
Updating Discord Webhooks
- Create new webhook in Discord
- Update all Discord HTTP Request node URLs:
- Discord Success
- Discord Error
- Discord Manual Review
- Discord Thank You
- Test each notification type
Rotating Credentials
Ko-fi Token:
- Get new token from Ko-fi dashboard
- Update in "Parse & Validate" Code node
- Test with cURL
Paper Dynasty API Key:
- Generate new key in PD admin
- Update "Paper Dynasty API" credential in n8n
- 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
datafield - Product codes are internal Ko-fi IDs, not custom
shop_itemscan 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
contentfield - 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:
- Ko-fi Webhook Docs: https://help.ko-fi.com/hc/en-us/articles/360004162298
- n8n Documentation: https://docs.n8n.io/
- Paper Dynasty API: See
/home/cal/.claude/skills/paper-dynasty/SKILL.md
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:
- Test Discord user ID lookup
- Deploy to production
- Make first real Ko-fi purchase
- Monitor and iterate
Status: ✅ Ready for production deployment