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

## CRITICAL: Use Maya VM, NOT Fred social-poster
- X: twikit v2.3.3 on Maya VM (`ssh maya@maya`)
- Script: `/home/maya/workspace/scripts/x_twikit_post2.py`
- Cookies: `/home/maya/workspace/x_cookies.json`

## Workflow
1. Fetch deals: `curl -s "https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest" | python3 -c "import sys,json; d=json.load(sys.stdin); deals=d if isinstance(d,list) else d.get('deals',[]); [print(f\"{x['id']}|{x.get('title','')[:60]}|${x.get('price','')}|{x.get('discount_percentage',0)}%\") for x in deals[:15]]"`
2. Check hash: `python3 scripts/posted_db.py check <deal_id> x`
3. If POSTED:YES — SKIP, pick another
4. Pick unposted deal (50%+ off, popular brand, limited time, freebies, under $10)
5. Download share image: `wget -q "https://www.gottahavecoups.com/api/v1/share/image/<deal_id>" -O /tmp/deal_img.jpg`
6. **BUILD TWEET:** Hook + value + 5-8 hashtags + link LAST. KEEP UNDER 280 CHARS.
7. **MANDATORY VALIDATION:** `python3 scripts/validate_tweet.py '<tweet_text>'` — If INVALID, STOP and pick different deal.
8. **POST TO X (Maya VM twikit):**
   ```bash
   ssh maya@maya "cat > /tmp/tweet.txt << 'TWEET'
   <tweet text here>
   TWEET"
   scp /tmp/deal_img.jpg maya@maya:/tmp/deal_img.jpg
   ssh maya@maya "python3 /home/maya/workspace/scripts/x_twikit_post2.py <deal_id> --file /tmp/tweet.txt"
   ```
9. **POST TO PINTEREST (Maya VM py3-pinterest):**
   ```bash
   ssh maya@maya "python3 /home/maya/workspace/scripts/pin_post_v2.py <deal_id> '<title>' '<description>' 1134485031073239531"
   ```
10. Record posts: `python3 scripts/posted_db.py record <deal_id> x <tweet_id> <url>`
11. Log in memory/YYYY-MM-DD.md

## If X cookies expired
Run: `ssh maya@maya "DISPLAY=:0 python3 /home/maya/workspace/scripts/extract_x_cookies.py"`

## Tweet format (STRICT)
- Hook (emoji + deal highlight)
- Product name + price (with $, e.g., "$12.99")
- 5-8 hashtags
- Link LAST: gottahavecoups.com/deal/<id>
- KEEP UNDER 280 CHARS

## NEVER post if validation fails:
- Shell artifacts (/bin/bash, python3 -c)
- Broken prices (.20 instead of $10.20)
- Broken emojis (�)
- > 280 chars
Current time: Friday, February 13th, 2026 — 1:27 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.


The user wants me to execute a scheduled cron task to post a deal to X (Twitter) and Pinterest. Let me follow the workflow step by step.

First, I need to:
1. Fetch deals from the API
2. Check which ones haven't been posted yet
3. Pick a good deal (50%+ off, popular brand, etc.)
4. Download the share image
5. Build a tweet under 280 chars
6. Validate the tweet
7. Post to X using Maya VM
8. Post to Pinterest using Maya VM
9. Record the posts

Let me start by fetching the deals.

I'll execute this scheduled deal post. Let me work through the workflow step by step.

exec

curl -s "https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest" | python3 -c "import sys,json; d=json.load(sys.stdin); deals=d if isinstance(d,list) else d.get('deals',[]); [print(f\"{x['id']}|{x.get('title','')[:60]}|${x.get('price','')}|{x.get('discount_percentage',0)}%\") for x in deals[:15]]"


/bin/bash: line 1: import sys,json; d=json.load(sys.stdin); deals=d if isinstance(d,list) else d.get('deals',[]); [print(f"{x['id']}|{x.get('title','')[:60]}|${x.get('price','')}|{x.get('discount_percentage',0)}%") for x in deals[:15]]: bad substitution

Command exited with code 1


The command failed due to quote escaping issues. Let me try a different approach - save the Python script to a file first, then run it.

Let me fix the command escaping:

curl -s "https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest" -o /tmp/deals.json && python3 -c "
import sys,json
d=json.load(open('/tmp/deals.json'))
deals=d if isinstance(d,list) else d.get('deals',[])
for x in deals[:15]:
    print(f\"{x['id']}|{x.get('title','')[:60]}|${x.get('price','')}|{x.get('discount_percentage',0)}%\")
"


/bin/bash: line 1:
import sys,json
d=json.load(open('/tmp/deals.json'))
deals=d if isinstance(d,list) else d.get('deals',[])
for x in deals[:15]:
    print(f"{x['id']}|{x.get('title','')[:60]}|${x.get('price','')}|{x.get('discount_percentage',0)}%")
: bad substitution

Command exited with code 1


The multiline command isn't working well. Let me write the Python script to a file first, then execute it.

write

import sys,json
d=json.load(open('/tmp/deals.json'))
deals=d if isinstance(d,list) else d.get('deals',[])
for x in deals[:15]:
    print(f"{x['id']}|{x.get('title','')[:60]}|${x.get('price','')}|{x.get('discount_percentage',0)}%")


Successfully wrote 231 bytes to /tmp/parse_deals.py


Now let me fetch the deals and parse them.

exec

curl -s "https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest" -o /tmp/deals.json && python3 /tmp/parse_deals.py


Traceback (most recent call last):
  File "/tmp/parse_deals.py", line 2, in <module>
    d=json.load(open('/tmp/deals.json'))
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/__init__.py", line 293, in load
    return loads(fp.read(),
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Command exited with code 1


The curl command returned empty. Let me check what the actual response is.

curl -s "https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest" | head -c 500


(no output)


The API seems to be returning empty. Let me check if the site is accessible at all.

curl -v "https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest" 2>&1 | head -50


% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Host www.gottahavecoups.com:443 was resolved.
* IPv6: 2606:4700:3037::6815:441e, 2606:4700:3033::ac43:b9d7
* IPv4: 104.21.68.30, 172.67.185.215
*   Trying 104.21.68.30:443...
* Connected to www.gottahavecoups.com (104.21.68.30) port 443
* ALPN: curl offers h2,http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [19 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2548 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [80 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519 / id-ecPublicKey
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=gottahavecoups.com
*  start date: Jan 24 01:17:46 2026 GMT
*  expire date: Apr 24 02:16:10 2026 GMT
*  subjectAltName: host "www.gottahavecoups.com" matched cert's "*.gottahavecoups.com"
*  issuer: C=US; O=Google Trust Services; CN=WE1
*  SSL certificate verify ok.
*   Certificate level 0: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA256
*   Certificate level 1: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA384
*   Certificate level 2: Public key type EC/secp384r1 (384/192 Bits/secBits), signed using ecdsa-with-SHA384
} [5 bytes data]
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: www.gottahavecoups.com]
* [HTTP/2] [1] [:path: /api/v1/deals?limit=20&sort=newest]
* [HTTP/2] [1] [user-agent: curl/8.5.0]
* [HTTP/2] [1] [accept: */*]
} [5 bytes data]


The connection is happening but the output seems to be empty. Let me wait for the full output and check the HTTP response code.

curl -s -w "\nHTTP_CODE:%{http_code}" "https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest" 2>&1


Ah, it's returning a 307 redirect. Let me follow the redirect with -L flag.

curl -s -L "https://www.gottahavecoups.com/api/v1/deals?limit=20&sort=newest" -o /tmp/deals.json && cat /tmp/deals.json | head -c 1000


{"deals":[{"title":"Anderson Metals - 56121-08 561...Head Plug,1/2\" NPT Male Pipe","description":"Amazon price drop:Anderson Metals - 56121-08 561...Head Plug,1/2\" NPT Male Pipe - down 39.51% ($1.79) to $2.74 from $4.53","price":2.74,"original_price":4.53,"discount_percentage":39,"deal_url":"https://camelcamelcamel.com/product/B000BOCA5S","affiliate_link":"https://www.amazon.com/dp/B000BOCA5S?tag=chelseaschn0b-20","coupon_code":null,"image_url":"https://www.gottahavecoups.com/api/v1/deal-images/734da061ac252128.jpg","thumbnail_url":null,"category_id":2,"store_name":"Amazon","brand":null,"retailer_links":null,"id":33923,"quality_score":7.0,"source":"Amazon","feed_name":"CamelCamelCamel","is_active":true,"is_featured":false,"is_hot":true,"is_limited_time":false,"views_count":1,"clicks_count":0,"saves_count":0,"expires_at":null,"published_at":null,"created_at":"2026-02-13T01:20:00.713201Z","updated_at":"2026-02-13T01:26:36.033146Z","savings":1.79,"featured_categories":null},{"title":"Ma


The API is working now with the -L flag. Let me parse the deals properly.


33923|Anderson Metals - 56121-08 561...Head Plug,1/2" NPT Male Pip|$2.74|39%
33924|Maille Pickles Cornichons Orig...king Product of France 13.5|$4.79|36%
33910|Louisville Ladder AE3228 Exten...LP-2200-00 Stabilizer,Silve|$354.85|42%
33928|Philips Avent Soothie Baby Pac...Green,4 Pack,Model SCF192/4|$6.79|42%
33929|Creative Co-Op Heavily Distres...al Tray with Black Frame & |$19.99|35%
33914|The Annotated Little Women (The Annotated Books Book 0|$2.99|76%
33922|Lucky Seed:A Novel|$15.0|39%
33930|Classic Accessories Terrazzo R...Table & Chair Set Cover,Lar|$34.18|51%
33926|Zaffi Taffy Sugar Free Candy -...s (Natural Fruit Flavor,3 o|$3.22|53%
33931|TABASCO Brand Cayenne Garlic Pepper Sauce,Mild Hot Sauce,Gla|$4.98|None%
33912|Easy-Going Fleece Stretch Chair Slipcover Coffee $15.59|$15.59|40%
33915|Select Stores:RIDGID 18V Cordless Reciprocating Saw w/ 4.0 A|$65.05|None%
33916|Costco Members:Dynamic Toscana Elite 3-Person Ultra Low EMF |$2000.0|None%
33917|3.4-oz Gucci Bloom for Women Eau de Parfum Spray $70 + Free |$70.0|None%
33921|15" Sanrio Kids Cloud Pillows:Kuromi,Cinnamoroll,Badtz Maru |$10.0|None%


Now I have the deals. Let me check which ones haven't been posted yet. I'll check each deal ID against the posted_db.py.

Now let me check which deals haven't been posted to X yet:


33923: POSTED:NO
33924: POSTED:NO
33910: POSTED:NO
33928: POSTED:NO
33929: POSTED:NO
33914: POSTED:NO
33922: POSTED:NO
33930: POSTED:NO
33926: POSTED:NO
33931: POSTED:NO


Good, none of these have been posted yet. Now I need to pick a good deal. Looking at the options:
- 33914: The Annotated Little Women - $2.99, 76% off - Great discount!
- 33930: Terrazzo Table & Chair Set Cover - $34.18, 51% off
- 33926: Zaffi Taffy Sugar Free Candy - $3.22, 53% off

Let me look at the full details of these promising deals. The Little Women book at 76% off for $2.99 is a great deal - books under $5 with high discounts tend to do well.

Let me look at the most promising deals (50%+ off):

python3 -c "
import json
d=json.load(open('/tmp/deals.json'))
deals=d if isinstance(d,list) else d.get('deals',[])
for x in deals:
    dp = x.get('discount_percentage',0) or 0
    if dp >= 50:
        print(f\"ID: {x['id']}\")
        print(f\"Title: {x['title']}\")
        print(f\"Price: ${x.get('price','')}\")
        print(f\"Discount: {dp}%\")
        print(f\"Store: {x.get('store_name','')}\")
        print('---')
"


/bin/bash: line 1:
import json
d=json.load(open('/tmp/deals.json'))
deals=d if isinstance(d,list) else d.get('deals',[])
for x in deals:
    dp = x.get('discount_percentage',0) or 0
    if dp >= 50:
        print(f"ID: {x['id']}")
        print(f"Title: {x['title']}")
        print(f"Price: ${x.get('price','')}")
        print(f"Discount: {dp}%")
        print(f"Store: {x.get('store_name','')}")
        print('---')
: bad substitution

Command exited with code 1


write

import json
d=json.load(open('/tmp/deals.json'))
deals=d if isinstance(d,list) else d.get('deals',[])
for x in deals:
    dp = x.get('discount_percentage',0) or 0
    if dp >= 50:
        print(f"ID: {x['id']}")
        print(f"Title: {x['title']}")
        print(f"Price: ${x.get('price','')}")
        print(f"Discount: {dp}%")
        print(f"Store: {x.get('store_name','')}")
        print('---')


Successfully wrote 401 bytes to /tmp/filter_deals.py


Now let me run it to see the 50%+ off deals.


ID: 33914
Title: The Annotated Little Women (The Annotated Books Book 0
Price: $2.99
Discount: 76%
Store: Amazon
---
ID: 33930
Title: Classic Accessories Terrazzo R...Table & Chair Set Cover,Large
Price: $34.18
Discount: 51%
Store: Amazon
---
ID: 33926
Title: Zaffi Taffy Sugar Free Candy -...s (Natural Fruit Flavor,3 oz
Price: $3.22
Discount: 53%
Store: Amazon
---


The Annotated Little Women at $2.99 (76% off) is the best deal here - books under $5 with high discounts are very appealing. Let me get the full details and download the share image.

I'll go with **The Annotated Little Women** - 76% off at $2.99 is a fantastic deal on a classic book. Let me get the full details:

exec

python3 -c "
import json
d=json.load(open('/tmp/deals.json'))
deals=d if isinstance(d,list) else d.get('deals',[])
for x in deals:
    if x['id'] == 33914:
        print(json.dumps(x, indent=2))
"


Amazon price drop:The Annotated Little Women (The Annotated Books Book 0) - down 76.98% ($10.00) to $2.99 from $12.99


Perfect! This is a great deal - The Annotated Little Women at $2.99 (was $12.99, 76% off). Quality score 10, featured and hot. Now I need to:
1. Download the share image
2. Build a tweet under 280 chars
3. Validate it
4. Post to X via Maya VM
5. Post to Pinterest via Maya VM
6. Record the post

Excellent! Quality score 10, featured & hot deal. Now downloading the share image:

wget -q "https://www.gottahavecoups.com/api/v1/share/image/33914" -O /tmp/deal_img.jpg && ls -la /tmp/deal_img.jpg


-rw-rw-r-- 1 crogers2287 crogers2287 137345 Feb 13 01:28 /tmp/deal_img.jpg


Image downloaded. Now let me build the tweet. I need:
- Hook (emoji + deal highlight)
- Product name + price
- 5-8 hashtags
- Link LAST: gottahavecoups.com/deal/33914
- KEEP UNDER 280 CHARS

Draft:
📚 76% OFF! The Annotated Little Women — now just $2.99 (was $12.99)!

Perfect for book lovers & classic literature fans! 💕

#BookDeals #LittleWomen #KindleDeals #AmazonDeals #BookLovers #Reading #BookSale #GottaHaveCoups

gottahavecoups.com/deal/33914

Let me count... that's under 280 chars. Let me validate it.

Now building the tweet:


Successfully wrote 254 bytes to /tmp/tweet.txt


Now let me validate the tweet before posting.

exec

python3 scripts/validate_tweet.py "$(cat /tmp/tweet.txt)"


VALID


The tweet is valid. Now I need to:
1. Copy the tweet text and image to Maya VM
2. Post to X using the twikit script
3. Post to Pinterest
4. Record the posts

Let me do this step by step.

Tweet validated! Now posting to X via Maya VM:


Warning: Permanently added 'maya' (ED25519) to the list of known hosts.


Good, the file was copied. Now let me copy the image and post.


Both files copied. Now let me post to X.

ssh maya@maya "python3 /home/maya/workspace/scripts/x_twikit_post2.py 33914 --file /tmp/tweet.txt" 2>&1


Warning: Permanently added 'maya' (ED25519) to the list of known hosts.
Cookies loaded
Authenticated as: @GottaHaveCoups
Image downloaded: /home/maya/workspace/downloads/deal-33914.jpg (137345 bytes)
Uploading image...
Image uploaded, media_id: 2022120767144534017
Posting tweet...
SUCCESS! Tweet ID: 2022120772312150385
URL: https://x.com/GottaHaveCoups/status/2022120772312150385


X post successful! Now let me post to Pinterest.

X posted successfully! Now posting to Pinterest:

ssh maya@maya "python3 /home/maya/workspace/scripts/pin_post_v2.py 33914 'The Annotated Little Women - 76% OFF!' 'Classic literature lovers rejoice! The Annotated Little Women is now just \$2.99 (was \$12.99). This annotated edition is perfect for book clubs, students, and fans of Louisa May Alcott. Save \$10 on this timeless classic!' 1134485031073239531" 2>&1


Warning: Permanently added 'maya' (ED25519) to the list of known hosts.
Loaded 8 cookies
Boards: 200
Found 7 boards (raw type: dict)
Raw keys: ['all_boards', 'boards_shortlist', 'create_suggestions']
  🔥 Today’s Best Deals (id: 1134485031073239531)
  Limited Time Promo Codes (id: 1134485031073239590)
  Gifts Under $50 (id: 1134485031073239588)
  Amazon Deals & Coupons (id: 1134485031073239559)
  Home & Kitchen Savings (id: 1134485031073239570)
Image upload: 200
Image URL: https://i.pinimg.com/previews/hcjwBnD3.jpeg
Pin create: 200
SUCCESS! Pin ID: 1134484962398633935


Pinterest post successful too! Now let me record the posts in the database.

Excellent! Pinterest posted successfully! Now recording the posts:

python3 scripts/posted_db.py record 33914 x 2022120772312150385 https://x.com/GottaHaveCoups/status/2022120772312150385


Recorded 33914 for x


Now let me also record the Pinterest post and log the activity in the daily memory file.

python3 scripts/posted_db.py record 33914 pinterest 1134484962398633935 https://pinterest.com/pin/1134484962398633935


Recorded 33914 for pinterest


Now let me log this in the memory file for today.

Now logging to daily memory:

write

## Deal Post - Feb 13, 2026 01:28 AM UTC

**Posted Deal:** The Annotated Little Women (ID: 33914)
- **Price:** $2.99 (was $12.99)
- **Discount:** 76% off
- **Store:** Amazon
- **Quality Score:** 10/10 (Featured + Hot)

**X Post:**
- Tweet ID: 2022120772312150385
- URL: https://x.com/GottaHaveCoups/status/2022120772312150385
- Status: SUCCESS with image

**Pinterest Post:**
- Pin ID: 1134484962398633935
- Board: Today's Best Deals
- Status: SUCCESS

**Notes:** Excellent book deal under $5 with high discount percentage - perfect engagement content.


Successfully wrote 553 bytes to memory/2026-02-13.md


All done! Let me summarize the results for the cron task output.

---

## CRON TASK COMPLETE ✅

**Deal Posted:** The Annotated Little Women (ID: 33914)
- Price: $2.99 (was $12.99) — 76% OFF
- Store: Amazon | Quality Score: 10/10

**X (Twitter):** ✅ SUCCESS
- Tweet ID: 2022120772312150385
- URL: https://x.com/GottaHaveCoups/status/2022120772312150385

**Pinterest:** ✅ SUCCESS
- Pin ID: 1134484962398633935
- Board: Today's Best Deals

**Database:** Both posts recorded in posted_deals.json

**Next Run:** In 30 minutes (per cron schedule)