Skype効率化

7a8922191c1fa60728589a3def4c179f?s=47 akiym
September 29, 2012

 Skype効率化

YAPC::Asia 2012

7a8922191c1fa60728589a3def4c179f?s=128

akiym

September 29, 2012
Tweet

Transcript

  1. BLJZN :"1$"TJB 4LZQFޮ཰Խ

  2. NF wBLJZN wIUUQBLJZNDPN w4LZQFUBLJZN w๺ւಓ͔Βདྷ·ͨ͠ wߴ

  3. ͜ͷηογϣϯͰ͸ wχονͳτʔΫ wਅͷΤϯδχΞ͸4LZQFͰ͸ͳ͘*3$ Λ࢖͏

  4. ͜ͷηογϣϯͰ͸ w4LZQFΛޮ཰తʹར༻͢ΔͨΊʹ͸ w4LZQFCPU wԻ੠௨࿩ɺΠϯελϯτϝοηʔδΛ ར༻

  5. ͜ͷηογϣϯͰ͸ w*3$CPUΛ4LZQFʹ

  6. % cpanm Skype::Any

  7. % cpanm Net::DBus::Skype::API % cpanm Cocoa::Skype

  8. 4LZQF"OZ

  9. IUUQTHJUIVCDPNBLJZN4LZQF"OZ

  10. w4LZQF%FTLUPQ"1*XSBQQFS wJOTQJSFECZ4LZQF1Z w4LZQF"1*ʹ͍ͭͯ͸ͪ͜ΒΛࢀর IUUQEFWFMPQFSTLZQFDPNQVCMJDBQJSFGFSFODF

  11. w.BD -JOVYͰಈ࡞ w8JOEPXTʹ͸ରԠ͍ͯ͠·ͤΜ w"OZ&WFOU w$PDPB4LZQF CZUZQFTUFS

  12. None
  13. JODPNQBUJCMFDIBOHFT

  14. ؀ڥߏங

  15. ͳͥʁ w$6*؀ڥͰͷ4LZQFEBFNPO w9WGC w(6*؀ڥͰ͋Ε͹4LZQFΛ্ཱͪ͛Δ ͚ͩͰΑ͍

  16. w%FCJBO(/6-JOVY4RVFF[F w4LZQFGPS-JOVY

  17. w-JOVY্Ͱಈ͘4LZQF༻ͷCPUΛ࡞Δํ ๏

  18. 4LZQFCPU

  19. QJOHQPOH

  20. QJOHQPOH wbQJOH`ͷϝοηʔδ͕ૹΒΕ͖ͯͨΒ wbQPOH`ͷϝοηʔδΛૹ৴͢Δ

  21. use strict; use warnings; use Skype::Any; my $skype = Skype::Any->new();

    $skype->message_received(sub { my ($msg) = @_; my $body = $msg->body; if ($body eq 'ping') { $msg->chat->send_message('pong'); } }); $skype->run;
  22. use strict; use warnings; use Skype::Any; my $skype = Skype::Any->new();

    $skype->message_received(sub { my ($msg) = @_; my $body = $msg->body; if ($body eq 'ping') { $msg->chat->send_message('pong'); } }); $skype->run; ஫ҙ4LZQFΫϥΠΞϯτΛ্ཱ͓ͪ͛ͯ͘͜ͱ
  23. None
  24. use strict; use warnings; use Skype::Any; my $skype = Skype::Any->new();

    $skype->message_received(sub { my ($msg) = @_; my $body = $msg->body; if ($body eq 'ping') { $msg->chat->send_message('pong'); } }); $skype->run;
  25. use strict; use warnings; use Skype::Any; my $skype = Skype::Any->new();

    $skype->message_received(sub { my ($msg) = @_; my $body = $msg->body; if ($body eq 'ping') { $msg->chat->send_message('pong'); } }); $skype->run; ϝοηʔδΛड৴͢Δͱݺ͹ΕΔ 4LZQF"OZ0CKFDU$IBU.FTTBHF
  26. use strict; use warnings; use Skype::Any; my $skype = Skype::Any->new();

    $skype->message_received(sub { my ($msg) = @_; my $body = $msg->body; if ($body eq 'ping') { $msg->chat->send_message('pong'); } }); $skype->run; ૹΒΕ͖ͯͨϝοηʔδͷຊจ
  27. use strict; use warnings; use Skype::Any; my $skype = Skype::Any->new();

    $skype->message_received(sub { my ($msg) = @_; my $body = $msg->body; if ($body eq 'ping') { $msg->chat->send_message('pong'); } }); $skype->run; νϟοτʹbQPOH`ͱϝοηʔδΛૹ৴ ϝοηʔδ͕ૹΒΕ͖ͯͨνϟοτ
  28. use strict; use warnings; use Skype::Any; my $skype = Skype::Any->new();

    $skype->message_received(sub { my ($msg) = @_; my $body = $msg->body; if ($body eq 'ping') { $msg->chat->send_message('pong'); } }); $skype->run; Πϕϯτϧʔϓͷ։࢝
  29. 4LZQF"OZ0CKFDU

  30. 4LZQF"OZ0CKFDU w4LZQF"1* w$BMM $IBU $IBU.FTTBHF  'JMF5SBOTGFS 1SPpMF 6TFS 

    w4LZQF"OZͰ͸ w4LZQF"OZ0CKFDU
  31. CHATMESSAGE 18537 STATUS RECEIVED

  32. νϟοτϝοηʔδͰ͋Ε͹ 4LZQF"OZ$IBU.FTTBHF

  33. $msg->body; $msg->chatname; $msg->from_handle; $msg->timestamp;

  34. 4LZQFͷνϟοτͷ ࢓૊Έ

  35. νϟοτͷࣝผ w͢΂ͯͷνϟοτ͸JEΛ͍࣋ͬͯΔ #anappo/$echo123;ebe5311cdd203657 w ΫϥΠΞϯτଆͰ͸ݟΔ͜ͱ͕Ͱ͖ͳ͍ w 4LZQF"1*ܦ༝ͰݟΔ͜ͱ͕Ͱ͖Δ

  36. ϝοηʔδૹ৴ wجຊతʹνϟοτΛ࡞੒ͯ͠ϝοηʔ δΛૹ৴͢Δ wνϟοτରɺάϧʔϓ ෳ਺

  37. $skype->user('echo123')->chat; $skype->user('echo123, t.akiym')->chat; ରͷνϟοτΛ࡞੒ άϧʔϓνϟοτΛ࡞੒

  38. my $user = $skype->user('echo123, t.akiym'); my $chat = $user->chat; $chat->send_message('hello');

    FDIP UBLJZNͱͷάϧʔϓνϟοτʹzIFMMPzͱૹ৴͢Δ
  39. say $skype->user('t.akiym')->chat->name; #=> #t.akiym/$akiym_bot;f8efe7736e507088 say $skype->user('t.akiym')->chat->name; #=> #t.akiym/$akiym_bot;f8efe7736e507088 say $skype->user('t.akiym,

    echo123')->chat->name; #=> #akiym_bot/$84192e06d8b4cce9 say $skype->user('t.akiym, echo123')->chat->name; #=> #akiym_bot/$d2257830ee67a5bb άϧʔϓνϟοτͷ৔߹͸ νϟοτΛ࡞੒͢Δͨͼʹ৽͍͠΋ͷ͕࡞੒͞ΕΔ
  40. 4LZQF%FTLUPQ"1*

  41. w4LZQF"OZ͸4LZQF"1*ͷXSBQQFS wੜͰ4LZQF"1*Λѻ͍͍ͨ

  42. $skype->api->send_command('SEARCH RECENTCHATS')->reply; ࠷ۙ࢖ͬͨνϟοτͷ໊લΛऔͬͯ͘Δ

  43. CHATS #t.akiym/$akiym_bot;e36505b33ee2e9c8, #akiym_bot/$echo123;b0d6153555b2f9d4

  44. w$skype->api->send_command() w͙͢ʹϨεϙϯεΛฦ͞ͳ͍৔߹΋ wͦ͏͍ͬͨ৔߹͸Ϩεϙϯε͕ฦͬͯ ͘Δ·Ͱ଴ͪ·͢

  45. 63-CPU

  46. 63- wIUUQT Ͱ࢝·Δ63-͔ΒUJUMFͷத ਎Λऔͬͯ͘Δ

  47. use strict; use warnings; use LWP::UserAgent; use Skype::Any; my $ua

    = LWP::UserAgent->new; my $skype = Skype::Any->new; $skype->message_received(sub { my ($msg) = @_; my $body = $msg->body; while ($body =~ m!(?=(https?://\S+))!g) { my $url = $1; my $res = $ua->get($url); return unless $res->is_success; my ($title) = $res->decoded_content =~ m! <title>(.*?)</title>!i; $msg->chat->send_message($title) if $title; } }); $skype->run;
  48. &NBJMCPU

  49. &NBJM wͳΜΒ͔ͷϝοηʔδʹରͯ͠ϝʔϧ ૹ৴͢Δ wlFNBJMzͰ࢝·Δϝοηʔδ

  50. &NBJM wDPEFUBLFOGSPN 1FSMʹΑΔϝʔϧૹ৴࣮ફతͳ &NBJM4FOEFSͷར༻ํ๏ wUPLVIJSPN

  51. use strict; use warnings; use utf8; use Email::Sender::Simple qw(sendmail); use

    Email::Simple; use Email::Simple::Creator; use Data::Recursive::Encode; use Encode; use Email::Sender::Transport::SMTP::TLS; use Skype::Any; my $sender = Email::Sender::Transport::SMTP::TLS->new( host => 'smtp.gmail.com', port => 587, username => 'example@gmail.com', password => 'pa33w0rd', helo => 'example.com', );
  52. my $skype = Skype::Any->new; $skype->message_received(sub { my ($msg) = @_;

    my $body = $msg->body; if ($body =~ /^!email/) { my $email = Email::Simple->create( header => Data::Recursive::Encode->encode( 'MIME-Header-ISO_2022_JP' => [ To => '"̨̩̠̠" <tksk@example.mil>', From => '"·ͬͭΜ" <example@gmail.com>', Subject => "༦൧", ] ), body => encode( 'iso-2022-jp', "͏ͪͰͨ΂Δͷʁ" ), attributes => { content_type => 'text/plain', charset => 'ISO-2022-JP', encoding => '7bit', }, ); my $ret = sendmail($email, {transport => $sender}); } }); $skype->run;
  53. શདCPU

  54. શདCPU w શདCPU TVHZBO w ʮશདͰʯ w KPLFCPU

  55. use strict; use warnings; use Skype::Any; use Acme::Zenra; use Try::Tiny;

    my $zenra = Acme::Zenra->new( yahoo_appid => $ENV{YAHOO_APPID}, ); my $skype = Skype::Any->new; my $chatname = ''; # your chatname
  56. use strict; use warnings; use Skype::Any; use Acme::Zenra; use Try::Tiny;

    my $zenra = Acme::Zenra->new( yahoo_appid => $ENV{YAHOO_APPID}, ); my $skype = Skype::Any->new; my $chatname = ''; # your chatname ZVTVLFCF"DNF;FOSB
  57. $skype->message_received(sub { my ($msg) = @_; if ($msg->chatname eq $chatname)

    { my $body = $msg->body; try { my $result = $zenra->zenrize($body); unless ($body eq $result) { # Edit message $msg->body($result); } }; } }); $skype->run;
  58. $skype->message_received(sub { my ($msg) = @_; if ($msg->chatname eq $chatname)

    { my $body = $msg->body; try { my $result = $zenra->zenrize($body); unless ($body eq $result) { # Edit message $msg->body($result); } }; } }); $skype->run; ฤू͢Δ͜ͱ͕Ͱ͖ͳ͍ϝοηʔδ΋͋ΔͨΊ
  59. $skype->message_received(sub { my ($msg) = @_; if ($msg->chatname eq $chatname)

    { my $body = $msg->body; try { my $result = $zenra->zenrize($body); unless ($body eq $result) { # Edit message $msg->body($result); } }; } }); $skype->run; 5JQT$msg->body(‘’);Ͱϝοηʔδͷ࡟আ
  60. ࣙॻCPU

  61. ࣙॻ wlEJDUEJDUJPOBSZzͷΑ͏ͳϝοηʔδ Λड৴ͨ͠Β wड৴ͨ͠Ϣʔβʔʹࣙॻͷ಺༰Λૹ৴ ͢Δ

  62. use strict; use warnings; use utf8; use Encode; use Lingua::JA::Regular::Unicode

    qw/alnum_z2h/; use LWP::UserAgent; use Skype::Any; use XML::Simple (); use URI; use URI::QueryParam; our %DICT_TYPE = (e2j => 'EJdict', j2e => 'EdictJE'); my $ua = LWP::UserAgent->new; my $api_url = 'http://public.dejizo.jp/NetDicV09.asmx'; my $skype = Skype::Any->new; $skype->message_received(sub { my $msg = shift; if (my ($word) = $msg->body =~ /^dict:\s*(.+)/) { my $type = $word =~ /^[a-zA-Z0-9_]+$/ ? 'e2j' : 'j2e'; my $user = $msg->object(user => $msg->from_handle); if (my $item_id = get_item_id($word, $type)) { my $body = get_body($item_id, $type); $body = alnum_z2h($body); $user->chat->send_message($body); } else { $user->chat->send_message('Sorry, did not match... ;('); } } }); $skype->run;
  63. use strict; use warnings; use utf8; use Encode; use Lingua::JA::Regular::Unicode

    qw/alnum_z2h/; use LWP::UserAgent; use Skype::Any; use XML::Simple (); use URI; use URI::QueryParam; our %DICT_TYPE = (e2j => 'EJdict', j2e => 'EdictJE'); my $ua = LWP::UserAgent->new; my $api_url = 'http://public.dejizo.jp/NetDicV09.asmx'; my $skype = Skype::Any->new; $skype->message_received(sub { my $msg = shift; if (my ($word) = $msg->body =~ /^dict:\s*(.+)/) { my $type = $word =~ /^[a-zA-Z0-9_]+$/ ? 'e2j' : 'j2e'; my $user = $msg->object(user => $msg->from_handle); if (my $item_id = get_item_id($word, $type)) { my $body = get_body($item_id, $type); $body = alnum_z2h($body); $user->chat->send_message($body); } else { $user->chat->send_message('Sorry, did not match... ;('); } } }); $skype->run; dict: Ͱ࢝·Δϝοηʔδ
  64. use strict; use warnings; use utf8; use Encode; use Lingua::JA::Regular::Unicode

    qw/alnum_z2h/; use LWP::UserAgent; use Skype::Any; use XML::Simple (); use URI; use URI::QueryParam; our %DICT_TYPE = (e2j => 'EJdict', j2e => 'EdictJE'); my $ua = LWP::UserAgent->new; my $api_url = 'http://public.dejizo.jp/NetDicV09.asmx'; my $skype = Skype::Any->new; $skype->message_received(sub { my $msg = shift; if (my ($word) = $msg->body =~ /^dict:\s*(.+)/) { my $type = $word =~ /^[a-zA-Z0-9_]+$/ ? 'e2j' : 'j2e'; my $user = $msg->object(user => $msg->from_handle); if (my $item_id = get_item_id($word, $type)) { my $body = get_body($item_id, $type); $body = alnum_z2h($body); $user->chat->send_message($body); } else { $user->chat->send_message('Sorry, did not match... ;('); } } }); $skype->run; $skype->user($msg->from_handle);
  65. sub get_item_id { my ($word, $type) = @_; my $uri

    = URI->new("$api_url/SearchDicItemLite"); $uri->query_form_hash({ Dic => $DICT_TYPE{$type}, Word => $word, Scope => 'HEADWORD', Match => 'STARTWITH', Merge => 'AND', Prof => 'XHTML', PageSize => 1, PageIndex => 0, }); my $res = $ua->get($uri); return unless $res->is_success; my $xml = XML::Simple::XMLin($res->content); return if $xml->{ItemCount} == 0; $xml->{TitleList}{DicItemTitle}{ItemID}; }
  66. sub get_body { my ($item_id, $type) = @_; my $uri

    = URI->new("$api_url/GetDicItemLite"); $uri->query_form_hash({ Dic => $DICT_TYPE{$type}, Item => $item_id, Loc => '', Prof => 'XHTML', }); my $res = $ua->get($uri); return unless $res->is_success; my $xml = XML::Simple::XMLin( $res->content, SuppressEmpty => 1, # returns empty element. ); if ($type eq 'e2j') { my $caption = $xml->{Head}->{div}{span}{content}; if ($caption =~ s/\.$//) { my @results = split /\s+/, $xml->{Body}->{div}{div}; sprintf '%d results: %s', scalar @results, join ', ', @results; } else { sprintf '[%s] %s', $caption, join "\n", split /\s+/, $xml->{Body}->{div}{div}; } } else { (my $caption = $xml->{Head}->{div}{span}{content}) =~ s/\n* \s+.*$//ms; my $stuff = $xml->{Body}->{div}{div}{div}; if (ref $stuff eq 'ARRAY') {
  67. Item => $item_id, Loc => '', Prof => 'XHTML', });

    my $res = $ua->get($uri); return unless $res->is_success; my $xml = XML::Simple::XMLin( $res->content, SuppressEmpty => 1, # returns empty element. ); if ($type eq 'e2j') { my $caption = $xml->{Head}->{div}{span}{content}; if ($caption =~ s/\.$//) { my @results = split /\s+/, $xml->{Body}->{div}{div}; sprintf '%d results: %s', scalar @results, join ', ', @results; } else { sprintf '[%s] %s', $caption, join "\n", split /\s+/, $xml->{Body}->{div}{div}; } } else { (my $caption = $xml->{Head}->{div}{span}{content}) =~ s/\n* \s+.*$//ms; my $stuff = $xml->{Body}->{div}{div}{div}; if (ref $stuff eq 'ARRAY') { sprintf '[%s] %s', $caption, join ', ', @{$xml->{Body}- >{div}{div}{div}}; } else { sprintf '[%s] %s', $caption, $stuff; } } }
  68. #0/64

  69. 1VTIOPUJpDBUJPO GPSJ1IPOF

  70. 1VTIOPUJpDBUJPOGPS J1IPOF w4LZQFGPSJ1IPOF͸ϓογϡ௨஌ʹର Ԡ͍ͯ͠ͳ͍ wCPUΛαʔόʹ্ཱ͓͍ͪ͛ͯͯɺ JNLBZBDͰ௨஌͢Ε͹͍͍ͷͰ͸

  71. use strict; use warnings; use Skype::Any; use LWP::UserAgent; my $IM_KAYAC

    = 'http://im.kayac.com/api/post'; my $username = ''; # im.kayac my $password = ''; my $ua = LWP::UserAgent->new();
  72. my $skype = Skype::Any->new(); $skype->message_received(sub { my ($msg) = @_;

    my $from = $msg->from_handle; my $body = $msg->body; my $res = $ua->post("$IM_KAYAC/$username", { message => "$from: $body", handler => 'skype://', password => $password, }); die $res->status_line unless $res->is_success; }); $skype->run;
  73. my $skype = Skype::Any->new(); $skype->message_received(sub { my ($msg) = @_;

    my $from = $msg->from_handle; my $body = $msg->body; my $res = $ua->post("$IM_KAYAC/$username", { message => "$from: $body", handler => 'skype://', password => $password, }); die $res->status_line unless $res->is_success; }); $skype->run; ϝοηʔδΛૹ৴ͨ͠ϢʔβʔJE
  74. my $skype = Skype::Any->new(); $skype->message_received(sub { my ($msg) = @_;

    my $from = $msg->from_handle; my $body = $msg->body; my $res = $ua->post("$IM_KAYAC/$username", { message => "$from: $body", handler => 'skype://', password => $password, }); die $res->status_line unless $res->is_success; }); $skype->run; ϝοηʔδΛૹ৴ͨ͠ϢʔβʔJE 5JQT$msg->from_dispname;
  75. my $skype = Skype::Any->new(); $skype->message_received(sub { my ($msg) = @_;

    my $from = $msg->from_handle; my $body = $msg->body; my $res = $ua->post("$IM_KAYAC/$username", { message => "$from: $body", handler => 'skype://', password => $password, }); die $res->status_line unless $res->is_success; }); $skype->run;
  76. UBDPDIBO

  77. wJLBDIBO :BQQP ͷ4LZQF൛ w༷ʑͳαʔόͷόονॲཧͷ݁Ռ౳Λ 4LZQFͷνϟοτʹ௨஌͢Δαʔό wϝοηʔδΛૹ৴͢Δͱ͍ͬͨ͜ͱΛ )551Ͱࡁ·͢͜ͱ͕Ͱ͖Δ

  78. None
  79. IUUQTHJUIVCDPNBLJZNQ"QQ5BDPDIBO

  80. "OZ4BO1SPWJEFS4LZQF

  81. wϝϦοτ w"OZ4BOΠϯλʔϑΣʔε w΋ͪΖΜɺ4LZQF"OZ୯ମͰ΋CPU ͸ॻ͚Δ

  82. use strict; use warnings; use AnySan; use AnySan::Provider::Skype; use LWP::UserAgent;

    my $ua = LWP::UserAgent->new; my $skype = skype; AnySan->register_listener( url => { event => 'chatmessage', cb => sub { my $receive = shift; my $message = $receive->message; while ($message =~ m!(?=(https?://\S+))!g) { my $url = $1; my $res = $ua->get($url); $res->is_success or return; my ($title) = $res->decoded_content =~ m! <title>(.*?)</title>!i; $title // return; $receive->send_reply($title); } }, }, ); AnySan->run;
  83. IUUQTHJUIVCDPNBLJZN"OZ4BO1SPWJEFS4LZQF

  84. 3FENJOF$IBO$IBO

  85. w3FENJOF$IBO POJTIJ ͷ4LZQF൛ wৄ͘͠͸ *3$͔Β3FENJOFΛૢ࡞͢ΔϞδϡʔ ϧΛ࡞Γ·ͨ͠ wPOJTIJ

  86. use strict; use warnings; use FindBin; use lib "$FindBin::Bin/../lib"; use

    Config::Pit; use Redmine::Chan; use utf8; my $minechan = Redmine::Chan->new(%{pit_get('redmine', require => { redmine_url => '', redmine_api_key => '', })}, skype_chats => { '#t.akiym/$akiym_bot;e36505b33ee2e9c8' => {project_id => 1} }, status_commands => { 1 => [qw/new/], 2 => [qw/ongoing doing/], 3 => [qw/ϨϏϡʔ͓ئ͍͠·͢ ϨϏϡʔ͓Ͷ͕͍͠·͢/], 4 => [qw/ϨϏϡʔ͠·͢/], 7 => [qw/ϨϏϡʔ͠·ͨ͠/], 6 => [qw/done/], }, custom_field_prefix => { 2 => [qw(origin/)], # branch }, issue_fields => [qw/subject assigned_to status 1/], nick => 'minechan', ); $minechan->cook;
  87. use strict; use warnings; use FindBin; use lib "$FindBin::Bin/../lib"; use

    Config::Pit; use Redmine::Chan; use utf8; my $minechan = Redmine::Chan->new(%{pit_get('redmine', require => { redmine_url => '', redmine_api_key => '', })}, skype_chats => { '#t.akiym/$akiym_bot;e36505b33ee2e9c8' => {project_id => 1} }, status_commands => { 1 => [qw/new/], 2 => [qw/ongoing doing/], 3 => [qw/ϨϏϡʔ͓ئ͍͠·͢ ϨϏϡʔ͓Ͷ͕͍͠·͢/], 4 => [qw/ϨϏϡʔ͠·͢/], 7 => [qw/ϨϏϡʔ͠·ͨ͠/], 6 => [qw/done/], }, custom_field_prefix => { 2 => [qw(origin/)], # branch }, issue_fields => [qw/subject assigned_to status 1/], nick => 'minechan', ); $minechan->cook; ͜͜ʹDIBUJE NJOFDIBOࢿྉ࡞Δ
  88. IUUQTHJUIVCDPNBLJZN3FENJOF$IBO$IBO

  89. None
  90. 5)"/,450 UZQFTUFS ZVTVLFCF TVHZBO UPLVIJSPN  :BQQP POJTIJ

  91. 2VFTUJPOT PSSFQMZUP!BLJZN