-- Common function for screenshot → ChatGPT workflow local function screenshotToChatGPT(createNewWindow) if createNewWindow == nil then createNewWindow = false end LOG.i("Screenshot hotkey triggered") -- Save current clipboard change count to detect new screenshots local oldChangeCount = hs.pasteboard.changeCount() LOG.i("Clipboard change count before: " .. oldChangeCount) -- Step 1: interactive screenshot directly to clipboard LOG.i("Taking screenshot to clipboard...") local output, status, execType, rc = hs.execute("/usr/sbin/screencapture -i -c") LOG.i(string.format("screencapture returned: rc=%d", rc)) -- Small delay for clipboard to update hs.timer.usleep(200000) -- 0.2 seconds -- Check if clipboard changed (new content added) local newChangeCount = hs.pasteboard.changeCount() LOG.i("Clipboard change count after: " .. newChangeCount) if newChangeCount == oldChangeCount then LOG.i("No screenshot taken (cancelled or clipboard unchanged)") return end -- Verify there's an image in clipboard local contentTypes = hs.pasteboard.contentTypes() LOG.i("Clipboard content types: " .. hs.inspect(contentTypes)) local hasImage = false if contentTypes then for _, contentType in ipairs(contentTypes) do if type(contentType) == "string" then if contentType:match("image") or contentType:match("png") or contentType:match("tiff") then hasImage = true break end end end end if not hasImage then LOG.i("Clipboard changed but no image found") return end LOG.i("Screenshot captured to clipboard") -- Step 2: open ChatGPT app LOG.i("Opening ChatGPT") hs.application.launchOrFocus("ChatGPT") hs.timer.doAfter(1.0, function() -- Get the app object local app = hs.application.get("ChatGPT") if not app then LOG.ef("ChatGPT app not found") return end -- Ensure ChatGPT is focused app:activate() LOG.i("ChatGPT activated") -- Create new window if requested if createNewWindow then LOG.i("Creating new ChatGPT window (Cmd+N)") hs.eventtap.keyStroke({"cmd"}, "n") hs.timer.usleep(500000) -- Wait 0.5s for new window end hs.timer.doAfter(0.3, function() -- Click on the input field (bottom center of window) local win = app:mainWindow() if win then local frame = win:frame() -- Click at bottom center of window (where input field usually is) local clickX = math.floor(frame.x + (frame.w / 2)) local clickY = math.floor(frame.y + frame.h - 75) -- 75 pixels from bottom LOG.i(string.format("Clicking input field at x=%d, y=%d", clickX, clickY)) hs.eventtap.leftClick({x = clickX, y = clickY}) else LOG.ef("Could not get ChatGPT window") end hs.timer.doAfter(0.2, function() -- Step 3: paste (ChatGPT accepts pasted images as upload) LOG.i("Pasting image") hs.eventtap.keyStroke({"cmd"}, "v") LOG.i("Paste command sent - ready for user to add text and send") end) end) end) end -- Cmd+Shift+1: Screenshot → ChatGPT (current window) hs.hotkey.bind({"cmd", "shift"}, "1", function() screenshotToChatGPT(false) end) -- Cmd+Shift+6: Screenshot → ChatGPT (new window) hs.hotkey.bind({"cmd", "shift"}, "6", function() screenshotToChatGPT(true) end)