=pod =encoding utf8 =head1 NAME Webqq::Client - A webqq client in Perl Language =head1 SYNOPSIS use Webqq::Client; use Digest::MD5 qw(md5_hex); my $qq = 12345678; #使用md5_hexå°†ä½ çš„qq密ç 进行md5åŠ å¯†åŽå†ä¼ 递给Webqq::Client #我å¯ä¸æƒ³è¢«æ€€ç–‘有盗å·è¡Œä¸º my $pwd = md5_hex('your password'); #通过newæ¥åˆå§‹åŒ–一个客户端对象 #debug=>1æ¥æ‰“å°debugä¿¡æ¯æ–¹ä¾¿è°ƒè¯• my $client = Webqq::Client->new(debug=>0); #通过login进行登录 $client->login( qq=> $qq, pwd => $pwd); #登录æˆåŠŸåŽè®¾ç½®å®¢æˆ·ç«¯çš„接收消æ¯å›žè°ƒå‡½æ•° $client->on_receive_message = sub{ #当收到消æ¯åŽï¼Œä¼ 递给回调函数的唯一å‚数是原始消æ¯çš„一个hash引用 my $msg = shift; ...; #ä½ å¯ä»¥å¯¹æ”¶åˆ°çš„消æ¯è¿›è¡Œä»»æ„çš„å¤„ç† #ä½ ä¹Ÿå¯ä»¥ä½¿ç”¨Data::Dumperè¿™æ ·çš„æ¨¡å—æ¥æŸ¥çœ‹æ¶ˆæ¯çš„结构,比如 #use Data::Dumper; #print Dumper $msg; }; #客户端进入事件循环,æ£å¼å¼€å§‹è¿è¡Œ $client->run(); =head1 CLIENT ASYNCHRONOUS FRAMEWORK client | ->login() | | +-------------------------<------------------------------+ | | | |->_recv_message()-[put]-> Webqq::Message::Queue -[get]-> on_receive_message() | |->send_message() -[put]--+ +-[get]-> _send_message() ---+ | \ / + |->send_sess_message()-[put]-Webqq::Message::Queue-[get]->_send_sess_message()-+ | / \ + |->send_group_message()-[put]-+ +-[get]->_send_group_message()--+ | + | on_send_message() ---<---- msg->{cb} -------<-------+ +->run() 请注æ„: 由于采用了å•çº¿ç¨‹å¼‚æ¥æ¡†æž¶ ä½ ä¸åº”该在任何回调函数ä¸äº§ç”Ÿé˜»å¡žæˆ–者长时间sleep è¿™ä¼šå¯¼è‡´æ•´ä¸ªè¿›ç¨‹è¢«é˜»å¡žï¼Œæ— æ³•æ£å¸¸å“应处ç†å…¶ä»–回调 =head1 CLIENT DATA STRUCTURE 客户端登录æˆåŠŸåŽï¼Œä¼šé©¬ä¸Šæ›´æ–°ä¸ªäººä¿¡æ¯ã€å¥½å‹ä¿¡æ¯ã€ç¾¤ä¿¡æ¯ 这些相关的信æ¯é€šè¿‡å¤šé‡hash引用的形å¼å˜å‚¨åœ¨å¦‚下形å¼ä¸ï¼š $client->{qq_database}{ user => {}, #个人信æ¯å˜å‚¨åœ¨ %{ $client->{qq_database}{user} }ä¸ friends => [], #好å‹ä¿¡æ¯å˜å‚¨åœ¨ @{ $client->{qq_database}{friends} }ä¸ group_list => [], #群列表信æ¯ï¼ˆä¸å«ç¾¤æˆå‘˜ï¼‰å˜å‚¨åœ¨@{$client->{qq_database}{group_list}}ä¸ group => [], #群信æ¯ï¼ˆåŒ…å«ç¾¤æˆå‘˜ï¼‰å˜å‚¨åœ¨ @{ $client->{qq_database}{group} } ä¸ discuss => [] #讨论组信æ¯ï¼Œæš‚未实现,仅ä¿ç•™ } =over =item %{ $client->{qq_database}{user} } ä¸ªäººä¿¡æ¯ ä¸€èˆ¬æƒ…å†µä¸‹ï¼Œä½ ä¸åº”该直接æ“作该数æ®ç»“构,而应该通过类æ供的方法进行查询 hash包å«çš„keyåŠç›¸å…³è¯´æ˜Ž,注æ„有些key的值并ä¸æ˜¯ç›´æŽ¥çš„结果,通常是一些索引编å·ç‰éœ€è¦åšé¢å¤–çš„è½¬æ¢ æ¯”å¦‚ç”Ÿè‚–çš„å€¼æ˜¯æ•°å—0,1,2,3,很容易猜测和12生肖ä¾æ¬¡å¯¹åº”,这部分å¯ä»¥è‡ªè¡Œç ”究 face => #作用未知 birthday => #生日 phone => #ç”µè¯ occupation => #èŒä¸š allow => #æƒé™ college => #å¤§å¦ uin => #æœ¬æ¬¡ç™»å½•å”¯ä¸€æ ‡è¯†ï¼Œå‘é€æ¶ˆæ¯æ—¶éœ€è¦ç”¨åˆ° blood => #血型 constel => #星座 homepage => #主页 stat => #çŠ¶æ€ country => #国家 city => #城市 personal => #个性ç¾å nick => #昵称 shengxiao => #生肖 email => #邮箱 token => #作用未知 client_type => #客户端类型 province => #çœä»½ gender => #性别 mobile => #手机 例如想获å–昵称,å¯ä»¥é€šè¿‡ $client->{qq_database}{user}{nick} æ¥èŽ·å– =item @{ $client->{qq_database}{friends} } 好å‹ä¿¡æ¯ ä¸€èˆ¬æƒ…å†µä¸‹ï¼Œä½ ä¸åº”该直接æ“作该数æ®ç»“构,而应该通过类æ供的方法进行查询,å‚è§ï¼š $client->search_friend() $cleint->update_friends_info() 好å‹ä¿¡æ¯å˜å‚¨åœ¨æ•°ç»„ä¸ï¼Œæ•°ç»„ä¸çš„æ¯ä¸ªå…ƒç´ åˆæ˜¯ä¸€ä¸ªhash的引用 [ {#数组ä¸ç¬¬1ä¸ªå…ƒç´ -好å‹1 flag => #作用未知 uin => #å‘é€æŽ¥æ”¶æ¶ˆæ¯å”¯ä¸€uin categories => #好å‹æ‰€å±žåˆ†ç»„ nick => #好有昵称 face => #作用未知 markname => #好å‹å¤‡æ³¨ is_vip => #是å¦æ˜¯vip vip_level => #vipç‰çº§ }, {#数组ä¸ç¬¬2ä¸ªå…ƒç´ -好å‹2 flag => uin => categories => nick => face => markname => is_vip => vip_level => }, ...#ä¾æ¤ç±»æŽ¨ ] 比如我è¦åœ¨å¥½å‹æ•°æ®åº“ä¸æŸ¥æ‰¾æ˜µç§°æ˜¯"å°ç°"的好å‹æ‰€å±žçš„分组,需è¦è¿™æ ·é历查找: for my $each_friend (@{ $client->{qq_database}{friends} }) { if( $each_friend->{nick} eq "å°ç°" ){ print "å°ç°æ‰€å±žçš„分组是:",$each_friend->{categories},"\n" } } =item @{ $client->{qq_database}{group_list} } 群列表(ä¸åŒ…å«ç¾¤æˆå‘˜ï¼‰ä¿¡æ¯ ä¸€èˆ¬æƒ…å†µä¸‹ï¼Œä½ ä¸åº”该直接æ“作该数æ®ç»“构,而应该通过类æ供的方法进行查询,å‚è§ï¼š $client->update_group_list_info(); 由于群包å«çš„æˆå‘˜æ•°é‡å¾ˆå¤šï¼Œå¾ˆå¤šæ—¶å€™æˆ‘们åªéœ€è¦çŸ¥é“æœ‰åŠ å…¥äº†å“ªäº›ç¾¤ï¼Œå¹¶ä¸å…³å¿ƒç¾¤é‡Œå…·ä½“çš„ æ¯ä¸€ä½æˆå‘˜ï¼Œè¿™ç§æƒ…况下åªéœ€è¦èŽ·å–群列表信æ¯å³å¯ï¼Œå’Œå¥½å‹ä¿¡æ¯ç±»ä¼¼ï¼Œç¾¤åˆ—表信æ¯ä¹Ÿæ˜¯å˜å‚¨åœ¨ 一个数组ä¸ï¼Œæ•°ç»„ä¸çš„æ¯ä¸ªå…ƒç´ åˆæ˜¯ä¸€ä¸ªhash引用 [ {#数组ä¸ç¬¬1ä¸ªå…ƒç´ ï¼Œç¾¤1 flag => #作用未知 name => #群å称 gid => #群的uin,å‘é€æŽ¥æ”¶æ¶ˆæ¯æ—¶ä½¿ç”¨ code => #群的gcode,查找群信æ¯æ—¶éœ€è¦ç”¨åˆ° markname => #群备注å称 }, {#数组ä¸ç¬¬2ä¸ªå…ƒç´ ï¼Œç¾¤2 flag => name => gid => code => }, ...#ä¾æ¤ç±»æŽ¨ ] 比如我è¦æŸ¥æ‰¾gcode是123456的群对应的群å称 for my $each_group (@{ $client->{qq_database}{group_list} }){ if($each_group->{code} == 123456){ print $each_group->{name}; } } 我è¦å‘群å称是"PERLå¦ä¹ 交æµ"的群å‘é€"hello world"æ¶ˆæ¯ å‘é€æ¶ˆæ¯éœ€è¦å…ˆèŽ·å–到群的uin(也就是gid) my $gid ; for my $each_group (@{ $client->{qq_database}{group_list} }){ if($each_group->{name} eq "PERLå¦ä¹ 交æµ" ){ $gid = $each_group->{gid} } } if($gid){ $client->send_group_message( $client->create_group_msg(to_uin=>$gid, content=>"hello world") ); } =item @{ $client->{qq_database}{group} } 群信æ¯ï¼ˆåŒ…å«ç¾¤æˆå‘˜ï¼‰ ä¸€èˆ¬æƒ…å†µä¸‹ï¼Œä½ ä¸åº”该直接æ“作该数æ®ç»“构,而应该通过类æ供的方法进行查询,å‚è§ï¼š $client->search_group(); $client->update_group_info(); $client->search_member_in_group(); æ¤ç»“构更为å¤æ‚一些,æ¯ä¸ªç¾¤ä¿¡æ¯ä»ç„¶å˜åœ¨æ”¾ä¸€ä¸ªæ•°ç»„ä¸ï¼Œ [ {#第1个群 ginfo => { face => #作用未知 memo => #ç¾¤ä»‹ç» class => #群类别 fingermemo => # code => #群的gcode,和$client->{qq_database}{group_list}一致 createtime => #群创建时间 flag => # level => #群ç‰çº§ name => #群å称 gid => #群gid ,和$client->{qq_database}{group_list}一致 owner => }, minfo => [ {#群里第1个æˆå‘˜ nick => #该æˆå‘˜æ˜µç§° province => #该æˆå‘˜çœä»½ gender => #该æˆå‘˜æ€§åˆ« uin => #该æˆå‘˜uin country => #该æˆå‘˜å›½å®¶ city => #该æˆå‘˜åŸŽå¸‚ card => #群å片 }, {#群里第2个æˆå‘˜ }, ..., ] }, {#第2个群 ginfo => {}, minfo => {}, }, ... ] 比如我è¦ç»Ÿè®¡ç¬¬1个群里女性群æˆå‘˜æ•°é‡ my $female_member = 0; for my $each_member @{ $client->{qq_database}{group}[0]{minfo} }{ if($each_member->{gender} eq 'female'){ $female_member++; } } =back æ¯ä¸ªæŽ¥æ”¶å’Œå‘é€çš„消æ¯å‡å˜å‚¨åœ¨ä¸€ä¸ªå•ç‹¬çš„hash引用ä¸,æ ¹æ®æ¶ˆæ¯ç±»åž‹çš„ä¸åŒï¼Œå†…容上ç¨æœ‰å‡ºå…¥ 与æ¤åŒæ—¶ï¼Œé‡‡ç”¨äº†Automated Accessor Generation的手段, æ¯ä¸ªhashçš„key产生一个对应的函数æ¥æ–¹ä¾¿è¯»å–,æ¯ä¸ªæ¶ˆæ¯hash引用还绑定了一些方法 关于Automated Accessor Generationå¯ä»¥å‚è§cpan Class::Accessor 注æ„:å‘é€å’ŒæŽ¥æ”¶æ¶ˆæ¯å¯¹åº”的方法å称和数é‡å¯èƒ½ä¸åŒ =over =item å‘é€æ¶ˆæ¯ç»“æž„ create_sess_msg()/create_group_msg()/create_msg()/reply_message()ç‰ä¼šç”Ÿæˆæ¤æ¶ˆæ¯ç»“æž„ send_message()/send_sess_message()/send_group_message()ç‰éœ€è¦ç”¨åˆ°æ¤æ¶ˆæ¯ç»“æž„ $msg = { type => #类型,"message"|"group_message"|"sess_message"|"kick_message" msg_id => #消æ¯id,系统自动维护 from_uin => #å‘é€è€…uin,就是自己的uin,系统自动维护 to_uin => #接收者uin content => #å‘é€å†…容 msg_class = "send" #消æ¯ç±»åˆ«,用于区分是å‘é€è¿˜æ˜¯æŽ¥æ”¶çš„æ¶ˆæ¯ msg_time => #消æ¯å‘é€æ—¶é—´ï¼Œç³»ç»Ÿè‡ªåŠ¨ç»´æŠ¤ cb => #该消æ¯å‘é€å®ŒæˆåŽçš„回调函数 group_code => #群消æ¯éœ€è¦è®¾ç½®,å‘é€ç¾¤ä¸´æ—¶æ¶ˆæ¯æ—¶éœ€è¦è®¾ç½®ï¼Œå…¶ä»–情况系统自动维护 send_uin => #群消æ¯éœ€è¦è®¾ç½®,系统自动维护 ttl => #å‘é€æ¶ˆæ¯å¸¦æœ‰ä¸€ä¸ªttl值,默认是5,当ttlå‡ä¸º0时会被å‘é€æ¶ˆæ¯é˜Ÿåˆ—丢弃 allow_plugin => #是å¦å…许æ’件处ç†è¯¥æ¶ˆæ¯æ ‡è®°ï¼Œæ’件之间互相é…åˆéœ€è¦ç”¨åˆ° } 由于采用了Automated Accessor Generationçš„æ‰‹æ®µï¼Œå› æ¤å½“ä½ è¦èŽ·å–$msgä¸çš„æŸä¸ªkey对应value时, ä½ å¯ä»¥æ‰æœ‰ä¸¤ç§æ–¹å¼ï¼š æ–¹å¼1: $msg->{type}; æ–¹å¼2: $msg->type; 接收到的消æ¯ç»“构也有类似的特性,ä¸å†è¯´æ˜Ž $msg除上述hashçš„key以外绑定的方法: 如果å‘é€æ¶ˆæ¯æ˜¯ç¾¤æ¶ˆæ¯ $msg->group_name();#å‘é€æ¶ˆæ¯å¯¹åº”的群å称 $msg->to_gname(); #消æ¯å¯¹åº”的群å称 $msg->from_qq(); #å‘é€è€…çš„qqå· $msg->from_nick(); #å‘é€è€…的昵称 如果å‘é€æ¶ˆæ¯æ˜¯å¥½å‹æ¶ˆæ¯ $msg->from_nick #å‘é€è€…昵称 $msg->from_qq #å‘é€è€…qqå· $msg->to_nick #接收者昵称 $msg->to_qq #接收者qqå· $msg->to_markname #接收者备注 $msg->to_categories #接收者所属分组 如果å‘é€æ¶ˆæ¯æ˜¯ä¸´æ—¶æ¶ˆæ¯ $msg->from_qq() #获å–å‘é€è€…qqå· $msg->from_nick() #获å–å‘é€è€…昵称 $msg->to_qq() #获å–接收者qqå· $msg->to_nick() #获å–接收者昵称 $msg->group_name() #获å–接收者所在的群å称 $msg->to_group() #获å–接收者所在的群å称 =item 接收到的好å‹æ¶ˆæ¯ç»“æž„ $msg = { type => "message" msg_id #系统自动维护 from_uin #消æ¯å‘é€è€…çš„uin,å¯ä»¥ä½¿ç”¨æ¤uin进行消æ¯å›žå¤ to_uin #消æ¯æŽ¥æ”¶è€…çš„uin,也就是自己的uin msg_time #消æ¯å‘é€æ—¶åˆ» content #消æ¯å†…容,UTF-8ç¼–ç ,表情会转æ¢æˆä¸ºæ–‡å—,例如"[系统表情]","[图片]" raw_content => [], #一个数组引用,原始消æ¯æŒ‰å›¾ç‰‡ã€è¡¨æƒ…ã€æ–‡æœ¬ç‰å½¢å¼åˆ†åˆ«å˜å‚¨åœ¨æ•°ç»„ä¸ msg_class = "recv" allow_plugin #是å¦å…许æ’件处ç†è¯¥æ¶ˆæ¯æ ‡è®°ï¼Œæ’件之间互相é…åˆéœ€è¦ç”¨åˆ° ttl #默认是5,当ttlå‡ä¸º0时会被å‘é€æ¶ˆæ¯é˜Ÿåˆ—丢弃 } $msg->{raw_content}ä¸çš„æ¯ä¸€ä¸ªå…ƒç´ åˆæ˜¯ä¸€ä¸ªhash的引用 好å‹æ¶ˆæ¯ã€ç¾¤æ¶ˆæ¯ã€ä¸´æ—¶æ¶ˆæ¯å‡åŒ…å«è¯¥ç»“构,ä¸å†é‡å¤è¯´æ˜Ž 文本类消æ¯çš„hash引用为 { type => 'txt', content => 'xxxxxxx', #utf8ç¼–ç çš„æ–‡æœ¬æ¶ˆæ¯ } 图片类消æ¯çš„hash引用为 { type => 'cface', content => '[图片]', name => 'xxxx.jpg',#文件å server => 'xxx.xxx.xxx.xxx:80', #图片å˜å‚¨æœåŠ¡å™¨ file_id => '图片文件id', } 表情类消æ¯çš„hash引用为 { type => 'face', content => '[微笑]', id => 14, #表情的唯一数å—id } $msg除上述hashçš„key以外绑定的方法: $msg->from_qq() #获å–å‘é€è€…qqå· $msg->from_nick() #获å–å‘é€è€…昵称 $msg->to_qq() #获å–接收者qqå· $msg->to_nick() #获å–接收者昵称 $msg->from_markname() #获å–å‘é€è¯¥æ¶ˆæ¯çš„好å‹å¤‡æ³¨å称 $msg->from_categories() #获å–å‘é€è¯¥æ¶ˆæ¯çš„好å‹åˆ†ç»„å称 $msg->from_city() #获å–å‘é€è€…æ‰€åœ¨åŸŽå¸‚ä¿¡æ¯ =item 接收到的群消æ¯ç»“æž„ $msg = { type = "group_message" msg_id #系统自动维护 from_uin #消æ¯æ¥æºç¾¤çš„uin,å¯ä»¥ä½¿ç”¨æ¤uin进行群消æ¯å›žå¤ to_uin #消æ¯æŽ¥æ”¶è€…çš„uin,也就是自己的uin msg_time #消æ¯å‘é€æ—¶åˆ» content #消æ¯å†…容,UTF-8ç¼–ç ,表情会转æ¢æˆä¸ºæ–‡å—,例如"[系统表情]","[图片]" send_uin #消æ¯å‘é€è€…çš„uin,和from_uin进行区别,æ¤uin是指具体的群æˆå‘˜ group_code #消æ¯æ¥æºç¾¤çš„gcode msg_class = "recv" raw_content => [], #一个数组引用,原始消æ¯æŒ‰å›¾ç‰‡ã€è¡¨æƒ…ã€æ–‡æœ¬ç‰å½¢å¼åˆ†åˆ«å˜å‚¨åœ¨æ•°ç»„ä¸ allow_plugin #是å¦å…许æ’件处ç†è¯¥æ¶ˆæ¯æ ‡è®°ï¼Œæ’件之间互相é…åˆéœ€è¦ç”¨åˆ° ttl #默认是5,当ttlå‡ä¸º0时会被å‘é€æ¶ˆæ¯é˜Ÿåˆ—丢弃 } $msg除上述hashçš„key以外绑定的方法: $msg->from_qq() #获å–å‘é€è€…qqå· $msg->from_nick() #获å–å‘é€è€…昵称 $msg->to_qq() #获å–接收者qqå· $msg->to_nick() #获å–接收者昵称 $msg->from_gname() #获å–消æ¯ç¾¤å称 $msg->group_name() #获å–消æ¯ç¾¤å称 $msg->from_card() #获å–å‘é€è€…群å片 $msg->from_city() #获å–消æ¯å‘é€è€…çš„æ‰€åœ¨åŸŽå¸‚ä¿¡æ¯ =item 接收到的群临时消æ¯ç»“æž„ $msg = { type = "group_message" msg_id #系统自动维护 from_uin #消æ¯æ¥æºç¾¤çš„uin,å¯ä»¥ä½¿ç”¨æ¤uin进行群消æ¯å›žå¤ to_uin #消æ¯æŽ¥æ”¶è€…çš„uin,也就是自己的uin msg_time #消æ¯å‘é€æ—¶åˆ» content #消æ¯å†…容,UTF-8ç¼–ç ,表情会转æ¢æˆä¸ºæ–‡å—,例如"[系统表情]","[图片]" gid #临时消æ¯æ‰€å±žçš„群的gid groud_code #临时消æ¯æ‰€å±žçš„群的group_code service_type #临时消æ¯service_type, 0表示群临时消æ¯ï¼Œ1è¡¨ç¤ºè®¨è®ºç»„ä¸´æ—¶æ¶ˆæ¯ msg_class = "recv" raw_content => [], #一个数组引用,原始消æ¯æŒ‰å›¾ç‰‡ã€è¡¨æƒ…ã€æ–‡æœ¬ç‰å½¢å¼åˆ†åˆ«å˜å‚¨åœ¨æ•°ç»„ä¸ allow_plugin #是å¦å…许æ’件处ç†è¯¥æ¶ˆæ¯æ ‡è®°ï¼Œæ’件之间互相é…åˆéœ€è¦ç”¨åˆ° ttl #默认是5,当ttlå‡ä¸º0时会被å‘é€æ¶ˆæ¯é˜Ÿåˆ—丢弃 } $msg除上述hashçš„key以外绑定的方法: $msg->from_qq() #获å–å‘é€è€…qqå· $msg->from_nick() #获å–å‘é€è€…昵称 $msg->to_qq() #获å–接收者qqå· $msg->to_nick() #获å–接收者昵称 $msg->group_name() #消æ¯å‘é€è€…所在的群å称 $msg->from_group() #消æ¯å‘é€è€…所在的群å称 =back =head1 PUBLIC CLASS METHOD =over =item new() 返回一个客户端对象 支æŒçš„å‚æ•° debug=>0|1 ,设置debug=>1æ¥æ‰“å°è°ƒè¯•ä¿¡æ¯ type=>"webqq"|"smartqq",设置typeæ¥åˆ‡æ¢ä½¿ç”¨webqq或者smartqq,默认使用smartqq webqq是腾讯的è€ç‰ˆæœ¬ï¼Œsmartqq是最新版本 my $client = Webqq::Client->new(debug=>1); =item on_send_message() :lvalue 设置客户端å‘é€æ¶ˆæ¯å®ŒæˆåŽçš„回调函数,常用于在回调函数ä¸è®°å½•å‘é€æ¶ˆæ¯å†…容或者判æ–å‘é€æ¶ˆæ¯çŠ¶æ€ 这是一个具有lvalue属性的subroutineï¼Œä½ å¿…é¡»èµ‹å€¼ä¸€ä¸ªå‡½æ•°å¼•ç”¨ $client->on_send_message() = sub{ my ($msg,$is_success,$status) = @_; ... }; 或者使用hashçš„å½¢å¼ $client->{on_send_message} = sub{ my ($msg,$is_success,$status) = @_; ... }; ä½ çš„å›žè°ƒä¼šåœ¨å‘é€æ¶ˆæ¯å®ŒæˆåŽè¢«ç«‹å³è°ƒç”¨ 这个回调通常是用æ¥åˆ¤æ–消æ¯çš„å‘é€çŠ¶æ€ ä¼ é€’ç»™å›žè°ƒçš„å‚数有三个: $msg: the original msg $is_success: the send status, true means success,false means fail $status: the send status, the value is "å‘é€æˆåŠŸ" or "å‘é€å¤±è´¥"; 注æ„,如果å‘é€æ¶ˆæ¯å¤±è´¥ï¼Œå®¢æˆ·ç«¯é»˜è®¤ä¼šæ ¹æ®$msg->{ttl}é‡è¯•å¤šæ¬¡ï¼Œ å› æ¤ä½ ä¸éœ€è¦å†æ ¹æ®$is_success自己å†è¿›è¡Œé‡è¯• =item on_receive_message() :lvalue 设置客户端接收消æ¯å›žè°ƒå‡½æ•°ï¼Œå®¢æˆ·ç«¯æŽ¥æ”¶åˆ°æ¶ˆæ¯åŽä¼šè°ƒç”¨è®¾ç½®çš„å›žè°ƒå‡½æ•°ï¼Œè®²æŽ¥æ”¶åˆ°çš„æ¶ˆæ¯ é€šè¿‡hash引用的形å¼ä¼ é€’ç»™å›žè°ƒå‡½æ•°ï¼Œä½ å¯ä»¥åœ¨æ¤å‡½æ•°ä¸å¯¹æŽ¥æ”¶åˆ°çš„消æ¯è¿›è¡Œå¤„ç† æ¯”å¦‚æ‰“å°æŽ¥æ”¶åˆ°çš„消æ¯ï¼Œå¯¹æŽ¥æ”¶åˆ°çš„消æ¯è¿›è¡Œåº”ç”ç‰ $client->on_receive_message() = sub{ my $msg = shift; }; ä¼ é€’ç»™å›žè°ƒå‡½æ•°çš„å”¯ä¸€å‚数是一个接收到的消æ¯çš„hashå¼•ç”¨ï¼Œä½ å¯ä»¥å¯¹è¿™ä¸ªmsg进行éšæ„å¤„ç† =item on_login() :lvalue 设置客户端登录æˆåŠŸåŽçš„回调函数,客户端在登录æˆåŠŸåŽä¼šè°ƒç”¨è¯¥å›žè°ƒå‡½æ•° $client->on_login() = sub{...;}; =item on_input_img_verifycode() :lvalue æ£å¸¸æƒ…å†µä¸‹ï¼Œå¦‚æžœä½ æ˜¯ç›´æŽ¥åœ¨ç»ˆç«¯è¿è¡Œwebqq,需è¦è¾“入验è¯ç æ—¶ 客户端会将验è¯ç 图片下载到本地,使用<STDIN>è¦æ±‚ä½ åœ¨ç»ˆç«¯è¾“å…¥ï¼Œå¹¶æç¤ºä½ éªŒè¯ç 图片ä¿å˜è·¯å¾„ å¦‚æžœä½ çš„å®¢æˆ·ç«¯æ˜¯åœ¨åŽå°è¿è¡Œï¼Œè„±ç¦»ç»ˆç«¯ï¼Œæ¤æ—¶æ— 法å†é€šè¿‡<STDIN>输入验è¯ç 如果设置了该回调函数,且客户端未连接到终端 则客户端会å°è¯•è°ƒç”¨on_input_img_verifycodeæ¥èŽ·å–验è¯ç ä½ å¯ä»¥åœ¨è¯¥å›žè°ƒå‡½æ•°ä¸å°†éªŒè¯ç 图片通过邮件å‘é€åˆ°æ‰‹æœºç«¯ 手机端通过特殊的链接将验è¯ç 最终æ交回webqq $client->img_verifycode_file() = sub{ #$img_verifycode_file是本地验è¯ç 图片路径 #$smtp是一个hash引用,用于设置å‘é€é‚®ç®±ç›¸å…³çš„设置,支æŒçš„key有: #{ # smtp => # user => # pass => # from # from_title # subject # to #} #实际上,采用的是Mail::SendEasy进行邮件å‘é€ï¼Œå‚æ•°å¯ä»¥å‚考cpan Mail::SendEasy my ($img_verifycode_file,$smtp) = @_; }; =item on_new_friend() :lvalue 设置新增好å‹æ—¶çš„回调 $client->on_new_friend = sub{ my $friend = shift; #$friend结构和$client->{qq_database}{user}一致 }; 注æ„,smartqqåšäº†å¾ˆå¤šé™åˆ¶ï¼Œæ–°å¢žå¥½å‹æ—¶å®¢æˆ·ç«¯ä¸ä¸€å®šèƒ½å¤ŸèŽ·å–到新增好å‹çš„ä¿¡æ¯ å¾€å¾€åªèƒ½çŸ¥é“该好å‹çš„uin,这ç§æƒ…况下客户端返回的$friendå¯èƒ½æ˜¯è¿™æ ·çš„一ç§ç»“构: { uin => xxxx, categories => "陌生人", nick => undef, }; =item on_new_group() :lvalue 设置新增群时的回调 $client->on_new_group = sub{ my $group = shift; #$group结构和@{$client->{qq_database}{group}}ä¸çš„å…ƒç´ ä¸€è‡´ }; 注æ„,smartqq有é™åˆ¶ï¼Œæ–°å¢žç¾¤çš„时候客户端ä¸ä¸€å®šèƒ½å¤ŸèŽ·å–åˆ°æ–°ç¾¤çš„ä¿¡æ¯ =item on_new_group_member() :lvalue 设置已有群ä¸æœ‰æ–°æˆå‘˜åŠ 入时的回调 注æ„,腾讯的webqq功能å—é™ï¼Œå·²å˜åœ¨çš„ç¾¤æ–°å¢žåŠ ç¾¤æˆå‘˜æ—¶ï¼Œä¸ä¸€å®šèƒ½å¤ŸèŽ·å–到新æˆå‘˜çš„ä¿¡æ¯ webqq还能够显示å‘é€çš„消æ¯ï¼Œåªæ˜¯æ˜µç§°å˜ä¸ºå‘é€è€…çš„uin smartqq则完全ä¸ä¼šæ˜¾ç¤ºæ–°æˆå‘˜å‘é€çš„æ¶ˆæ¯ ä¸æ˜Žç™½ä¸ºä»€ä¹ˆä¼šè¿™æ ·å,这算腾讯很二的地方么。。 客户端会努力å°è¯•èŽ·å–,但实在获å–ä¸åˆ°åªèƒ½è¿”回一个默认的结构: $default_member = { nick => undef, province=> undef, gender => undef, uin => $member_uin, country => undef, city => undef, card => undef, }; åªèƒ½çŸ¥é“å‘é€è€…çš„uin,其他的全部都是undefï¼Œå› æ¤ï¼Œåœ¨è¿›è¡Œå›žè°ƒå¤„ç†æ—¶ï¼Œä½ 需è¦è€ƒè™‘到这ç§æƒ…况 当客户端é‡æ–°å†æ¬¡ç™»é™†æ—¶ï¼Œä¼šå†æ¬¡èŽ·å–整个群æˆå‘˜ä¿¡æ¯ï¼Œè¿™æ—¶å€™ä¾¿å¯ä»¥å…¨éƒ¨æˆå‘˜ä¿¡æ¯éƒ½èŽ·å–到 新增好å‹ä¹Ÿæœ‰ä¸Šè¿°ç±»ä¼¼çš„情况 $client->on_new_group_member = sub{ my($group,$member) =@_; #$groupå’Œ@{$client->{qq_database}{group}}ä¸å…ƒç´ çš„->{ginfo}一致 #memberå’Œ@{$client->{qq_database}{group}}ä¸å…ƒç´ çš„->{minfo}å…ƒç´ ä¸€è‡´ my $member_nick = defined $member->{nick}?$member->{nick}:"昵称未知"; }; =item login(qq=>$qq,pwd=>$pwd) 客户端登录,登录æˆåŠŸåŽæ‰èƒ½å¤Ÿæ£å¸¸æ”¶å‘消æ¯ï¼Œç™»å½•å¤±è´¥è¯¥å‡½æ•°ä¼šdie,登录æˆåŠŸè¿”回true $client->login(qq=>xxxx, pwd=> xxxx); #pwd是ç»è¿‡md5åŠ å¯†åŽçš„ =item relogin() 客户端长期è¿è¡Œä¸€æ®µæ—¶é—´ï¼Œä¼šæ”¶åˆ°kick的消æ¯è¦æ±‚强制下线 默认情况下客户端会自动调用relogin() å°è¯•é‡æ–°ç™»å½•ï¼Œä½ 也å¯ä»¥æ ¹æ®éœ€è¦ä¸»åŠ¨è¿›è¡Œrelogin 注æ„relogin过程ä¸å¯èƒ½ä¼šéœ€è¦é‡æ–°è¾“入验è¯ç $client->relogin() =item get_qq_from_uin($uin) webqqä¸æ¯ä¸ªqq用户在æ¯ä¸€æ¬¡å®¢æˆ·ç«¯ç™»å½•åŽä½¿ç”¨çš„是一个唯一的uin(一串数å—ï¼‰è¿›è¡Œèº«ä»½æ ‡è¯† åŒä¸€ä¸ªç”¨æˆ·åœ¨å¤šæ¬¡ç™»å½•ä¸uinå¯èƒ½ä¸ä¸€æ ·ï¼Œä½†qqå·ç 是永远ä¸å˜çš„ 通常情况下å‘é€ã€æŽ¥æ”¶æ¶ˆæ¯ä½¿ç”¨uinå³å¯ å½“ä½ éœ€è¦èŽ·å–原始的qqå·æ—¶ï¼Œå¯ä»¥ä½¿ç”¨è¯¥å‡½æ•° my $qq = $client->get_qq_from_uin($uin); $uin通常是包å«åœ¨æŽ¥æ”¶åˆ°çš„消æ¯æˆ–者客户端自己的数æ®åº“ä¸ï¼Œå¯ä»¥å‚考客户端数æ®ç»“构介ç»éƒ¨åˆ† =item send_message($msg) =item send_message(to_uin=>$uin, content=>$content) å‘é€å¥½å‹ä¿¡æ¯ï¼Œå¦‚æžœä¼ é€’ç»™send_messageçš„å‚æ•°åªæœ‰ä¸€ä¸ª$msg 它必须是一个由$client->create_msg()生æˆçš„消æ¯ç»“æž„ my $msg=$client->create_msg(to_uin=>$uin, content=>$content); $client->send_message($msg); æˆ–è€…ä½ å¯ä»¥æŒ‰å¦‚下方å¼ç›´æŽ¥è°ƒç”¨send_message() $client->send_message(to_uin=>$uin, content=>$content); 如果å‘é€å¤±è´¥é»˜è®¤ä¼šå°è¯•é‡æ–°å‘é€ï¼Œæœ€å¤šå°è¯•5次 å‚è§$client->create_msg() =item send_sess_message($msg) =item send_sess_message(to_uin=>$uin,group_code=>$gcode,content=>$content) å‘é€ä¸´æ—¶æ¶ˆæ¯ï¼Œsend_sess_messageçš„å‚æ•°åªæœ‰ä¸€ä¸ª$msg 它必须是由$client->create_sess_msg()生æˆçš„消æ¯ç»“æž„ my $msg=$client->create_sess_msg(to_uin=>$uin, group_code=>$gcode,content=>$content); $client->send_sess_message($msg); æˆ–è€…ä½ å¯ä»¥æŒ‰å¦‚下方å¼ç›´æŽ¥è°ƒç”¨send_sess_message() $client->send_sess_message(to_uin=>$uin, group_code=>$gcode,content=>$content); 如果å‘é€å¤±è´¥é»˜è®¤ä¼šå°è¯•é‡æ–°å‘é€ï¼Œæœ€å¤šå°è¯•5次 å‚è§$client->create_sess_msg() =item send_group_message($msg) =item send_group_message(to_uin=>$uin,content=>$content) å‘é€ç¾¤æ¶ˆæ¯ï¼Œsend_group_messageçš„å‚数如果åªæœ‰ä¸€ä¸ª$msg 它必须是由$client->create_group_msg()生æˆçš„消æ¯ç»“æž„ my $msg=$client->create_group_msg(to_uin=>$uin, content=>$content); $client->send_group_message($msg); æˆ–è€…ä½ å¯ä»¥æŒ‰å¦‚下方å¼ç›´æŽ¥è°ƒç”¨send_group_message() $client->send_group_message(to_uin=>$uin, content=>$content); 如果å‘é€å¤±è´¥é»˜è®¤ä¼šå°è¯•é‡æ–°å‘é€ï¼Œæœ€å¤šå°è¯•5次 å‚è§$client->create_group_msg() =item reply_message($msg,$content) å½“ä½ ä½¿ç”¨send_message() send_sess_message() send_group_message()æ—¶ä¸å¯é¿å…ä½ éœ€è¦è‡ªå·±æž„é€ ä¸€ä¸ªæ¶ˆæ¯ç»“构,需è¦è®¾ç½®æ¶ˆæ¯ç»“æž„ä¸çš„ç›®æ ‡uin和其他一些关键信æ¯ï¼Œè¿™ç§å½¢å¼é€‚åˆä¸»åŠ¨å‘é€æ¶ˆæ¯ 但大部分时候,我们都是倾å‘于收到消æ¯åŽé’ˆå¯¹æ¤æ”¶åˆ°çš„消æ¯è¿›è¡Œå›žå¤ï¼Œè¿™ç§æƒ…况下å¯ä»¥è€ƒè™‘使用 reply_message(),该方法接收两个å‚数,第一个å‚数是接收到的消æ¯ï¼Œç¬¬äºŒä¸ªå‚数是回å¤çš„内容,比如: $client->on_receive_message = sub{ my $msg = shift; $client->reply_message($msg,"hello world"); }; $client->run(); è¿™ç§æ–¹å¼æ›´ä¸ºä¾¿æ·ï¼Œä¸éœ€è¦å…³å¿ƒæ¶ˆæ¯çš„类型,reply_message()支æŒå›žå¤å¥½å‹æ¶ˆæ¯ï¼Œä¸´æ—¶æ¶ˆæ¯å’Œç¾¤æ¶ˆæ¯ 如果回å¤å¤±è´¥é»˜è®¤ä¼šå°è¯•é‡æ–°å‘é€ï¼Œæœ€å¤šå°è¯•5次 =item create_sess_msg(to_uin=>$uin, group_code => $gcode, content=> $content, cb=>sub{...;}) 创建一个群临时消æ¯ï¼Œéœ€è¦è‡³å°‘设置 to_uin #接收者的uin group_code #接收者所在的群的gcode content #å‘é€å†…容,UTF8ç¼–ç 返回一个消æ¯ç»“æž„çš„hash引用: my $sess_msg = $client->create_sess_msg(to_uin=>$uin, content=> $content,); =item create_group_msg(to_uin=>$uin, content=> $content,cb=>sub{...;}) 创建一个群消æ¯ï¼Œéœ€è¦è®¾ç½®çš„å‚æ•° to_uin #ç›®æ ‡ç¾¤çš„uin,和数æ®ç»“æž„ä¸æ到的gidã€æŽ¥æ”¶æ¶ˆæ¯ä¸çš„from_uin呼应 content #å‘é€çš„内容,UTF8ç¼–ç my $group_msg = $client->create_group_msg(to_uin=>$uin, content=> $content,); =item create_msg() 创建一个好å‹æ¶ˆæ¯ï¼Œéœ€è¦è®¾ç½®çš„å‚æ•° to_uin #ç›®æ ‡ç¾¤çš„uin,和接收消æ¯ä¸çš„from_uin呼应 content #å‘é€çš„内容,UTF8ç¼–ç my $msg = $client->create_msg(to_uin=>$uin, content=> $content,); =item welcome() 登录æˆåŠŸåŽï¼ŒèŽ·å–个人信æ¯ï¼Œæ‰“å°ä¸€äº›æ¬¢è¿Žä¿¡æ¯ $client->welcome() =item logout() 注销登陆,webqq一般ä¸éœ€è¦æ³¨é”€ï¼Œè¦é€€å‡ºç›´æŽ¥å…³é—终æ¢å®¢æˆ·ç«¯å³å¯ $client->logout() =item run() 客户端è¿è¡Œçš„æµç¨‹æ˜¯ 1ã€ç™»å½• 2ã€è®¾ç½®ç›¸å…³çš„回调函数 3ã€è¿›å…¥äº‹ä»¶å¾ªçŽ¯ å› æ¤run()往往是放在代ç 最åŽæ‰§è¡Œï¼Œä¸”ä¸å¯ç¼ºå°‘ $client->run() =item search_cookie($cookie_name) 查找指定cookie对应的值,客户端会自动维护所有的cookieä¿¡æ¯ï¼Œè¯¥æ–¹æ³•åŸºæœ¬ç”¨ä¸åˆ° my $cookie_val = $client->search_cookie($cookie_name); =item search_friend($uin) æ ¹æ®æ供的uin在@{ $client->{qq_database}{friends} }ä¸æŸ¥æ‰¾åŒ¹é…的结果, 返回@{ $client->{qq_database}{friends} }ä¸æŸä¸€ä¸ªåŒ¹é…çš„å…ƒç´ my $friend_hash_ref = $client->search_friend($uin); $friend_hash_ref = { flag => #作用未知 uin => #å‘é€æŽ¥æ”¶æ¶ˆæ¯å”¯ä¸€uin categories => #好å‹æ‰€å±žåˆ†ç»„ nick => #好有昵称 face => #作用未知 markname => #好å‹å¤‡æ³¨ is_vip => #是å¦æ˜¯vip vip_level => #vipç‰çº§ } =item search_member_in_group($gcode,$member_uin) æ ¹æ®æ供的gcodeå’Œuin在指定的群里æœç´¢æŒ‡å®šçš„æˆå‘˜ï¼Œè¿”回匹é…的群æˆå‘˜å¼•ç”¨ my $member_hash_ref = $client->search_member_in_group($gcode,$member_uin); $member_hash_ref = { nick => #该æˆå‘˜æ˜µç§° province => #该æˆå‘˜çœä»½ gender => #该æˆå‘˜æ€§åˆ« uin => #该æˆå‘˜uin country => #该æˆå‘˜å›½å®¶ city => #该æˆå‘˜åŸŽå¸‚ }, =item search_stranger($uin) 收到临时消æ¯æ—¶ï¼Œå¯ä»¥æ¶ˆæ¯åŒ…å«çš„uinæŸ¥æ‰¾å¯¹åº”çš„é™Œç”Ÿäººä¿¡æ¯ my $stranger_hash_ref = $client->search_stranger($uin); $stranger_hash_ref = { uin => #uin nick => #昵称 } =item search_group($gcode) æ ¹æ®è®¾ç½®çš„gcode在@{ $client->{qq_database}{group} }ä¸æŸ¥æ‰¾å¯¹åº”çš„ç¾¤ä¿¡æ¯ my $group_hash_ref = $client->search_group($gcode); $group_hash_ref = { face => #作用未知 memo => #ç¾¤ä»‹ç» class => #群类别 fingermemo => # code => #群的gcode,和$client->{qq_database}{group_list}一致 createtime => #群创建时间 flag => # level => #群ç‰çº§ name => #群å称 gid => #群gid ,和$client->{qq_database}{group_list}一致 owner => } =item update_user_info() æ›´æ–°$client->{qq_database}{user},如果为空则åˆå§‹åŒ– 客户端登陆åŽä¼šè°ƒç”¨ä¸€æ¬¡è¯¥æ–¹æ³•ï¼ŒåŽŸåˆ™ä¸Šä½ ä¸éœ€è¦åœ¨ä½¿ç”¨è¿‡ç¨‹ä¸å†æ¬¡è°ƒç”¨è¯¥æ–¹æ³• =item update_friends_info([$friend]) æ›´æ–°$client->{qq_database}{friends} ,如果å‚数为空,则åˆå§‹åŒ– 如果å‚æ•°ä¸ä¸ºç©ºï¼Œåˆ™å¿…须是一个有效的好å‹hash结构的引用,客户端登录完æˆåŽä¼šè°ƒç”¨ä¸€æ¬¡è¯¥æ–¹æ³• åŽŸåˆ™ä¸Šä½ ä¸éœ€è¦ç›´æŽ¥è°ƒç”¨è¯¥æ–¹æ³•ï¼Œå¦‚果需è¦æœç´¢å¥½å‹ä¿¡æ¯ï¼Œè¯·é€šè¿‡$clent->search_friend()进行æ“作 $clent->search_friend()ä¼šæ ¹æ®æŸ¥è¯¢çš„情况自动调用update_friends_info()æ¥æ›´æ–°å®¢æˆ·ç«¯æ•°æ®åº“ =item update_group_info([$group]) æ›´æ–°$client->{qq_database}{group} 如果å‚数为空则åˆå§‹åŒ– 如果å‚æ•°ä¸ä¸ºç©ºï¼Œåˆ™å¿…须是一个有效的群hash结构的引用,客户端登录完æˆåŽä¼šè°ƒç”¨ä¸€æ¬¡è¯¥æ–¹æ³• åŽŸåˆ™ä¸Šä½ ä¸éœ€è¦ç›´æŽ¥è°ƒç”¨è¯¥æ–¹æ³•ï¼Œå¦‚果需è¦æœç´¢å¥½å‹ä¿¡æ¯ï¼Œè¯·é€šè¿‡$clent->search_group()进行æ“作 $clent->search_group()/$clent->search_member_in_group()会自动调用update_group_info()æ¥æ›´æ–°å®¢æˆ·ç«¯æ•°æ®åº“ =item update_group_list_info([$group]) æ›´æ–°$client->{qq_database}{group_list} 如果å‚数为空则åˆå§‹åŒ– åŽŸåˆ™ä¸Šä½ ä¸éœ€è¦ç›´æŽ¥è°ƒç”¨è¯¥æ–¹æ³•ï¼Œå®¢æˆ·ç«¯ä¼šè‡ªå·±ç®¡ç† =item add_job($type,$time,$callback) å®¢æˆ·ç«¯æ·»åŠ å®šæ—¶ä»»åŠ¡ï¼Œå‚数: $type #ä»»æ„å—符串 $time #时间HH:MM::SS $callback #达到指定时刻åŽæ‰§è¡Œçš„动作 $client->add_job("定时任务","11:12",sub{...;}); 该方法继承自Webqq::Client::Cron更多说明å‚è§ä¸‹æ–¹çš„Webqq::Client::Cron =item get_group_code_from_gid($gid) 通过gid查找gcode my $gcode = $client->get_group_code_from_gid($gid); =item get_single_long_nick($uin) 通过uin查找个性ç¾å my $single_long_nick = $client->get_single_long_nick($uin); 返回utf-8ç¼–ç 的个性ç¾å =item load($module1,$module2...) 该方法继承自Webqq::Client::Plugin 客户端æ供了一个简å•çš„æ’件管ç†æ¡†æž¶ è¯¥æ–¹æ³•ç”¨äºŽæŸ¥æ‰¾å¹¶åŠ è½½ä¸€ä¸ªæ’件, $client->load("ShowMsg"); 会自动查找Webqq::Client::Plugin::ShowMsg模å—,并æå–模å—ä¸çš„call函数 更多说明å‚åŠ ä¸‹æ–¹çš„Webqq::Client::Plugin =item call($module,$param1,$param2...) =item call([$module1,$module2,...],$param1,$param2...) 该方法继承自Webqq::Client::Plugin,è¿è¡Œä¸€ä¸ªæˆ–多个æ’件 =item plugin($module) 该方法继承自Webqq::Client::Plugin,返回一个已ç»åŠ 载的模å—çš„call函数引用 $client->load("ShowMsg"); my $code_ref = $client->plugin("ShowMsg"); #执行对应的函数,获å–函数的返回值 my $return = &{$code_ref}(...); ä¸€èˆ¬æƒ…å†µä¸‹ï¼Œä½ å¯ä»¥ä½¿ç”¨$client->call()æ¥æ‰§è¡Œæ’件,但callä¸ä¼šå…³å¿ƒæ’件的返回值 å½“ä½ éœ€è¦èŽ·å–æ’件的返回值,则需è¦é€šè¿‡$client->plugin()获å–到æ’件函数引用,然åŽè‡ªå·±æ‰§è¡Œ =back =head1 PRIVATE CLASS METHOD =over =item _prepare_for_login() =item _check_verify_code() =item _get_img_verify_code() =item _check_sig() =item _login1() =item _login2() =item _get_user_info() =item _get_group_info() =item _get_group_list_info() =item _get_friend_info() =item _get_user_friends() =item _get_discuss_list_info() =item _send_message() =item _send_group_message() =item _get_msg_tip() =item _get_vfwebqq() =item _report() =back =head1 OTHER MODULE =over =item Webqq::Client::Cache 一个简å•çš„缓å˜æ¨¡å—,å¯ä»¥ç¼“å˜ä»»ä½•å†…容,支æŒè®¾ç½®è¿‡æœŸæ—¶é—´ $cache = Webqq::Client::Cache->new; $cache->store('key',{a=>1,b=2,c=>[1,2,3]},30); $cache->retrieve('key');#得到{a=>1,b=2,c=>[1,2,3]} sleep 30; $cache->retrieve('key');#缓å˜å·²è¿‡æœŸï¼Œå¾—到undef =item Webqq::Client::Util æ¤æ¨¡å—导出4个函数 console("UTF-8的内容") #打å°å†…容到STDOUT,会自动检测终端编ç ,以防æ¢ä¹±ç console_stderr("UTF-8的内容") #打å°å†…容到STDERR,会自动检测终端编ç ,以防æ¢ä¹±ç hash() #webqq密ç 生æˆå‡½æ•°ï¼Œæ— 视 truncate($msg_content,max_bytes=>200,max_lines=>3) #截æ–消æ¯ï¼Œé˜²æ¢æ¶ˆæ¯å¤ªé•¿ =item Webqq::Client::Cron 客户端定时执行任务模å—,已被Webqq::Client继承,æä¾›å‚è§$client->add_job() =item Webqq::Client::Plugin 一个简å•çš„客户端æ’件管ç†æ¨¡å—,被Webqq::Client继承,å«å‡ 个方法: 1ã€$client->new() 2ã€$client->load() #åŠ è½½æ’件,例如$client->load("Test");则会查找Webqq::Client::Plugin::Testæ¨¡å— #å¹¶åŠ è½½æ¨¡å—ä¸çš„call()å‡½æ•°ï¼Œå› æ¤ä½ å¼€å‘æ’件模å—应该éµå¾ªè¿™æ ·çš„包命å规则,并且 #模å—ä¸å®šä¹‰äº†call方法,例如: package Webqq::Client::Plugin::Test; sub call{ #$clientå°†æ˜¯åœ¨æ‰§è¡Œæ—¶ä¼ å…¥çš„ç¬¬ä¸€ä¸ªå‚æ•° my $client = shift; } #å¦‚æžœä½ çš„æ¨¡å—ä¸æ˜¯éµå¾ªWebqq::Client::Plugin::å‰ç¼€ï¼Œä½ å¯ä»¥åœ¨load的模å—åå‰é¢æ·»åŠ 一个+å· #例如: $client->load("+MyPakcag::Test"); #则会在@INC里æœç´¢MyPakcag::Testæ¨¡å— 3ã€$client->call() #执行指定æ’件的call函数,例如: $client->load("Test"); $client->call("Test","a","b","c"); #相当于执行Webqq::Client::Plugin::Test::call($client,"a","b","c"); #如果有多个æ’件è¦æ‰§è¡Œï¼Œå¯ä»¥ä½¿ç”¨æ•°ç»„å¼•ç”¨çš„å½¢å¼ $client->call(["Test1","Test2","Test3"],"a","b","c"); #会顺åºæ‰§è¡Œæ¯ä¸€ä¸ªæ’件的call函数 4ã€$client->call_all() #按load的顺åºä¾æ¬¡æ‰§è¡Œæ¯ä¸ªæ’件 $client->load("Test1","Test2","Test3"); $client->call_all("a","b","c"); #相当于ä¾æ¬¡æ‰§è¡Œå¦‚下æ’件 Webqq::Client::Plugin::Test1::call($client,"a","b","c"); Webqq::Client::Plugin::Test2::call($client,"a","b","c"); Webqq::Client::Plugin::Test3::call($client,"a","b","c"); 5ã€$client->plugin() #返回æ’件对应的call函数引用 package Webqq::Client::Plugin::Test; sub call{ #$clientå°†æ˜¯åœ¨æ‰§è¡Œæ—¶ä¼ å…¥çš„ç¬¬ä¸€ä¸ªå‚æ•° my $client = shift; } 1; $client->load("Test"); my $plugin_code_ref = $client->plugin("Test"); $plugin_code_ref是Webqq::Client::Plugin::Test::call()的引用 6ã€$client->clear() å¸è½½å®¢æˆ·ç«¯æ‰€æœ‰æ’件 =item Webqq::Client::Plugin::ShowMsg 打å°æŽ¥æ”¶æˆ–者å‘é€æ¶ˆæ¯çš„æ’件,æ’件调用时需è¦ä¼ 入接收或者å‘é€çš„$msg $client->load("ShowMsg"); $client->on_receive_message = sub{ my $msg = shift; $client->call("ShowMsg",$msg); }; $client->on_send_message =sub { my $msg = shift; my $is_success = shift; my $status = shift; $client->call("ShowMsg",$msg,"[$status]"); }; $client->run(); =item Webqq::Client::Plugin::SendMsgControl =item Webqq::Client::Plugin::PicLimit =item Webqq::Client::Plugin::SmartReply =item Webqq::Client::Plugin::Perlcode =item Webqq::Client::Plugin::Perldoc =item Webqq::Client::Plugin::ShowMsg =item Webqq::Client::Plugin::Msgstat =item Webqq::Client::Plugin::SendMsgFromMsg =item Webqq::Client::Plugin::SendMsgFromSocket =back =head1 SEE ALSO https://github.com/sjdy521/Webqq-Client =head1 AUTHOR Perfi, E<lt>sjdy521@163.comE<gt> =head1 COPYRIGHT AND LICENSE Copyright (C) 2014 by Perfi This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. =cut