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

463 lines
14 KiB
Markdown

# 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):**
```javascript
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:
```bash
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:**
```json
{
"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
```bash
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`:
```javascript
'new-product-id': {
name: 'Product Name',
pack_type_id: 1, // 1=Standard, 3=Premium, 8=Team Choice
packs_per_quantity: 1
}
```
4. 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:**
- 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:**
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