package SkypeAPI; use 5.008005; use strict; use warnings; require Exporter; use Class::Accessor::Fast; our @ISA = qw(Exporter Class::Accessor::Fast); our $VERSION = '0.06'; # Preloaded methods go here. use SkypeAPI::Win; use Time::HiRes qw( sleep ); use threads::shared; use Digest::MD5; use Data::Dumper; $| = 1; __PACKAGE__->mk_accessors( qw/api handler_list stop_listen/ ); our $command_lock : shared; our %command_list : shared; our @message_list : shared; sub attach { my $self = shift; print "[skype]I am attaching\n"; $self->api(SkypeAPI::Win->new); $self->api->init($self->handler_list); $self->wait_available; } sub is_available { my $self = shift; return $self->api->is_available(); } sub wait_available { my $self = shift; my ($times, $interval) = @_; $times ||= 100; $interval ||= 0.1; for (1..$times) { return 1 if $self->api->is_available(); sleep $interval; } return 0; } sub send_command { my $self = shift; my $command = shift; { lock(%command_list); $command_list{$command->id} = $command; } my $command_string = sprintf("#%s %s", $command->id, $command->string); printf("[send]$command_string\n"); $self->api->send_message($command_string); if ($command->blocking) { { my $start = time; WAIT: while (1) { { lock $SkypeAPI::command_lock; if (defined $command->reply) { last WAIT; } } if (time - $start > $command->timeout) { print "[skype]wait command timeout\n"; last; } sleep 0.01; } } } return $command->reply(); } sub create_command { my $self = shift; my $opt = shift; my $command; share($command); $command = &share({}); bless $command, 'SkypeAPI::Command'; $command->timeout($opt->{timeout} || 10); $command->blocking($opt->{blocking} || 1); $command->id($opt->{id} || substr(Digest::MD5::md5_hex(time . int(rand(10000))), 0, 16)); $command->string($opt->{string} || ''); return $command; } sub register_handler { my $self = shift; my $ref_sub = shift; $self->handler_list({}) if not defined $self->handler_list; my $id = keys %{$self->handler_list}; $self->handler_list->{$id + 1} = $ref_sub; } sub listen { my $self = shift; $self->stop_listen(0); while (!$self->stop_listen) { my $message; { lock @message_list; $message = shift @message_list; } if (not defined $message) { sleep 0.01; next; } for my $id (sort keys %{$self->handler_list}) { $self->handler_list->{$id}->($self, $message); } } } 1; __END__ =head1 NAME SkypeAPI - Skype API simple implementation, only support windows platform now. =head1 VERSION 0.06 =head1 SYNOPSIS use SkypeAPI; my $skype = SkypeAPI->new(); print " skype available=", $skype->attach , "\n"; my $command = $skype->create_command( { string => "GET USERSTATUS"} ); print $skype->send_command($command) , "\n"; $command = $skype->create_command( { string => "SEARCH CHATS"} ); print $skype->send_command($command) , "\n"; =head1 FUNCTIONS =head2 SkypeAPI->new( ) Returns a SkypeAPI object. my $skype = SkypeAPI->new(); =head2 SkypeAPI->attach( ) Attach to skype, return 1 if attached ok. =head2 SkypeAPI->send_command( $command_object ) Send command to skype, return the reponse of skype =head2 SkypeAPI->create_command( $opt ) Create command. $opt is a hashref. You can defind the command string, timeout in it. timeout default is 10 seconds. my $command = $skype->create_command( { string => "SEARCH CHATS", timeout => 5} ); =head2 SkypeAPI->register_handler( $ref_callback ) Add listener to the chain of message handler. $skype->register_handler(\&handler); $skype->attach(); sub handler { my $skype = shift; my $msg = shift; my $command = $skype->create_command( { string => "GET USERSTATUS"} ); print $skype->send_command($command) , "\n"; } =head2 SkypeAPI->listen( ) After you register handlers, call $skype->listen to entery the message loop; $skype->listen(); =head2 SkypeAPI->stop_listen( ) Call stop_listen in your handler to exit the message loop sub handler { my $skype = shift; my $msg = shift; $skype->stop_listen(); } =head1 DESCRIPTION A Perl simple implementation of the Skype API, working off of the canonical Java and Python implementations. It is a encapsulation of Windows message communication between Skype and client applications. This version of SkypeAPI only implement some commands of SKYPE API, you can implement the others using SkypAPI->send_command =head2 EXPORT None by default. =head1 ROBOT DEMO You can find the robot.pl in the lib/../t/robot.pl, run it and your skype will become a xiaoi robot :) the robot needs the module XiaoI, please install it first, See L =head1 SEE ALSO For more command information, See L The svn source of this project, See L =head1 AUTHOR laomoi ( I ) =head1 COPYRIGHT AND LICENSE Copyright (C) 2008 by laomoi This library is free software; you can redistribute it and/or modify it under the same terms as Perl itinstance, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. =cut