package WebService::Antigate::V2; use strict; use JSON::PP; use MIME::Base64; use parent 'WebService::Antigate'; sub new { my ($class, %args) = @_; # change some defaults $args{scheme} = 'https' unless defined $args{scheme}; $args{subdomain} = 'api.' unless defined $args{subdomain}; $class->SUPER::new(%args); } sub try_upload { my ($self, %opts) = @_; if ( defined $opts{file} ) { $opts{content} = do { local $/; open my $fh, '<:raw', $opts{file} or Carp::croak "open `$opts{file}': ", $!; <$fh>; }; } if ( defined $opts{content} ) { $opts{body} = encode_base64( $opts{content}, '' ); } if ( defined $opts{body} && !defined $opts{type} ) { $opts{type} = 'ImageToTextTask'; } my $response = $self->{ua}->post( "$self->{scheme}://$self->{subdomain}$self->{domain}/createTask", Content => encode_json { clientKey => $self->{key}, exists $opts{softId} ? ( softId => delete $opts{softId} ) : (), exists $opts{languagePool} ? ( languagePool => delete $opts{languagePool} ) : (), task => { %opts } } ); unless($response->is_success) { $self->{errno} = 'HTTP_ERROR'; $self->{errstr} = $response->status_line; return undef; } my $result = decode_json $response->decoded_content; if ($result->{errorId}) { $self->{errno} = $result->{errorCode}; $self->{errstr} = $result->{errorDescription}; return undef; } return $self->{last_captcha_id} = $result->{taskId}; } sub try_recognize { my ($self, $id) = @_; Carp::croak "Captcha id should be specified" unless defined $id; my $response = $self->{ua}->post( "$self->{scheme}://$self->{subdomain}$self->{domain}/getTaskResult", Content => encode_json { clientKey => $self->{key}, taskId => $id } ); unless($response->is_success) { $self->{errno} = 'HTTP_ERROR'; $self->{errstr} = $response->status_line; return undef; } my $result = decode_json $response->decoded_content; if ($result->{errorId}) { $self->{errno} = $result->{errorCode}; $self->{errstr} = $result->{errorDescription}; return undef; } if ($result->{status} ne 'ready') { $self->{errno} = 'CAPCHA_NOT_READY'; $self->{errstr} = 'captcha is not recognized yet'; return undef; } for my $key ( qw/text gRecaptchaResponse token/ ) { return $result->{solution}{$key} if exists $result->{solution}{$key}; } return $result->{solution}; } sub abuse { my ($self, $id) = @_; Carp::croak "Captcha id should be specified" unless defined $id; my $response = $self->{ua}->post( "$self->{scheme}://$self->{subdomain}$self->{domain}/reportIncorrectImageCaptcha", Content => encode_json { clientKey => $self->{key}, taskId => $id } ); unless($response->is_success) { $self->{errno} = 'HTTP_ERROR'; $self->{errstr} = $response->status_line; return undef; } my $result = decode_json $response->decoded_content; if ($result->{errorId}) { if ($result->{errorCode}) { $self->{errno} = $result->{errorCode}; $self->{errstr} = $result->{errorDescription}; } else { $self->{errno} = 'ERROR_NO_SUCH_CAPCHA_ID'; $self->{errstr} = 'no such captcha id in the database'; } return undef; } return $result->{status}; } sub balance { my $self = shift; my $response = $self->{ua}->post( "$self->{scheme}://$self->{subdomain}$self->{domain}/getBalance", Content => encode_json { clientKey => $self->{key}, } ); unless($response->is_success) { $self->{errno} = 'HTTP_ERROR'; $self->{errstr} = $response->status_line; return undef; } my $result = decode_json $response->decoded_content; if ($result->{errorId}) { $self->{errno} = $result->{errorCode}; $self->{errstr} = $result->{errorDescription}; return undef; } return $result->{balance}; } 1; __END__ =head1 NAME WebService::Antigate::V2 - Recognition of captches using antigate.com service (now anti-captcha.com) through API v2 =head1 SYNOPSIS # you can use it directly use WebService::Antigate::V2; my $recognizer = WebService::Antigate::V2->new(key => "..."); $recognizer->upload_and_recognize(...); # or via base class use WebService::Antigate; my $recognizer = WebService::Antigate->new(key => "...", api_version => 2); $recognizer->upload_and_recognize(...); =head1 DESCRIPTION This is subclass of L which implements version 2 of API. API documentation available at L =head1 METHODS This class has all methods described in L. Specific changes listed below. =over =item WebService::Antigate::V2->new( %options ) Constructor changes some options defaults: KEY DEFAULT OPTIONAL ----------- -------------------- --------------- scheme https yes subdomain api. yes For other options see L =item $recognizer->try_upload(%options) API v2 accepts several types of captcha. For now it is: captcha image, recaptcha, funcaptcha. Each type has specific options which may be passed to this method: L Also some common options available, like C and C, which also may be passed: L How to upload normal captcha from image: print $recognizer->try_upload( file => "/tmp/captcha.jpeg" # or content => "binary data", # and any options supported by this type you need languagePool => "en", numeric => 1, minLength => 10 # type => 'ImageToTextTask' # you may specify it or not, because when `file' or `content' options detected it will be added automatically ); How to upload recaptcha: print $recognizer->try_upload( type => 'NoCaptchaTaskProxyless', # here you need to specify type websiteURL => "https://www.google.com/", websiteKey => "6LeZhwoTAAAAAP51ukBEOocjtdKGRDei9wFxFSpm", languagePool => "rn" ); And so on for other types =back =head1 SEE ALSO L, L =head1 COPYRIGHT Oleg G . This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut