Create instagram-automation-session-notes.md via n8n
This commit is contained in:
parent
dfbabd73ed
commit
6f81771dd8
165
PBS/Tech/Sessions/instagram-automation-session-notes.md
Normal file
165
PBS/Tech/Sessions/instagram-automation-session-notes.md
Normal file
@ -0,0 +1,165 @@
|
||||
---
|
||||
project: instagram-automation-session-notes
|
||||
type: session-notes
|
||||
status: active
|
||||
tags:
|
||||
- pbs
|
||||
- n8n
|
||||
- instagram
|
||||
- mysql
|
||||
- wordpress
|
||||
- automation
|
||||
- docker
|
||||
created: 2026-03-16
|
||||
updated: 2026-03-16
|
||||
path: PBS/Tech/Sessions/
|
||||
---
|
||||
|
||||
# Session Notes — MySQL Schema, Error Checking & The Great Lockout of 2026
|
||||
|
||||
## ✅ Accomplished This Session
|
||||
|
||||
### Error Checking — Instagram Reply Workflow
|
||||
All four error checks are now wired to Notify Travis → Google Chat:
|
||||
|
||||
- ✅ Subscribe check notification
|
||||
- ✅ Hash verification failure notification (with ⛔ alert level)
|
||||
- ✅ Empty table lookup notification (includes Reel ID, commenter, comment text)
|
||||
- ✅ Keyword not matched notification
|
||||
|
||||
**Key learnings:**
|
||||
- n8n "Always Output Data" needed on MySQL node so IF node can evaluate empty results
|
||||
- When "Always Output Data" is on, check `$('node').first().json.id` exists instead of `length > 0` (length returns 1 for empty item)
|
||||
- Google Chat HTTP Request node must use "Using Fields Below" mode, not raw JSON — literal newlines from expressions break JSON
|
||||
- Build message strings as single `={{ }}` expression using `+` concatenation to keep `\n` as escaped characters
|
||||
- `$now.toFormat('MMM dd, HH:mm:ss')` works in both test and live contexts (unlike `$execution.startedAt`)
|
||||
- Timestamp and title passed from calling workflow, Notify Travis just passes them through
|
||||
|
||||
---
|
||||
|
||||
### MySQL Schema — New Tables Created
|
||||
|
||||
**`pbs_recipes`:**
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS pbs_recipes (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
post_id BIGINT UNSIGNED NOT NULL,
|
||||
title VARCHAR(500) NOT NULL,
|
||||
url VARCHAR(500) NOT NULL,
|
||||
keyword VARCHAR(100) NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (post_id)
|
||||
);
|
||||
```
|
||||
|
||||
**`instagram_posts`:**
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS instagram_posts (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
reel_id VARCHAR(50) NOT NULL,
|
||||
post_id BIGINT UNSIGNED NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (reel_id),
|
||||
FOREIGN KEY (post_id) REFERENCES pbs_recipes(post_id)
|
||||
);
|
||||
```
|
||||
|
||||
**Key decisions:**
|
||||
- `post_id` is nullable in `instagram_posts` — NULL means unmatched reel, not an error
|
||||
- `reel_id` stored as VARCHAR not BIGINT (Instagram ID integer overflow issue)
|
||||
- Normalized schema — keyword and URL live in `pbs_recipes` only, JOIN at query time
|
||||
- Staying on shared MySQL instance — at current scale (2k/month, 10-20 replies) separate instance is overkill
|
||||
- phpMyAdmin added back to Docker Compose for direct MySQL access
|
||||
|
||||
---
|
||||
|
||||
### WordPress Publish Webhook — Proof of Concept Complete
|
||||
- WPCode Lite snippet fires on post publish (admin only)
|
||||
- Payload: post_id, title, url, tags, categories
|
||||
- HMAC signature verification via X-PBS-Signature header
|
||||
- Raw body passed via X-PBS-Body header (base64 encoded) for exact signature verification
|
||||
- n8n Code node verifies signature before processing
|
||||
- Ready to wire into `pbs_recipes` table insert workflow
|
||||
|
||||
---
|
||||
|
||||
### Architecture Decision — Reply Workflow Refactor
|
||||
Current two-table lookup + merge is being replaced with:
|
||||
- Single `instagram_posts` lookup only
|
||||
- URL stored directly in `instagram_posts` (populated at reel insert time from `pbs_recipes`)
|
||||
- Simpler, faster, fewer failure points
|
||||
|
||||
---
|
||||
|
||||
## 🔧 The Great WordPress Lockout of 2026
|
||||
|
||||
**What happened:** Wordfence locked out staging WP admin. Unlock email never arrived.
|
||||
|
||||
**What we tried (none of it worked):**
|
||||
- WP-CLI wf:unblock-ip command (not a registered command)
|
||||
- Clearing wp_options Wordfence entries in MySQL
|
||||
- Disabling Wordfence plugin
|
||||
- Restarting WordPress container
|
||||
- Deleting wflogs directory
|
||||
|
||||
**Root cause discovered:**
|
||||
Wordfence WAF runs as a PHP auto_prepend_file — completely independent of the plugin being active. Found in .htaccess and wordfence-waf.php in WordPress root.
|
||||
|
||||
**Actual fix:** Wrong email address on the admin account. Changed it, logged right in. 🤦
|
||||
|
||||
**Real lesson learned:** Read the error message carefully before spending an hour troubleshooting! 😄
|
||||
|
||||
**Lockout duration if we hadn't figured it out:** 1 MONTH
|
||||
|
||||
---
|
||||
|
||||
## 📋 Runbook Addition — WordPress Lockout Recovery
|
||||
|
||||
```bash
|
||||
# Get into WordPress container
|
||||
docker exec -it wordpress bash
|
||||
cd /var/www/html
|
||||
|
||||
# List all users
|
||||
wp --allow-root user list
|
||||
|
||||
# Reset password by username
|
||||
wp --allow-root user update admin --user_pass=newpassword
|
||||
|
||||
# Reset password by email
|
||||
wp --allow-root user update user@email.com --user_pass=newpassword
|
||||
|
||||
# If WAF is blocking login page independently of plugin:
|
||||
# 1. Remove Wordfence WAF block from .htaccess
|
||||
# 2. Rename wordfence-waf.php to wordfence-waf.php.disabled
|
||||
# 3. docker restart wordpress
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔜 Next Steps
|
||||
|
||||
- [ ] Wire WordPress publish webhook → n8n workflow → insert into `pbs_recipes`
|
||||
- [ ] Build one-time migration workflow — n8n datatables → MySQL
|
||||
- [ ] Finish reply workflow refactor — remove Merge node, single `instagram_posts` lookup
|
||||
- [ ] Fix production WordPress admin email (same issue exists there!)
|
||||
- [ ] Deploy all changes to production once staging is verified
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- All development on staging (staging.plantbasedsoutherner.com)
|
||||
- n8n datatables to be retired once MySQL migration complete
|
||||
- Foreign key constraint requires `pbs_recipes` record to exist before `instagram_posts` insert
|
||||
- Use `WHERE post_id IS NULL` query to find unmatched reels for Content Hub dashboard
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: March 16, 2026*
|
||||
*Maintained by: Travis*
|
||||
*Project: Plant Based Southerner — Instagram Automation*
|
||||
Loading…
Reference in New Issue
Block a user