Class: AntiCaptcha::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/anti_captcha/client.rb

Overview

AntiCaptcha::Client is a client that communicates with the Anti Captcha API: anti-captcha.com.

Constant Summary collapse

BASE_URL =
'https://api.anti-captcha.com/:action'
PROXYABLE_TASKS =
%w(RecaptchaV2Task FunCaptchaTask HCaptchaTask GeeTestTask TurnstileTask)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client_key, options = {}) ⇒ AntiCaptcha::Client

Creates a client for the Anti Captcha API.

Parameters:

  • client_key (String)

    The key of the Anti Captcha account.

  • options (Hash) (defaults to: {})

    Options hash.

Options Hash (options):

  • :timeout (Integer) — default: 120

    Seconds before giving up of a captcha being solved.

  • :polling (Integer) — default: 5

    Seconds before checking answer again.



23
24
25
26
27
# File 'lib/anti_captcha/client.rb', line 23

def initialize(client_key, options = {})
  self.client_key = client_key
  self.timeout    = options[:timeout] || 120
  self.polling    = options[:polling] || 5
end

Instance Attribute Details

#client_keyObject

Returns the value of attribute client_key.



9
10
11
# File 'lib/anti_captcha/client.rb', line 9

def client_key
  @client_key
end

#pollingObject

Returns the value of attribute polling.



9
10
11
# File 'lib/anti_captcha/client.rb', line 9

def polling
  @polling
end

#timeoutObject

Returns the value of attribute timeout.



9
10
11
# File 'lib/anti_captcha/client.rb', line 9

def timeout
  @timeout
end

Instance Method Details

#create_task!(type, options, proxy = nil) ⇒ Hash

Creates a task for solving the selected CAPTCHA type.

@option proxy [String]  :proxy_type
@option proxy [String]  :proxy_address
@option proxy [String]  :proxy_port
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_password
@option proxy [String]  :user_agent

Parameters:

  • type (String)

    The type of the CAPTCHA.

  • options (Hash)

    Options hash. # Image to text CAPTCHA @option options [String] :body64 File body encoded in base64. Make sure to

    send it without line breaks.
    

    @option options [Boolean] :phrase If the worker must enter an answer

    with at least one "space".
    

    @option options [Boolean] :case If the answer must be entered with case

    sensitivity.
    

    @option options [Integer] :numeric 0 - no requirements; 1 - only numbers

    are allowed; 2 - any letters are
    allowed except numbers.
    

    @option options [Boolean] :math If the answer must be calculated. @option options [Integer] :min_length Defines minimum length of the

    answer. 0 - no requirements.
    

    @option options [Integer] :max_length Defines maximum length of the

    answer. 0 - no requirements.
    

    @option options [String] :comment Additional comment for workers like

    "enter letters in red color". Result
    is not guaranteed.
    

    # NoCaptcha @option options [String] :website_url Address of target web page. @option options [String] :website_key Recaptcha website key. @option options [String] :language_pool

  • proxy (Hash) (defaults to: nil)

    Not mandatory. A hash with configs of the proxy that has to be used. Defaults to ‘nil`.

Returns:

  • (Hash)

    Information about the task.



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# File 'lib/anti_captcha/client.rb', line 322

def create_task!(type, options, proxy = nil)
  args = {
    languagePool: (options[:language_pool] || 'en'),
    softId: '859'
  }

  case type
  when 'ImageToTextTask'
    args[:task] = {
      type:      'ImageToTextTask',
      body:      options[:body64],
      phrase:    options[:phrase],
      case:      options[:case],
      numeric:   options[:numeric],
      math:      options[:math],
      minLength: options[:min_length],
      maxLength: options[:max_length],
      comment:   options[:comment],
    }

  when 'RecaptchaV2Task'
    args[:task] = {
      type:       'RecaptchaV2Task',
      websiteURL: options[:website_url],
      websiteKey: options[:website_key],
    }

  when 'RecaptchaV3TaskProxyless'
    args[:task] = {
      type: 'RecaptchaV3TaskProxyless',
      websiteURL:   options[:website_url],
      websiteKey:   options[:website_key],
      minScore:     (options[:min_score] || 0.3).to_f,
      pageAction:   options[:page_action],
    }
    args[:isEnterprise] = options[:is_enterprise] if [true, false].include?(options[:is_enterprise])


  when 'FunCaptchaTask'
    args[:task] = {
      type:            'FunCaptchaTask',
      websiteURL:       options[:website_url],
      websitePublicKey: options[:website_public_key],
    }

  when 'HCaptchaTask'
    args[:task] = {
      type:       'HCaptchaTask',
      websiteURL: options[:website_url],
      websiteKey: options[:website_key],
    }

  when 'GeeTestTask'
    args[:task] = {
      type:       'GeeTestTask',
      websiteURL: options[:website_url],
      gt:          options[:gt],
      challenge:   options[:challenge],
    }
    args[:geetestApiServerSubdomain] = options[:geetest_api_server_subdomain] if !options[:geetest_api_server_subdomain].nil?
    args[:geetestGetLib]             = options[:geetest_get_lib]              if !options[:geetest_get_lib].nil?
    args[:version]                   = options[:version]                      if !options[:version].nil?
    args[:initParameters]            = options[:init_parameters]              if !options[:init_parameters].nil?

  when 'TurnstileTask'
    args[:task] = {
      type:       'TurnstileTask',
      websiteURL: options[:website_url],
      websiteKey: options[:website_key],
    }

  else
    message = "Invalid task type: '#{type}'."
    raise AntiCaptcha::ArgumentError.new(message)
  end

  if PROXYABLE_TASKS.include?(type)
    if proxy.nil?
      args[:task][:type] += 'Proxyless'
    else
      args[:task].merge!(
        proxyType:     proxy[:proxy_type],
        proxyAddress:  proxy[:proxy_address],
        proxyPort:     proxy[:proxy_port],
        proxyLogin:    proxy[:proxy_login],
        proxyPassword: proxy[:proxy_password],
        userAgent:     proxy[:user_agent],
      )
    end
  end

  request('createTask', args)
end

#decode_fun_captcha!(options, proxy = nil) ⇒ AntiCaptcha::FunCaptchaSolution

Decodes a FunCaptcha CAPTCHA.

@option proxy [String]  :proxy_type
@option proxy [String]  :proxy_address
@option proxy [String]  :proxy_port
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_password
@option proxy [String]  :user_agent

Parameters:

  • options (Hash)

    Options hash. @option options [String] :website_url @option options [String] :website_public_key @option options [String] :language_pool

  • proxy (Hash) (defaults to: nil)

    Not mandatory. A hash with configs of the proxy that has to be used. Defaults to ‘nil`.

Returns:



166
167
168
169
170
# File 'lib/anti_captcha/client.rb', line 166

def decode_fun_captcha!(options, proxy = nil)
  task = create_task!('FunCaptchaTask', options, proxy)
  task_result = get_task_result!(task['taskId'])
  AntiCaptcha::FunCaptchaSolution.new(task_result)
end

#decode_geetest(options, proxy = nil) ⇒ Object

Decodes a Geetest CAPTCHA.

See Also:

  • AntiCaptcha::Client.`AntiCaptcha`AntiCaptcha::Client`AntiCaptcha::Client#decode_geetest!`


213
214
215
216
217
# File 'lib/anti_captcha/client.rb', line 213

def decode_geetest(options, proxy = nil)
  decode_geetest!(options, proxy)
rescue
  AntiCaptcha::GeetestSolution.new
end

#decode_geetest!(options, proxy = nil) ⇒ AntiCaptcha::GeetestSolution

Decodes a Geetest CAPTCHA.

@option proxy [String]  :proxy_type
@option proxy [String]  :proxy_address
@option proxy [String]  :proxy_port
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_password
@option proxy [String]  :user_agent

Parameters:

  • options (Hash)

    Options hash. @option options [String] :website_url @option options [String] :gt @option options [String] :challenge @option options [String] :geetest_api_server_subdomain @option options [String] :geetest_get_lib @option options [String] :version @option options [String] :init_parameters

  • proxy (Hash) (defaults to: nil)

    Not mandatory. A hash with configs of the proxy that has to be used. Defaults to ‘nil`.

Returns:



243
244
245
246
247
# File 'lib/anti_captcha/client.rb', line 243

def decode_geetest!(options, proxy = nil)
  task = create_task!('GeeTestTask', options, proxy)
  task_result = get_task_result!(task['taskId'])
  AntiCaptcha::GeetestSolution.new(task_result)
end

#decode_h_captcha(options, proxy = nil) ⇒ Object

Decodes a HCaptcha CAPTCHA.

See Also:

  • AntiCaptcha::Client.`AntiCaptcha`AntiCaptcha::Client`AntiCaptcha::Client#decode_h_captcha!`


177
178
179
180
181
# File 'lib/anti_captcha/client.rb', line 177

def decode_h_captcha(options, proxy = nil)
  decode_h_captcha!(options, proxy)
rescue
  AntiCaptcha::HCaptchaSolution.new
end

#decode_h_captcha!(options, proxy = nil) ⇒ AntiCaptcha::HCaptchaSolution

Decodes a HCaptcha CAPTCHA.

@option proxy [String]  :proxy_type
@option proxy [String]  :proxy_address
@option proxy [String]  :proxy_port
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_password
@option proxy [String]  :user_agent

Parameters:

  • options (Hash)

    Options hash. @option options [String] :website_url @option options [String] :website_key

  • proxy (Hash) (defaults to: nil)

    Not mandatory. A hash with configs of the proxy that has to be used. Defaults to ‘nil`.

Returns:



202
203
204
205
206
# File 'lib/anti_captcha/client.rb', line 202

def decode_h_captcha!(options, proxy = nil)
  task = create_task!('HCaptchaTask', options, proxy)
  task_result = get_task_result!(task['taskId'])
  AntiCaptcha::HCaptchaSolution.new(task_result)
end

#decode_image(options) ⇒ Object

Decodes an image CAPTCHA.

See Also:

  • AntiCaptcha::Client.`AntiCaptcha`AntiCaptcha::Client`AntiCaptcha::Client#decode_image!`


34
35
36
37
38
# File 'lib/anti_captcha/client.rb', line 34

def decode_image(options)
  decode_image!(options)
rescue
  AntiCaptcha::ImageToTextSolution.new
end

#decode_image!(options) ⇒ AntiCaptcha::ImageToTextSolution

Decodes an image CAPTCHA.

Parameters:

  • options (Hash)

    Options hash. @option options [String] :body64 File body encoded in base64. Make sure to

    send it without line breaks.
    

    @option options [String] :body Binary file body. @option options [String] :path File path of the image to be decoded. @option options [File] :file File instance with image to be

    decoded.
    

    @option options [Boolean] :phrase If the worker must enter an answer

    with at least one "space".
    

    @option options [Boolean] :case If the answer must be entered with case

    sensitivity.
    

    @option options [Integer] :numeric 0 - no requirements; 1 - only numbers

    are allowed; 2 - any letters are
    allowed except numbers.
    

    @option options [Boolean] :math If the answer must be calculated. @option options [Integer] :min_length Defines minimum length of the

    answer. 0 - no requirements.
    

    @option options [Integer] :max_length Defines maximum length of the

    answer. 0 - no requirements.
    

    @option options [String] :comment Additional comment for workers like

    "enter letters in red color". Result
    is not guaranteed.
    

Returns:



69
70
71
72
73
74
# File 'lib/anti_captcha/client.rb', line 69

def decode_image!(options)
  options[:body64] = load_captcha(options)
  task = create_task!('ImageToTextTask', options)
  task_result = get_task_result!(task['taskId'])
  AntiCaptcha::ImageToTextSolution.new(task_result)
end

#decode_recaptcha_v2(options, proxy = nil) ⇒ Object Also known as: decode_nocaptcha

Decodes a reCAPTCHA v2 (NoCaptcha).

See Also:

  • AntiCaptcha::Client.`AntiCaptcha`AntiCaptcha::Client`AntiCaptcha::Client#decode_recaptcha_v2!`


81
82
83
84
85
# File 'lib/anti_captcha/client.rb', line 81

def decode_recaptcha_v2(options, proxy = nil)
  decode_recaptcha_v2!(options, proxy)
rescue
  AntiCaptcha::RecaptchaV2Solution.new
end

#decode_recaptcha_v2!(options, proxy = nil) ⇒ AntiCaptcha::RecaptchaV2Solution Also known as: decode_nocaptcha!

Decodes a reCAPTCHA v2 (NoCaptcha).

@option proxy [String]  :proxy_type
@option proxy [String]  :proxy_address
@option proxy [String]  :proxy_port
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_password
@option proxy [String]  :user_agent

Parameters:

  • options (Hash)

    Options hash. @option options [String] :website_url @option options [String] :website_key @option options [String] :language_pool

  • proxy (Hash) (defaults to: nil)

    Not mandatory. A hash with configs of the proxy that has to be used. Defaults to ‘nil`.

Returns:



108
109
110
111
112
# File 'lib/anti_captcha/client.rb', line 108

def decode_recaptcha_v2!(options, proxy = nil)
  task = create_task!('RecaptchaV2Task', options, proxy)
  task_result = get_task_result!(task['taskId'])
  AntiCaptcha::RecaptchaV2Solution.new(task_result)
end

#decode_recaptcha_v3(options) ⇒ Object

Decodes a reCAPTCHA v3.

See Also:

  • AntiCaptcha::Client.`AntiCaptcha`AntiCaptcha::Client`AntiCaptcha::Client#decode_recaptcha_v3!`


120
121
122
123
124
# File 'lib/anti_captcha/client.rb', line 120

def decode_recaptcha_v3(options)
  decode_recaptcha_v3!(options)
rescue
  AntiCaptcha::RecaptchaV3Solution.new
end

#decode_recaptcha_v3!(options) ⇒ AntiCaptcha::RecaptchaV3Solution

Decodes a reCAPTCHA v3. Proxy is not supported.

Parameters:

  • options (Hash)

    Options hash. @option options [String] :website_url @option options [String] :website_key @option options [String] :min_score (one of 0.3, 0,5 or 0.7) @option options [String] :page_action @option options [String] :is_enterprise @option options [String] :language_pool

Returns:



140
141
142
143
144
# File 'lib/anti_captcha/client.rb', line 140

def decode_recaptcha_v3!(options)
  task = create_task!('RecaptchaV3TaskProxyless', options)
  task_result = get_task_result!(task['taskId'])
  AntiCaptcha::RecaptchaV3Solution.new(task_result)
end

#decode_turnstile(options, proxy = nil) ⇒ Object

Decodes a Turnstile CAPTCHA.

See Also:

  • AntiCaptcha::Client.`AntiCaptcha`AntiCaptcha::Client`AntiCaptcha::Client#decode_turnstile!`


254
255
256
257
258
# File 'lib/anti_captcha/client.rb', line 254

def decode_turnstile(options, proxy = nil)
  decode_turnstile!(options, proxy)
rescue
  AntiCaptcha::TurnstileSolution.new
end

#decode_turnstile!(options, proxy = nil) ⇒ AntiCaptcha::TurnstileSolution

Decodes a Turnstile CAPTCHA.

@option proxy [String]  :proxy_type
@option proxy [String]  :proxy_address
@option proxy [String]  :proxy_port
@option proxy [String]  :proxy_login
@option proxy [String]  :proxy_password

Parameters:

  • options (Hash)

    Options hash. @option options [String] :website_url @option options [String] :website_key

  • proxy (Hash) (defaults to: nil)

    Not mandatory. A hash with configs of the proxy that has to be used. Defaults to ‘nil`.

Returns:



277
278
279
280
281
# File 'lib/anti_captcha/client.rb', line 277

def decode_turnstile!(options, proxy = nil)
  task = create_task!('TurnstileTask', options, proxy)
  task_result = get_task_result!(task['taskId'])
  AntiCaptcha::TurnstileSolution.new(task_result)
end

#get_balance!Hash

Retrieves account balance.

Returns:

  • (Hash)

    Information about the account balance.



445
446
447
# File 'lib/anti_captcha/client.rb', line 445

def get_balance!
  request('getBalance')
end

#get_queue_stats!(queue_id) ⇒ Hash

This method allows you to define if it is a suitable time to upload new tasks.

Parameters:

  • queue_id (String)

    The ID of the queue. Options: 1 - standart ImageToText, English language. 2 - standart ImageToText, Russian language. 5 - Recaptcha NoCaptcha tasks. 6 - Recaptcha Proxyless task. 7 - Funcaptcha task. 10 - Funcaptcha Proxyless task. 18 - Recaptcha V3 s0.3 19 - Recaptcha V3 s0.7 20 - Recaptcha V3 s0.9 21 - hCaptcha Proxy-On 22 - hCaptcha Proxyless 26 - Turnstile Proxy-On 27 - Turnstile Proxyless

Returns:

  • (Hash)

    Information about the queue.



470
471
472
473
# File 'lib/anti_captcha/client.rb', line 470

def get_queue_stats!(queue_id)
  args = { queueId: queue_id }
  request('getQueueStats', args)
end

#get_task_result!(task_id) ⇒ Hash

Creates a task for solving the selected CAPTCHA type.

Parameters:

  • task_id (String)

    The ID of the CAPTCHA task.

Returns:

  • (Hash)

    Information about the task.

Raises:



423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/anti_captcha/client.rb', line 423

def get_task_result!(task_id)
  raise AntiCaptcha::Error.new('taskId not received from Anti Captcha.') unless task_id

  started_at = Time.now

  loop do
    api_result = request('getTaskResult', { taskId: task_id })

    if api_result['status'] == 'ready'
      return AntiCaptcha::TaskResult.new(api_result, task_id)
    end

    sleep(polling)
    raise AntiCaptcha::Timeout if (Time.now - started_at) > timeout
  end
end

#report_incorrect_image_catpcha!(task_id) ⇒ Hash

Complaints are accepted only for image CAPTCHAs. A complaint is checked by 5 workers, 3 of them must confirm it.

Parameters:

  • task_id (String)

    The ID of the CAPTCHA task.

Returns:

  • (Hash)

    Information about the complaint.



483
484
485
486
# File 'lib/anti_captcha/client.rb', line 483

def report_incorrect_image_catpcha!(task_id)
  args = { taskId: task_id }
  request('getTaskResult', args)
end