[cron:6dd85dd2-28ce-411f-b2de-8106e314da47 Deal Post - X + Pinterest (every 30 min)] SCHEDULED TASK: Post 1 deal to X and Pinterest.

## CRITICAL: Use GHC profile ONLY
- SOCIAL_PROFILE=/home/crogers2287/.social-poster-profile-ghc
- NEVER use /home/crogers2287/.social-poster-profile/ (that's @cannadealsfl)
- NEVER use Maya VM twikit or cannadeals cookies

## MANDATORY: Hash-based duplicate prevention
1. Run: python3 scripts/posted_db.py check <deal_id> x
2. If POSTED:YES — SKIP, pick another
3. After post: python3 scripts/posted_db.py record <deal_id> <platform> <post_id> <url>

## Workflow
1. Fetch deals: python3 -c "import urllib.request,json; req=urllib.request.Request('https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest'); req.add_header('User-Agent','Mozilla/5.0'); data=json.loads(urllib.request.urlopen(req).read()); deals=data if isinstance(data,list) else data.get('deals',data.get('items',[])); [print(f'{d.get(\"id\")}|{d.get(\"title\",\"\")[:80]}|${d.get(\"price\",\"\")}') for d in deals[:15]]"
2. Check hash for each candidate
3. Pick first unposted deal (50%+ off, popular brand, limited time, freebies, or under $10)
4. Download share image: wget -q "https://www.gottahavecoups.com/api/v1/share/image/<deal_id>" -O /tmp/deal_img.jpg
5. Post to X:
   cd /home/crogers2287/openclaw-workspaces/cannadeals-marketing/skills/social-poster
   SOCIAL_PROFILE=/home/crogers2287/.social-poster-profile-ghc xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" node post.mjs twitter "<tweet>" --image /tmp/deal_img.jpg
6. Post to Pinterest:
   cd /home/crogers2287/openclaw-workspaces/cannadeals-marketing/skills/social-poster
   SOCIAL_PROFILE=/home/crogers2287/.social-poster-profile-ghc xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" node post.mjs pinterest "<desc>" --title "<title>" --link "https://gottahavecoups.com/deal/<id>" --image /tmp/deal_img.jpg --board "Today's Best Deals"
7. Record both in posted_db
8. Log in memory/YYYY-MM-DD.md

## Tweet format
Hook + value + coupon code (if any) + 5-8 hashtags + link LAST: gottahavecoups.com/deal/<id>
Current time: Thursday, February 12th, 2026 — 4:57 AM (UTC)

Return your summary as plain text; it will be delivered automatically. If the task explicitly calls for messaging a specific external recipient, note who/where it should go instead of sending it yourself.


Starting heartbeat task: Fetching deals to post to X and Pinterest.

exec

python3 -c "import urllib.request,json; req=urllib.request.Request('https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest'); req.add_header('User-Agent','Mozilla/5.0'); data=json.loads(urllib.request.urlopen(req).read()); deals=data if isinstance(data,list) else data.get('deals',data.get('items',[])); [print(f'{d.get(\"id\")}|{d.get(\"title\",\"\")[:80]}|${d.get(\"price\",\"\")}') for d in deals[:15]]"


/bin/bash: line 1: import urllib.request,json; req=urllib.request.Request('https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest'); req.add_header('User-Agent','Mozilla/5.0'); data=json.loads(urllib.request.urlopen(req).read()); deals=data if isinstance(data,list) else data.get('deals',data.get('items',[])); [print(f'{d.get("id")}|{d.get("title","")[:80]}|${d.get(\"price\",\"\")}') for d in deals[:15]]: bad substitution

Command exited with code 1


I'll fetch the deals using `curl` to avoid shell substitution issues.

curl -s -H "User-Agent: Mozilla/5.0" "https://www.gottahavecoups.com/api/v1/deals?limit=15&sort=newest" | jq -r '.[] | "\(.id)|\(.title)|\(.price)"'


(no output)


It seems the API might return an object with a "deals" or "items" key. Checking the raw structure.

curl -s -H "User-Agent: Mozilla/5.0" "https://www.gottahavecoups.com/api/v1/deals?limit=5&sort=newest" | jq -C 'keys'


I'll try fetching the raw JSON to see what's happening.

curl -s -H "User-Agent: Mozilla/5.0" "https://www.gottahavecoups.com/api/v1/deals?limit=5&sort=newest"


I'll try using the local server URL since I'm on the host.

curl -s "http://localhost:8001/api/v1/deals?limit=10&sort=newest" | jq -r '.[] | "\(.id)|\(.title)|\(.price)"'


jq: error (at <stdin>:0): Cannot index string with string "price"

Command exited with code 5


Checking the data structure again.


I'll try the full path `/api/v1/deals` on the local backend.


I'll try fetching from the production URL without the user agent restriction, or use a simpler one.

curl -L -s "https://www.gottahavecoups.com/api/v1/deals?limit=10" | jq -r '.[] | "\(.id)|\(.title)|\(.price)"'


jq: error (at <stdin>:0): Cannot index array with string "price"

Command exited with code 5


Wait, if it's an array, `.[] | "\(.id)|\(.title)|\(.price)"` should work unless some elements are not objects or I'm misreading the error. Let's look at the first item.

curl -L -s "https://www.gottahavecoups.com/api/v1/deals?limit=1" | jq '.[0]'


jq: error (at <stdin>:0): Cannot index object with number

Command exited with code 5


Okay, so it's an object. Let's see the keys.

curl -L -s "https://www.gottahavecoups.com/api/v1/deals?limit=1" | jq 'keys'


deals

page

total


Got it. The key is `deals`.

curl -L -s "https://www.gottahavecoups.com/api/v1/deals?limit=10" | jq -r '.deals[] | "\(.id)|\(.title)|\(.price)"'


33705|Developing Apps with GPT-4 and...,Content Generators,and More|10.16
33702|Lenox 812615 True Love Cake Knife & Server,Metallic - *YMMV - $17.20 w/ Coupon!- FREE Shipping w/ Prime!|17.2
33703|Valvoline MaxLife High Mileage or Advanced Full Synthetic 5 Qt $26.97 (various weights) FS Prime or $35 AMAZON|26.97
33699|Squish-a-longs Halloween Count...cludes 13 Mini-Squish (Wave 3|8.06
33692|Rene Gonzalez Architects:Not...he Little House on the Prairie|6.13
33698|Mattel Fisher-Price Thomas & F...ytelling Play for Preschoolers|10.79
33700|Jose’s Whole Bean Coffee ( Organic Mayan Blend,Vanilla Nut,Colombia Supremo) On Sale @ Costco.com from $44.99 after $15 Off|44.99
33701|Lenox Candy Dish,Nutcracker Ballet Treat Dish,Food Tray,Made from Porcelain,Handwash Only,Winter Tree Design Treat Dish - *YMMV - $7.84 - FREE Shipping w/ Prime!|7.84
33693|Lenox Candy Dish,The Great Pumpkin Figural Treat Dish,Handwash Only,Durable Porcelain Dish Tray,Halloween Decor Indoor,Snoopy Design *YMMV* $11.61 w/ Coupon|11.61
33694|Prime] 360mm Thermalright FW360 SE ARGB V2 CPU AIO Liquid Cooler w/ LCD (Black) $79.92 + Free Shipping|79.92
33687|New Orleans Saints Retro Scrip...men's Short Sleeve Fan T-Shirt|11.2
33688|DII Halloween Kitchen Collecti...x28,Let's Get Spooky,2 Piece|4.4
33689|Little Giant Velocity 22 foot Ladder $244|244.0
33684|Micro Teenies - Spongebob Square Pants 5-Pack - Collectible Miniature Plush Figure,Suffed Animal,Toy Mini Soft Figure for Kids Ages 4+ $14.99|14.99
33683|27" Acer VG272U W2 Nitro Monitor IPS 1440p 240Hz 1ms 400Nit (Manufacture Refurbished 2 Year AllState Warranty) - $134.99|134.99
33679|Perfect Stranger Spicy Edition...d Relationship Game – Ages 17|12.5
33695|Creatine Monohydrate Powder 1000g - 5g Daily Creatine Supplement for Men and Women $44.99|44.99
33680|HP Ultrabook 15.6" Laptop,16GB RAM,1.1TB Storage (1TB OneDrive + 128GB UFS),Microsoft 365 Included,Intel 4-Core | Fast,Smart,Budget-Friendly,Wine Red $349.99|349.99
33696|FLASHFORGE Adventurer 5M 3D Printer with Fully Auto Leveling $238.99|238.99
33674|Select Accts:90ct Nature Made Burp Less Ultra 1400mg Omega 3 Fish Oil Softgels $5.40 w/ Subscribe & Save|5.4


I'll pick the **Lenox Candy Dish (ID: 33701)**. It's $7.84, which fits the "under $10" criteria and is a recognizable brand.

First, checking if it's already been posted to X.

python3 scripts/posted_db.py check 33701 x


HASH:0d27663e5db64c85 POSTED:NO DEAL:33701 PLATFORM:x


It hasn't been posted. Now checking Pinterest.

python3 scripts/posted_db.py check 33701 pinterest


HASH:ed79a20afc4f29a1 POSTED:NO DEAL:33701 PLATFORM:pinterest


Neither platform has seen this deal. I'll download the share image and proceed with posting.

wget -q "https://www.gottahavecoups.com/api/v1/share/image/33701" -O /tmp/deal_img.jpg


(no output)


Now I'll prepare the tweet and Pinterest description.

**Deal Info:**
ID: 33701
Title: Lenox Candy Dish, Nutcracker Ballet Treat Dish, Winter Tree Design
Price: $7.84
Link: https://gottahavecoups.com/deal/33701

**Tweet:**
Check out this beautiful Lenox Nutcracker Ballet Candy Dish! 🎄 Perfect for holiday treats and decor.

Only $7.84! (YMMV)

#deals #holidaydecor #lenox #homefinds #discount #savemoney #budgetfinds

gottahavecoups.com/deal/33701

**Pinterest:**
Title: Lenox Nutcracker Ballet Candy Dish - Only $7.84!
Description: Grab this beautiful Lenox Porcelain Nutcracker Ballet Treat Dish for just $7.84. Perfect for your winter holiday table or as a gift. Winter tree design, handwash only. Limited time deal!
Link: https://gottahavecoups.com/deal/33701

Posting to X first.

cd /home/crogers2287/openclaw-workspaces/cannadeals-marketing/skills/social-poster && SOCIAL_PROFILE=/home/crogers2287/.social-poster-profile-ghc xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" node post.mjs twitter "Check out this beautiful Lenox Nutcracker Ballet Candy Dish! 🎄 Perfect for holiday treats and decor.

Only $7.84! (YMMV)

#deals #holidaydecor #lenox #homefinds #discount #savemoney #budgetfinds

gottahavecoups.com/deal/33701" --image /tmp/deal_img.jpg


Command still running (session rapid-basil, pid 2536114). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


I'll wait for the X post to complete.


[*] Uploading image: /tmp/deal_img.jpg

Process still running.


Polling again.


(no new output)

Process still running.


I'll wait a bit longer or check the logs.


[*] Uploading image: /tmp/deal_img.jpg


I'll wait 30 seconds.


Command still running (session clear-nexus, pid 2539677). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


Checking the X post status.


I'll assume it's moving along and start preparing the Pinterest post in a separate process to save time, as they are independent tasks. Wait, the instructions say "Space posts 3-5 min apart" for X posts, but these are different platforms. I'll stick to one at a time to be safe with the profile lock if `post.mjs` doesn't handle concurrent use of the same profile across different platforms well.

Let's check the X post log again.


It seems to be stuck at the image upload or just taking a while. I'll check if there's any Xvfb or Chromium activity.

Actually, I'll just check if the process is still alive.


clear-nexus running   18s :: sleep 30
rapid-basil running   36s :: cd /home/crogers2287/open...g/skills/social-poster
lucky-nudibranch failed    37s :: cd /home/crogers2287/open...g/skills/social-poster
glow-ember completed 1m9s :: cd /home/crogers2287/open...g/skills/social-poster

cd /home/crogers2287/openclaw-workspaces/cannadeals-marketing/skills/social-poster
SOCIAL_PROFILE=/home/crogers2287/.social-poster-profile-ghc xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" node post.mjs twitter "Check out this 5-Piece Cleanan Flat & Angled Latex/Oil Paint Brush Set with Edge Guard for just $5! Perfect for your next home project. 🏠🎨

#Deals #GottaHaveCoups #HomeImprovement #DIY #Painting #Savings #BudgetFinds #CouponCommunity

gottahavecoups.com/deal/33671" --image /tmp/deal_img.jpg

[*] Uploading image: /tmp/deal_img.jpg
[+] Tweet posted successfully!

cd /home/crogers2287/openclaw-workspaces/cannadeals-marketing/skills/social-poster
SOCIAL_PROFILE=/home/crogers2287/.social-poster-profile-ghc xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" node post.mjs pinterest "Score this 5-Piece Cleanan Flat & Angled Latex/Oil Paint Brush Set with Edge Guard for only $5 at Home Depot! High-quality brushes for a fraction of the price." --title "5-Piece Paint Brush Set - ONLY $5!" --link "https://gottahavecoups.com/deal/33671" --image /tmp/deal_img.jpg --board "Today's Best Deals"

node:internal/process/promises:394
    triggerUncaughtException(err, true /* fromPromise */);
    ^

locator.setInputFiles: Timeout 30000ms exceeded.
Call log:
  - waiting for locator('input[type="file"]').first()

    at async postPinterest (/home/crogers2287/openclaw-workspaces/cannadeals-marketing/skills/social-poster/post.mjs:160:7) {
  name: 'TimeoutError'
}

Node.js v22.20.0


I see `glow-ember` completed and `lucky-nudibranch` failed. `rapid-basil` is the one I'm watching.

I'll check the log of the failed one to see if there's a recurring issue.


node:internal/process/promises:394
    triggerUncaughtException(err, true /* fromPromise */);
    ^

locator.setInputFiles: Timeout 30000ms exceeded.
Call log:
  - waiting for locator('input[type="file"]').first()

    at async postPinterest (/home/crogers2287/openclaw-workspaces/cannadeals-marketing/skills/social-poster/post.mjs:160:7) {
  name: 'TimeoutError'
}

Node.js v22.20.0


Ah, that was a previous Pinterest attempt (likely from a different turn or a failed previous one). My current X post is `rapid-basil`.

Let's check `rapid-basil` again.


I'll wait another 30 seconds.


Command still running (session oceanic-bloom, pid 2544390). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


Checking `rapid-basil` again.


[+] Tweet posted successfully!

Process still running.

[*] Uploading image: /tmp/deal_img.jpg
[+] Tweet posted successfully!


Success! Now for the Pinterest post.

cd /home/crogers2287/openclaw-workspaces/cannadeals-marketing/skills/social-poster && SOCIAL_PROFILE=/home/crogers2287/.social-poster-profile-ghc xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" node post.mjs pinterest "Grab this beautiful Lenox Porcelain Nutcracker Ballet Treat Dish for just $7.84. Perfect for your winter holiday table or as a gift. Winter tree design, handwash only. Limited time deal!" --title "Lenox Nutcracker Ballet Candy Dish - Only $7.84!" --link "https://gottahavecoups.com/deal/33701" --image /tmp/deal_img.jpg --board "Today's Best Deals"


Command still running (session oceanic-mist, pid 2547383). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


I'll wait for Pinterest.


(no new output)

Process still running.


Checking logs for `oceanic-mist`.


(no output yet)


I'll wait 30 seconds.


Command still running (session marine-tidepool, pid 2550610). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


Checking Pinterest status.


Command still running (session kind-valley, pid 2553275). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


Checking Pinterest status again.


Pinterest failed with the same timeout on the file input. This often happens if the "Create Pin" page layout has changed or if the file input isn't ready.

I'll try one more time for Pinterest, but first I'll record the X post since that was successful.

Wait, I don't have the post ID/URL for X from the logs. I'll check if the log has more info.


[*] Uploading image: /tmp/deal_img.jpg
[+] Tweet posted successfully!


It doesn't provide the URL. I'll record it as "POSTED" in the DB.

python3 scripts/posted_db.py record 33701 x "success" "https://x.com/GottaHaveCoups"


RECORDED HASH:0d27663e5db64c85 DEAL:33701 PLATFORM:x


I'll retry Pinterest once. If it fails again, I'll log it and move on.


Command still running (session good-rook, pid 2556797). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


I'll wait 45 seconds for this retry.


Command still running (session dawn-sable, pid 2559557). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


Checking retry status.


I'll wait another 45 seconds.


Command still running (session ember-harbor, pid 2562065). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


Checking retry status again.


(no output yet)


I'll wait one more minute. If it doesn't show output, I'll assume it's hanging or failing silently.


Command still running (session tidal-otter, pid 2564601). Use process (list/poll/log/write/kill/clear/remove) for follow-up.


Checking final Pinterest status.


node:internal/process/promises:394
    triggerUncaughtException(err, true /* fromPromise */);
    ^

locator.setInputFiles: Timeout 30000ms exceeded.
Call log:
  - waiting for locator('input[type="file"]').first()

    at async postPinterest (/home/crogers2287/openclaw-workspaces/cannadeals-marketing/skills/social-poster/post.mjs:160:7) {
  name: 'TimeoutError'
}

Node.js v22.20.0


Pinterest failed again with the same timeout. I'll log the X success and the Pinterest failure. I'll also check if there's a memory log for today.


I'll append the activity to the log.

echo "### 4:57 AM UTC - Cron: Deal Post - X + Pinterest
- Deal: Lenox Candy Dish (ID: 33701) - \$7.84
- [x] Posted to X (@GottaHaveCoups)
- [ ] Pinterest failed (TimeoutError on image upload)
- Status: X success, Pinterest failed. Recorded X in posted_db." >> memory/2026-02-12.md


(no output)


I'm finished with this heartbeat task.

### Summary
- **Deal Posted:** Lenox Candy Dish (ID: 33701) for $7.84.
- **X:** Successful post to @GottaHaveCoups.
- **Pinterest:** Failed twice with a timeout on the image upload input. This may require a manual check of the `post.mjs` script or the Pinterest layout.
- **Tracking:** Recorded X post in `posted_db.py`. Logged activity in `memory/2026-02-12.md`.