Agent skill

tuesday-pivots

Stars 2
Forks 0

Install this agent skill to your Project

npx add-skill https://github.com/ChinchillaEnterprises/ChillSkills/tree/main/tuesday-pivots

SKILL.md

Tuesday Pivots

Weekly distribution skill for GFY (Go Farm Yourself) pivot reports. Takes Cliff's image + text from Slack and pushes it out via SMS (SlickText), email (HubSpot), and blog (DropInBlog).

Trigger

User says: "run tuesday pivots", "tuesday pivots", "send pivots", or similar.

Inputs

Content comes from ONE of these sources (ask if unclear):

  1. Slack #automation channel — fetch latest from GFY workspace
  2. User pastes text + provides image path — manual input

Prerequisites

  • Slack MCP active on GFY workspace (account id: gfy)
  • Playwright MCP tools loaded (load ALL needed tools upfront in Step 0)
  • Chrome profile "Jamie (gfyag.com)" used for all web steps
  • HubSpot token at ~/.config/hubspot/token

Pre-flight: Load all tools at once

Before starting, load every Playwright tool you'll need in a single batch:

ToolSearch: "playwright navigate click fill snapshot type evaluate file_upload wait_for"

This avoids repeated ToolSearch calls mid-workflow.

Step 0: Switch Slack to GFY workspace

Use mcp__slack__switch_account with account_id: "gfy"

Step 1: Fetch content from #automation channel

IMPORTANT: The Slack bot CANNOT access user DMs. Do NOT attempt DM channels.

  • Channel: #automation (ID: C08MZHERDHA) — bot is already a member
  • Use mcp__slack__slack_get_channel_history on channel C08MZHERDHA, limit 5
  • Look for today's pivot message (forwarded by user from Cliff's DM)
  • Extract the text from the message body

KNOWN LIMITATION: Slack MCP does not return file attachments. Images forwarded to #automation will not be accessible. The image must come from one of these fallback paths:

  1. User provides a file path directly (e.g., ~/Downloads/image.png)
  2. User pastes the image into the CLI
  3. User saves it to Downloads first, then gives the filename

If no pivot message in #automation today, immediately ask user: "Can you forward Cliff's pivot to #automation, or paste the text and image here?"

Step 2: Save files locally

Image save path: ~/Desktop/%/Work/GFY/Pivots/weekly/YYYY/Mon/Mon-DD.png Text save path: ~/Desktop/%/Work/GFY/Pivots/weekly/YYYY/Mon/Mon-DD.txt

Format rules:

  • YYYY = 4-digit year, Mon = 3-letter month (Feb, Mar, Jan)
  • DD = day of month, NO leading zero
  • Examples: Feb-18.png, Mar-4.png, Jan-7.txt

Create year/month folders if they don't exist:

bash
mkdir -p "~/Desktop/%/Work/GFY/Pivots/weekly/YYYY/Mon"

CRITICAL: Also copy the image into the repo for Playwright uploads:

bash
cp "<saved_image_path>" /Users/tori/Documents/Repos/CHI/pivot-upload.png

Playwright sandbox only allows file uploads from within /Users/tori/Documents/Repos/CHI. Always use /Users/tori/Documents/Repos/CHI/pivot-upload.png for ALL browser file uploads. Clean up this file at the end.

Step 3: Validate text length

  • Count characters in the pivot text
  • Limit: 1600 characters for SlickText (MMS messages use 3x multiplier)
  • If OVER 1600: STOP and show the text with char count. Ask user to trim.
  • If UNDER 1600: proceed automatically, note the count

Step 4: SlickText — Send SMS to both lists

URL: https://slicktext.com/dashboard/sendmessage.php Account: Rupert Williams (Administrator) Send to BOTH lists sequentially: "data" first, then "ginger"

For EACH list:

  1. Navigate to https://slicktext.com/dashboard/sendmessage.php

  2. If login required, tell user to log in via the Playwright browser, then snapshot

  3. Take a snapshot to see the form

  4. Fill the form fields:

    • Textword dropdown: Select the list ("data" or "ginger")
    • Campaign Name: Pivots M/DD/YY (e.g., "Pivots 2/18/26")
    • Message body: Type/fill the pivot text
  5. Attach image — use this exact sequence (the attach button has an overlapping div):

    browser_evaluate: () => { document.querySelector('input.mmsFile').click(); return 'triggered'; }
    

    Wait for file chooser modal, then:

    browser_file_upload: paths: ["/Users/tori/Documents/Repos/CHI/pivot-upload.png"]
    
  6. HANDLE LINK SHORTENER PROMPTS: SlickText will pop up "Shorten and track the X link?" for every decimal number in the text (459.125, 1097.70, 4.31, etc.). There will be ~20-30 of these. Dismiss them efficiently:

    browser_evaluate: () => {
      const dismissAll = () => {
        const btns = document.querySelectorAll('.swal2-deny, .swal2-cancel, [data-action="dismiss"]');
        btns.forEach(b => b.click());
      };
      const interval = setInterval(() => {
        const popup = document.querySelector('.swal2-popup');
        if (popup) {
          const noBtn = popup.querySelector('.swal2-deny') || popup.querySelector('.swal2-cancel');
          if (noBtn) noBtn.click();
        }
      }, 200);
      setTimeout(() => clearInterval(interval), 15000);
      return 'auto-dismissing link prompts for 15s';
    }
    

    After running that, click the message body field to trigger remaining prompts, then wait 15 seconds. If prompts persist, click "No" on each one via snapshot + click.

  7. Timing:

    • Before 9 AM ET: Select "Later..." and schedule for 9:00 AM
    • After 9 AM ET: Select "Now"
  8. Click "Send Message" button

  9. Confirm dialog: Click "Yes, Send It"

  10. Verify success message (e.g., "296 people will be receiving your message")

After "data" list is sent, navigate back to the same URL for "ginger" list. Campaign name for second: Pivots M/DD/YY - Ginger.

Step 5: HubSpot — Update email content (API)

Uses HubSpot API — no Playwright needed. Script: ~/.claude/skills/tuesday-pivots/scripts/hubspot-email-update.sh Marketing Email ID: 208610266640 Content widget: module-1-0-0 (via content.widgets) From: Rupert Williams / rwilliams@mail.gfy.ag (already configured)

5a. Upload pivot image to HubSpot

bash
IMAGE_URL=$(~/.claude/skills/tuesday-pivots/scripts/hubspot-email-update.sh upload-image "<saved_image_path>")

This uploads to /pivots/ folder and returns the hosted URL.

5b. Build HTML content with personalization

IMPORTANT: Always prepend the greeting with HubSpot personalization token.

html
<p>Howdy {{ contact.firstname }},</p>
<p>Paragraph 1 of pivot text...</p>
<p>Paragraph 2...</p>
<img src="HOSTED_IMAGE_URL" alt="Ginger Pivots" style="max-width:100%;" />
  • First line is ALWAYS <p>Howdy {{ contact.firstname }},</p>
  • Wrap each paragraph in <p> tags
  • Escape & as &amp;
  • Place the image at the bottom after all text paragraphs

5c. Update email content

bash
~/.claude/skills/tuesday-pivots/scripts/hubspot-email-update.sh update-content "<html_content>"

This updates the draft (PATCH /draft) and publishes (POST /publish) in one call. The footer module is included automatically to pass HubSpot validation.

5d. Verify content

bash
~/.claude/skills/tuesday-pivots/scripts/hubspot-email-update.sh get

Step 6: HubSpot — Turn on Tuesday Pivots workflow (API)

Uses HubSpot API — no Playwright needed. Script: ~/.claude/skills/tuesday-pivots/scripts/hubspot-workflow.sh Workflow ID: 519040090

The workflow sends marketing email 208610266640 to contacts in lists 137 (Opt-in Voicemail), 276, and 138 (Trialists). It checks marketability, waits 1 minute, then sends.

bash
# Check current status
~/.claude/skills/tuesday-pivots/scripts/hubspot-workflow.sh status

# Turn on — workflow enrolls contacts and sends the email
~/.claude/skills/tuesday-pivots/scripts/hubspot-workflow.sh on

IMPORTANT: Turn the workflow OFF after enrollment completes (~5 minutes):

bash
~/.claude/skills/tuesday-pivots/scripts/hubspot-workflow.sh off

This prevents re-sending if the workflow's weekly Tuesday 9 AM schedule fires later. The pre-day LaunchAgent (com.gfy.pivots-precheck) also runs Monday nights at 10 PM as a safety net.

Fallback: If API fails, use Playwright:

  1. Navigate to https://app.hubspot.com/workflows/23710839/platform/flow/519040090/edit
  2. Click "Review and turn on" → "Skip to turn on" → "Turn on workflow"

TIMING NOTE: The workflow has a built-in weekly schedule (Tuesday 9 AM CT). When turned on:

  • It will immediately enroll all contacts in lists 137/276/138 and send the email
  • The 1-minute delay in the workflow gives a small buffer
  • Turn it OFF within 5 minutes to avoid the scheduled trigger re-firing

Step 7: DropInBlog — Create blog post

URL: https://app.dropinblog.com/posts

  1. Navigate to posts page

  2. If login required, tell user to log in

  3. Click "Add Post" link (bottom right of page, ref to the link not the table button)

  4. Fill the post:

    Title (textbox): M/DD/YY Pivots format (e.g., 2/17/26 Pivots)

    • Month: no leading zero, Day: no leading zero, Year: 2-digit

    Content (iframe editor) — set via JS, do NOT try to type into it:

    browser_evaluate: () => {
      const iframe = document.querySelector('#seo-content-wrap iframe');
      if (iframe && iframe.contentDocument) {
        iframe.contentDocument.body.innerHTML = '<p>First paragraph...</p><p>Second...</p>';
        return 'Content set';
      }
      return 'iframe not found';
    }
    

    Wrap each paragraph in <p> tags. Escape & as &amp;.

    Status: Click the "Published" LABEL text (ref for the label, NOT the radio input — the radio input has an overlapping label that intercepts clicks):

    browser_click: ref for "Published" label text (generic element), NOT the radio ref
    

    Visibility: Should default to "Public" — verify but don't change unless wrong.

  5. Featured Image — Click "Select" under Featured Image to open File Manager:

    • Click "Upload" in the File Manager sidebar
    • Trigger the file input via JS (filepond label intercepts clicks):
      browser_evaluate: () => { document.querySelector('input[name="filepond"]').click(); return 'triggered'; }
      
    • Use browser_file_upload with /Users/tori/Documents/Repos/CHI/pivot-upload.png
    • Wait for upload to complete (browser_wait_for textGone: "Uploading")
    • The upload dialog may auto-close. Take a snapshot.
    • In File Manager, click the uploaded filename (should be at top, sorted by Modified)
    • Click "Insert" button that appears
    • Verify alert: "Featured image added."
  6. Click "Save Post"

  7. Verify alert shows "Saved" and page title changes to "Edit Post"

  8. Note the View Post URL from the sidebar link

Step 8: Cleanup & Confirmation

Cleanup:

bash
rm /Users/tori/Documents/Repos/CHI/pivot-upload.png

Turn off workflow (if not already done in Step 6):

bash
~/.claude/skills/tuesday-pivots/scripts/hubspot-workflow.sh off

Report to user:

  • Image saved to: [full path]
  • Text character count: [X]/1600
  • SlickText: Sent to "data" list ([N] recipients) / Sent to "ginger" list ([N] recipients)
  • HubSpot email updated + sent via workflow to lists 137/276/138
  • DropInBlog post published: [title] — [URL]

Key Reference Data

Item Value
Cliff Slack ID U02718MM970
Slack workspace GFY (account id: gfy)
Slack channel #automation (C08MZHERDHA)
Image save path ~/Desktop/%/Work/GFY/Pivots/weekly/YYYY/Mon/
Playwright upload path /Users/tori/Documents/Repos/CHI/pivot-upload.png
SlickText URL slicktext.com/dashboard/sendmessage.php
SlickText lists data, ginger
SMS char limit 1600 (MMS = 3x multiplier)
HubSpot account ID 23710839
HubSpot marketing email ID 208610266640
HubSpot content widget module-1-0-0 (in content.widgets)
Email from Rupert Williams / rwilliams@mail.gfy.ag
Personalization {{ contact.firstname }} in greeting
HubSpot workflow ID 519040090
Workflow actions Marketability check → 1-min delay → send email 208610266640
Workflow enrollment lists 137 (Opt-in Voicemail), 276, 138 (Trialists)
Email subject "Ginger Pivots"
Email update script ~/.claude/skills/tuesday-pivots/scripts/hubspot-email-update.sh
Workflow toggle script ~/.claude/skills/tuesday-pivots/scripts/hubspot-workflow.sh
DropInBlog URL app.dropinblog.com/posts
Blog title format M/DD/YY Pivots
Chrome profile Jamie (gfyag.com)

Known Platform Quirks

Slack MCP

  • Bot CANNOT access user-to-user DMs (channel_not_found error)
  • Bot CANNOT see file attachments in messages (images silently stripped)
  • Bot is deactivated in GFY workspace — cannot join new channels
  • Only use channels where bot is already a member (#automation)

Playwright Sandbox

  • File uploads MUST use paths within /Users/tori/Documents/Repos/CHI
  • Always copy images to pivot-upload.png in repo root before uploading
  • If a file_upload fails, the file chooser modal CLOSES — must re-trigger the input before retrying

SlickText

  • Decimal numbers in text trigger "Shorten and track?" link prompts (~20-30 per send)
  • The attach file button (btnAttach) has an overlapping btnContainer div — use JS to click the hidden input.mmsFile instead
  • MMS messages use a 3x character multiplier (1600 chars = 3 MMS segments)

HubSpot

  • Email 208610266640 is in AUTOMATED state — direct PATCH fails (400), must use PATCH /draft + POST /publish
  • The script handles this automatically — includes footer module (module_17725218052791, @hubspot/email_footer) in every draft PATCH to pass publish validation
  • Image upload via Files API (/files/v3/files) to /pivots/ folder
  • Workflow 519040090 sends the email — toggle on/off via API
  • MUST turn workflow OFF after sending to prevent re-fire on weekly schedule
  • Old template 51704482 (design template) is deprecated — do NOT use
  • Old sales sequence 92766546 is deprecated — workflow now sends email directly

DropInBlog

  • Content editor is inside an iframe — must use JS innerHTML to set content, NOT type/fill
  • Radio buttons have overlapping labels — click the label text element, not the radio input
  • Featured image upload uses filepond — label div intercepts clicks on the file input, use JS .click() on the input directly
  • After upload completes, must manually select the file in File Manager and click "Insert"

Error Handling

  • No pivot in #automation: Ask user to forward from Cliff's DM or provide manually
  • Image not accessible from Slack: Ask user for file path or have them paste into CLI
  • Text over 1600 chars: Stop, show count, ask user to trim
  • Login required on any site: Tell user to log in via Playwright browser, then snapshot to continue
  • File upload sandbox error: Verify image was copied to repo root first
  • File chooser closed after error: Re-trigger the input element via JS before retrying upload
  • HubSpot email update fails: Check token at ~/.config/hubspot/token, try refreshing
  • Image upload fails: Check file exists, try again — HubSpot Files API is reliable
  • Workflow already ON: Skip the toggle step, note it in summary
  • Workflow toggle fails: Fall back to Playwright (workflow edit page)

Post-Run Assessment (mandatory)

After every run, before closing the session:

  1. Review all errors, retries, and wasted turns from this run
  2. Identify any new platform quirks or UI changes
  3. Update this SKILL.md with fixes — add new quirks, refine JS snippets, fix selectors
  4. Note what worked well and what was slow
  5. Update the "Last Run" section below

Last Run

  • Date: 2026-03-03
  • Model: Opus 4.6
  • Changes:
    • Email published from AUTOMATED_DRAFT to AUTOMATED state (footer + unsubscribe added via Playwright UI)
    • Script rewritten for draft+publish flow (direct PATCH fails on AUTOMATED emails)
    • Footer module (module_17725218052791) included in every draft PATCH for publish validation
    • Added get-draft command to script
    • Email from changed to Rupert Williams / rwilliams@mail.gfy.ag
    • Added {{ contact.firstname }} personalization greeting
    • Workflow 519040090 sends marketing email 208610266640 directly (old sequence deprecated)
  • Result: All API calls tested and working. update-content, update-subject, upload-image, get, get-draft all confirmed.
  • Target: Run on Sonnet next time, Haiku eventually

Performance Notes

  • Load all Playwright tools in one ToolSearch call at the start
  • Don't waste turns trying Slack DMs — go straight to #automation
  • Don't waste turns trying to create Slack channels — bot is deactivated
  • Copy image to repo root immediately after saving — don't discover sandbox error mid-upload
  • Use JS for all tricky UI interactions (file inputs, iframes, intercepted elements)
  • For SlickText link prompts, try the auto-dismiss JS first before manual clicking
  • HubSpot email step is now pure API — fastest step in the workflow
  • This skill is designed to run on Sonnet or Haiku — all steps are explicit with exact selectors and JS snippets

Expand your agent's capabilities with these related and highly-rated skills.

ChinchillaEnterprises/ChillSkills

Red Team

Use this skill when the user says "red team", "stress test", "attack this", "critique this", "run the models against this", "test this plan", "refine this with AI", or wants to use external AI models to critique, validate, or improve a document, pitch, plan, or idea. Also use when the user wants to save Claude Code usage by offloading analysis to other models.

2 0
Explore
ChinchillaEnterprises/ChillSkills

Upwork Scanner

This skill should be used when the user asks to "scan upwork", "find upwork jobs", "check upwork", "run the scanner", "look for jobs", or mentions finding freelance projects for Chinchilla AI.

2 0
Explore
ChinchillaEnterprises/ChillSkills

Polymarket Arb Scanner

This skill should be used when the user asks to "scan polymarket", "find arb opportunities", "check polymarket arbs", "run arb scanner", "polymarket arbitrage", or mentions detecting price inefficiencies on Polymarket.

2 0
Explore
ChinchillaEnterprises/ChillSkills

captain-update

2 0
Explore
ChinchillaEnterprises/ChillSkills

Polymarket Copy Trader

This skill should be used when the user asks to "copy trade", "telegram bot polymarket", "follow traders", "copy polymarket", or mentions building a copy trading bot for Polymarket.

2 0
Explore
ChinchillaEnterprises/ChillSkills

Architecture Diagram

This skill should be used when the user asks to "generate a diagram", "create an architecture diagram", "make a diagram", "draw a system diagram", or needs a branded Chinchilla AI technical diagram for proposals or documentation.

2 0
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results