Pipedream कोड स्टेप (Node.js) में कैप्चा कैसे हल करें

pipedream captcha - How to Solve CAPTCHAs in a Pipedream Code Step (Node.js)

Pipedream में कैप्चा हल करना Zapier या Make.com में वही काम करने से आसान है, क्योंकि एक कोड स्टेप असल में npm imports वाला Node.js v20 रनटाइम है। आप कुछ भी इंस्टॉल नहीं करते, आप सामान्य JavaScript लिखते हैं, और CapSkip SDK ठीक वैसे ही काम करता है जैसे आपके लैपटॉप पर। दो चीज़ें अलग हैं, और दोनों इस बारे में हैं कि कोड चलता कहाँ है। Pipedream अपने ही क्लाउड में चलता है, इसलिए सॉल्वर तक इंटरनेट से पहुँचा जा सकना चाहिए। और एक workflow execution की समय सीमा एक reCAPTCHA solve से कम होती है, जो तय करती है कि आप एक स्टेप लिखेंगे या दो।

आपको क्या चाहिए

  • कोड स्टेप वाला एक Pipedream workflow। नीचे Node.js रनटाइम इस्तेमाल किया गया है। और आगे नीचे एक Python वर्ज़न भी है।
  • Server mode में चलता CapSkip, ऐसी मशीन पर जिस तक इंटरनेट से पहुँचा जा सके, और एक स्टैटिक public IP के साथ।
  • जिस साइट को आप ऑटोमेट कर रहे हैं उसका sitekey और पेज URL।
  • दो Pipedream एनवायरनमेंट वेरिएबल, जिनमें सॉल्वर का पता और उसकी key रखी हो।

यहाँ loopback पता क्यों काम नहीं कर सकता

Pipedream के workflows, Pipedream के अपने इन्फ़्रास्ट्रक्चर पर, AWS us-east-1 network में चलते हैं। किसी कोड स्टेप के अंदर से 127.0.0.1 पर भेजी गई request उसी कंटेनर पर पहुँचती है जिसमें स्टेप चल रहा है, आपकी डेस्क पर नहीं। वहाँ कुछ भी सुन नहीं रहा होता, और SDK एक NetworkException उठाता है।

CapSkip में दो कनेक्शन मोड हैं और दूसरा ही जवाब है। Local, 127.0.0.1 से बंधता है और सिर्फ़ उसी डिवाइस को सेवा देता है, जो तब सही है जब ऑटोमेशन और सॉल्वर एक ही मशीन साझा करते हों। Server, आपके network पते या public IP से बंधता है, इसलिए कोई होस्टेड प्लेटफ़ॉर्म उसी Windows मशीन तक API के ज़रिए पहुँच सकता है। स्टैटिक public IP की सलाह दी जाती है, क्योंकि घूमता फिरता रेज़िडेंशियल पता आपको बताए बिना रात तीन बजे workflow तोड़ देगा। दोनों मोड यहाँ सेट किए जाते हैं: कनेक्शन सेटिंग्स.

Server mode सिर्फ़ यह बदलता है कि सॉल्वर कहाँ चलता है, और कुछ नहीं। यह अब भी आपका हार्डवेयर है और अब भी बिना मीटर के है, इसलिए महीने में दस हज़ार बार चलने वाले workflow की लागत उतनी ही है जितनी दस बार चलने वाले की।

स्टेप 1: पते को एक एनवायरनमेंट वेरिएबल में रखें

स्टेप में public IP हार्डकोड न करें। Pipedream में workspace एनवायरनमेंट वेरिएबल होते हैं, और कोड स्टेप उन्हें सामान्य process environment से पढ़ता है। दो बनाएँ।

वेरिएबल का नाममान
CAPSKIP_HOST नाम वालाआपकी सॉल्वर मशीन का public IP, बिना scheme और बिना port के
CAPSKIP_API_KEY नाम वालावह key जो आपने इस workflow के लिए CapSkip ऐप में बनाई

एक ही key साझा करने के बजाय इस workflow को उसकी अपनी key दें। किसी साझा workspace में लीक हुई key को रद्द करने से आपका बाक़ी ऑटोमेशन भी साथ में नहीं गिरना चाहिए।

स्टेप 2: पूरा solve एक ही कोड स्टेप में

जैसे ही आप कोई npm पैकेज import करते हैं, Pipedream उसे उसी वक़्त इंस्टॉल कर देता है, इसलिए न कोई इंस्टॉल स्टेप है और न कोई पैकेज फ़ाइल। import specifier वही जगह भी है जहाँ आप version पिन करते हैं, जो हर उस चीज़ पर करना चाहिए जो बिना निगरानी के चलती है।

// npm install capskip - Pipedream installs it from this import.
// The package is CommonJS, so take the default and destructure.
import capskip from "capskip";

const { CapSkip } = capskip;

export default defineComponent({
  async run({ steps, $ }) {
    const solver = new CapSkip({
      host: process.env.CAPSKIP_HOST,
      port: 8080,
      apiKey: process.env.CAPSKIP_API_KEY,
    });

    const result = await solver.recaptcha(
      "YOUR_SITEKEY",
      "https://example.com/page-with-recaptcha"
    );

    return result.code;   // the token, for the next step
  },
});

बस इतना ही है। हर reCAPTCHA वैरिएंट वही method है, बस एक options ऑब्जेक्ट के साथ: invisible को 1, enterprise को 1, या version को v3 और साथ में एक action नाम। Turnstile और GeeTest के अपने methods हैं, ढाँचा वही है, और parameters की पूरी सूची यहाँ है: CapSkip API डॉक्यूमेंटेशन.

स्टेप जो भी लौटाता है वह workflow के exports में पहुँच जाता है, इसलिए बाद का कोई स्टेप token को उसी स्टेप के अपने नाम से पढ़ता है। अगर आप उसे कोई लेबल देना चाहें, तो export helper इस्तेमाल करें।

// A named export reads better downstream than a bare return.
$.export("token", result.code);

// The next step then reads steps.solve_captcha.token

execution टाइमआउट, और एक स्टेप कब काफ़ी नहीं रह जाता

यही वह बंदिश है जो बाक़ी सब कुछ तय करती है। Pipedream के एक execution की डिफ़ॉल्ट समय सीमा HTTP और email ट्रिगर के लिए 30 सेकंड है, और cron ट्रिगर के लिए 60 सेकंड। आप इसे workflow settings में बढ़ा सकते हैं, मुफ़्त प्लान पर 300 सेकंड तक और पेड प्लान पर 750 सेकंड तक।

reCAPTCHA v2 का solve आमतौर पर 30 सेकंड के भीतर आराम से हो जाता है, पर आमतौर पर का मतलब हमेशा नहीं होता, और SDK की अपनी ऊपरी सीमा recaptchaTimeout है, 300 सेकंड पर। तो ऊपर वाला एक स्टेप वाला तरीक़ा ठीक उतना ही भरोसेमंद है जितनी आपकी टाइमआउट सेटिंग। अगर workflow की सीमा solve से कम है, तो पोलिंग के बीच में ही execution ख़त्म कर दिया जाता है और आपको एक नाकाम रन मिलता है जिसमें कुछ काम का नहीं होता।

आपकी स्थितिक्या करें
कम वॉल्यूम, और आप execution की सीमा 300 सेकंड तक बढ़ा सकते हैंएक स्टेप वाला तरीक़ा ही रखें। workflow settings में टाइमआउट बढ़ाएँ
ज़्यादा वॉल्यूम, या आप execution समय के पैसे दे रहे हैंइसे बाँट दें, और नीचे बताया गया rerun helper इस्तेमाल करें
Turnstile challenge पेज या GeeTest, जिनमें ज़्यादा समय लगता हैइसे बाँट दें। छोटी सीमा से आगे निकल जाने की सबसे ज़्यादा संभावना इन्हीं प्रकारों में है

स्टेप 3: rerun helper से इसे बाँटें

Pipedream के पास एक पोलिंग प्रिमिटिव है जो ज़्यादातर ऑटोमेशन प्लेटफ़ॉर्म पर नहीं होता। flow rerun helper मौजूदा स्टेप को ख़त्म करता है, इंतज़ार करता है, और उसी स्टेप को उस state के साथ दोबारा चलाता है जो आप उसे सौंपते हैं। इंतज़ार के दौरान workflow चल नहीं रहा होता, इसलिए धीमे solve की आपको कोई क़ीमत नहीं पड़ती और वह सीमा से टकरा भी नहीं सकता।

तीन चीज़ें इसे काम करने लायक़ बनाती हैं। run काउंटर 1 से शुरू होता है और हर rerun पर बढ़ता है। आप जो context ऑब्जेक्ट पास करते हैं, वह अगले pass पर पढ़ा जा सकता है। और retry की ऊपरी सीमा पार होने पर workflow नाकाम होने के बजाय अगले स्टेप पर चला जाता है, इसलिए अगर आप यह नहीं चाहते तो throw करें।

// No SDK here. The raw endpoints suit a step that exits
// between polls, because nothing has to stay in memory.
const MAX_RETRIES = 20;
const DELAY = 15000;   // 15s, the recommended first wait for v2

export default defineComponent({
  async run({ steps, $ }) {
    const { run } = $.context;
    const base = `http://${process.env.CAPSKIP_HOST}:8080`;
    const key = process.env.CAPSKIP_API_KEY;

    if (run.runs === 1) {
      const params = new URLSearchParams({
        key,
        method: "userrecaptcha",
        googlekey: "YOUR_SITEKEY",
        pageurl: "https://example.com/page-with-recaptcha",
        json: "1",
      });
      const submitted = await fetch(`${base}/in.php?${params}`);
      const { request: id } = await submitted.json();

      // The id survives into the next run through the context.
      return $.flow.rerun(DELAY, { id }, MAX_RETRIES);
    }

    const { id } = $.context.run.context;
    const polled = await fetch(
      `${base}/res.php?key=${key}&action=get&id=${id}&json=1`
    );
    const data = await polled.json();

    if (data.request !== "CAPCHA_NOT_READY") {
      return data.request;   // the token
    }
    if (run.runs === MAX_RETRIES + 1) {
      throw new Error("Solve did not finish in time");
    }
    return $.flow.rerun(DELAY, { id }, MAX_RETRIES);
  },
});

उस pending रिस्पॉन्स की स्पेलिंग लोगों को धोखा देती है। यह CAPCHA_NOT_READY है, जिसमें एक T ग़ायब है, और यह कोई error नहीं है: इसका मतलब है कि जवाब अभी तैयार नहीं है और आपको दोबारा पोल करना चाहिए। इसे नाकामी मान लेना हाथ से लिखे पोलिंग loop की सबसे आम ग़लती है, और यहाँ मौजूद है CAPCHA_NOT_READY रिस्पॉन्स पर एक पूरा लेख.

उस endpoint के बारे में एक और बात। कोई result ठीक एक ही बार पढ़ा जा सकता है। अगर आप response body को लॉग करते हैं और फिर किसी बाद के स्टेप में उसे दोबारा पढ़ते हैं, तो दूसरी बार वह खाली आता है और लगता है जैसे solve नाकाम हो गया।

token तुरंत भेजें

एक reCAPTCHA token लगभग दो मिनट तक चलता है। किसी workflow में इसे गँवाना जितना लगता है उससे ज़्यादा आसान है, क्योंकि कोई delay स्टेप, कोई धीमा HTTP कॉल या बहुत देर तक इंतज़ार करने वाला rerun, सब उसी बजट में से खाते हैं। token submit करने वाले स्टेप को ठीक उसी स्टेप के बाद रखें जिसने उसे बनाया, और token बाद के लिए जमा न करें। पूरी तस्वीर यहाँ है: reCAPTCHA token expiration की गाइड.

Python वाला वर्ज़न

Pipedream, Python 3.12 कोड स्टेप भी चलाता है, और उसी तरह आपके imports से pip पैकेज इंस्टॉल कर देता है। SDK अपने आप एनवायरनमेंट वेरिएबल नहीं पढ़ता, इसलिए नीचे वाला स्टेप CAPSKIP_HOST, CAPSKIP_PORT और CAPSKIP_API_KEY को पढ़कर constructor को पास करता है।

# pip install capskip - Pipedream installs it from this import
import os
from capskip import CapSkip

def handler(pd: "pipedream"):
    # Your Pipedream environment variables. The SDK does not read
    # them by itself, so pass them to the constructor.
    solver = CapSkip(
        host=os.environ["CAPSKIP_HOST"],
        port=int(os.environ["CAPSKIP_PORT"]),
        apiKey=os.environ["CAPSKIP_API_KEY"],
    )

    page_url = pd.steps["trigger"]["event"]["body"]["url"]
    result = solver.recaptcha(sitekey="YOUR_SITEKEY", url=page_url)

    # Downstream steps read pd.steps["solve"]["token"]
    return {"token": result["code"]}

अगर आप यह रास्ता चुनते हैं तो बाक़ी दो के साथ CAPSKIP_PORT को 8080 पर सेट करें। तय करने से पहले एक सीमा जान लें: rerun और delay helpers Node.js के लिए ही डॉक्यूमेंट किए गए हैं, इसलिए Python स्टेप सिर्फ़ एक बार वाला वर्ज़न है। अगर आपको बँटा हुआ पोलिंग वाला ढाँचा चाहिए, तो वह एक स्टेप Node में लिखें।

अभी अभी खोले गए port को सुरक्षित करना

Server mode सार्वजनिक इंटरनेट पर एक listener लगा देता है, इसलिए इसे किसी भी दूसरी खुली सेवा की तरह ही समझें। पहले ही दिन तीन चीज़ें कर लेनी चाहिए।

  • CapSkip ऐप में API key validation चालू करें और इस workflow को उसकी अपनी key दें। इसके बिना कोई भी स्ट्रिंग key के तौर पर स्वीकार कर ली जाती है।
  • 8080 को सबके लिए खुला छोड़ने के बजाय सॉल्वर को किसी firewall नियम के पीछे रखें।
  • तय करें कि आप वह नियम कैसे लिखेंगे। Pipedream का सामान्य आउटबाउंड ट्रैफ़िक मानक AWS us-east-1 रेंज से आता है, जो allowlist में काम की तरह डालने के लिए कहीं ज़्यादा चौड़ी हैं। अगर आपको कोई सँकरा नियम चाहिए, तो Pipedream हर workspace के लिए एक समर्पित स्टैटिक आउटबाउंड IP वाला VPC देता है, और आप उसी पते को allowlist करते हैं।

आम errors और उनका मतलब

आप जो देखते हैंकारणफिक्स
NetworkException, या port 8080 पर connection refusedसॉल्वर Local mode में है, या host वेरिएबल ग़लत हैServer mode पर स्विच करें और host वेरिएबल को public IP पर सेट करें
solve के बीच में ही execution ख़त्म कर दिया जाता हैworkflow की समय सीमा, solve में लगे समय से कम हैइसे workflow settings में बढ़ाएँ, या rerun वाले वर्ज़न पर जाएँ
स्टेप अपने नतीजे के तौर पर वही pending रिस्पॉन्स लौटा देता हैपोलिंग ब्रांच ने CAPCHA_NOT_READY को जवाब मान लियाउसे साफ़ तौर पर जाँचें और लौटाने के बजाय rerun करें
raw endpoint से ERROR_WRONG_USER_KEYkey वेरिएबल खाली है, इसलिए एक खाली स्ट्रिंग भेजी गईएनवायरनमेंट वेरिएबल का नाम जाँचें, केस समेत
दूसरी बार पढ़ने पर token खाली होता हैकोई result सिर्फ़ एक बार पढ़ा जा सकता हैउसे एक बार पढ़ें, किसी वेरिएबल में रखें, और उसी को आगे पास करें
एक वैध token को टारगेट साइट अस्वीकार कर देती हैवह solve और submit के बीच expire हो गयाsubmit स्टेप को सीधे solve स्टेप के बाद ले जाएँ
Cannot use import statement outside a moduleस्टेप में import और require दोनों मिले हुए हैंहर स्टेप में एक ही शैली चुनें। कोड स्टेप ES modules हैं

FAQ

क्या मैं कुछ भी उजागर किए बिना Pipedream से CapSkip इस्तेमाल कर सकता हूँ?

सीधे तौर पर नहीं, क्योंकि Pipedream का कंप्यूट Pipedream का ही है। किसी न किसी को इनबाउंड कनेक्शन स्वीकार करना ही होगा। key validation और एक firewall नियम के साथ Server mode इसका सीधा जवाब है। अगर आपकी नीति खुला port पूरी तरह मना करती है, तो विकल्प यह है कि कैप्चा का काम अपने नियंत्रण वाली मशीन पर रखें और Pipedream से उसी मशीन का अपना endpoint कॉल कराएँ, जो जोखिम को हटाता नहीं, बस उसकी जगह बदल देता है।

क्या rerun अलग execution गिना जाता है?

स्टेप दोबारा चलता है, इसलिए कोड एक से ज़्यादा बार चलता है, और ठीक इसीलिए काउंटर मौजूद है। helper का मक़सद यह है कि इंतज़ार के दौरान workflow खुला नहीं रखा जाता, इसलिए धीमा solve किसी एक execution को समय सीमा से आगे नहीं धकेलता। अगर बिलिंग मायने रखती है तो अपने प्लान की अपनी गिनती जाँच लें, पर टाइमआउट वाली समस्या दोनों ही हालात में हल हो जाती है।

मुझे SDK इस्तेमाल करना चाहिए या raw endpoints?

SDK तब, जब एक ही स्टेप पूरा काम करता है, क्योंकि वह पोलिंग संभालता है, एक समान अंतराल पर सोने के बजाय 250 मिलीसेकंड से धीरे-धीरे बढ़ता है, और आपको typed errors देता है। raw endpoints तब, जब आप काम को reruns में बाँटते हैं, क्योंकि स्टेप हर पोल के बीच बाहर निकल जाता है और task को थामे रखने के लिए मेमोरी में कोई client बचता ही नहीं। दोनों उसी port पर उसी सेवा से बात करते हैं।

यह n8n या Zapier में करने से कैसे अलग है?

ज़्यादातर फ़र्क़ रनटाइम का है। Pipedream आपको npm imports वाला असली Node.js देता है, इसलिए SDK सीधे फ़िट हो जाता है, और rerun helper धीमे solves को साफ़ ढंग से संभाल लेता है। Zapier का कोड स्टेप पैकेज इंस्टॉल नहीं कर सकता, इसलिए Zapier कैप्चा गाइड उसके timeout के इर्द गिर्द ही बनाई गई है। Make.com में कोड स्टेप है ही नहीं, इसी वजह से Make.com वॉकथ्रू HTTP modules से जोड़कर बनाया गया है। n8n को सॉल्वर के साथ ही सेल्फ़ होस्ट किया जा सकता है, इसलिए n8n गाइड अक्सर Local mode ही रख पाती है।

संक्षेप में

CapSkip को Server mode में डालें, उसका पता और key Pipedream एनवायरनमेंट वेरिएबल में रखें, और SDK को सीधे किसी Node.js कोड स्टेप में import करें। अगर workflow की समय सीमा आपके सबसे धीमे solve से आराम से ऊपर है, तो एक ही स्टेप पूरा इंटीग्रेशन है। अगर नहीं, तो स्टेप को बाँट दें: raw endpoint पर submit करें, id को rerun helper को सौंपें, और वापस आते वक़्त पोल करें। token मिलते ही उसे तुरंत submit करें, क्योंकि वह लगभग दो मिनट में expire हो जाता है।

Node.js वाला पक्ष यहाँ कवर किया गया है: Node.js कैप्चा सॉल्वर पेज, checkbox challenge यहाँ: reCAPTCHA v2 सॉल्वर पेज, और Python, PHP तथा C# में उसी के बराबर की कॉल यहाँ: CAPTCHA solving SDK पेज.

इसे दिन भर चलने वाली किसी चीज़ में जोड़ने से पहले यह जान लेना ठीक रहेगा: CapSkip कैप्चा बायपास उसी हार्डवेयर पर करता है जो पहले से आपका है, इसलिए लगातार चलने वाले workflow और कभी कभार चलने वाले workflow की लागत बिलकुल एक जैसी है।