3 czerwca 2015

Aplikacja LINE, protokół Thrift i Perl

Wszystkie skrypty jakie znalazłem w sieci, które logowały się do LINE, były napisane głównie w języku Python, a ja niestety programuję w Perl. Więc po dwóch dniach walk, na podstawie znalezionego kodu w sieci, stworzyłem skrypt który loguje się do LINE i pobiera dane użytkownika. Inne funkcje można podejrzeć w pliku TalkService.pm
#!/usr/bin/perl

package customHttpClient;
use base qw(Thrift::HttpClient);

sub setCustomHeader {
    my $self = shift;
    push @{$self->{'customHeaders'}},[@_];
}

sub flush
{
    my $self = shift;

    my $ua = LWP::UserAgent->new('timeout' => 1);
    $ua->default_header('Accept' => 'application/x-thrift');
    $ua->default_header('Content-Type' => 'application/x-thrift');
    $ua->cookie_jar({}); # hash to remember cookies between redirects

    my $out = $self->{out};
    $out->setpos(0); # rewind
    my $buf = join('', <$out>);

    my $request = new HTTP::Request(POST => $self->{url}, undef, $buf);

    foreach ( @{$self->{'customHeaders'}} ) {
        $request->header(@$_);
    }

    my $response = $ua->request($request);
    my $content_ref = $response->content_ref;

    my $in = IO::String->new($content_ref);
    binmode($in);
    $self->{in} = $in;
    $in->setpos(0); # rewind

    # reset write buffer
    $out = IO::String->new;
    binmode($out);
    $self->{out} = $out;
}

package main;

use strict;
use warnings;
use Data::Dumper;
use Thrift::XS;
use TalkService;
use Try::Tiny;

use constant LINE_DOMAIN   => "http://125.209.252.15";
use constant LINE_HTTP_URL => LINE_DOMAIN . "/api/v4/TalkService.do";

my $ip          = "127.0.0.1";
my $version     = "4.0.2.366";
my $com_name    = "LineJ";

my $id = '<email>';
my $password = '<password>';

my $os_version = "6.2.9200-8-x64";
my $user_agent = sprintf("DESKTOP:WINDOWS:%s(%s)",$os_version,$version);
my $app = sprintf("DESKTOPWIN\t%s\tWINDOWS\t%s",$version, $os_version);

my $transport = new customHttpClient(LINE_HTTP_URL);
$transport->setCustomHeader('User-Agent' => $user_agent);
$transport->setCustomHeader('X-Line-Application' => $app);

my $protocol  = new Thrift::XS::CompactProtocol($transport);
my $client = new TalkServiceClient($protocol);

try {
    my $msg = $client->loginWithIdentityCredentialForCertificate(
        IdentityProvider::LINE, $id, $password, 0, $ip, $com_name, ""
    );
    $transport->setCustomHeader('X-Line-Access' => $msg->{authToken});
    print Dumper $client->getProfile();
} catch {
    print STDERR Dumper $_;
};

exit;
Moduł TalkService wygenerowałem na podstawie pliku line.thrift. Informacje jak wygenerować kod w Perlu (i nie tylko) znajdują się pod adresem https://thrift.apache.org/tutorial/.