package QQ::weixin::work::kf; =encoding utf8 =head1 Name QQ::weixin::work::kf =head1 DESCRIPTION å¾®ä¿¡å®¢æœ =cut use strict; use base qw(QQ::weixin::work); use Encode; use LWP::UserAgent; use JSON; use utf8; our $VERSION = '0.06'; our @EXPORT = qw/ add_contact_way sync_msg send_msg send_msg_on_event /; =head1 FUNCTION =head2 add_contact_way(access_token, hash); 获å–客æœå¸å·é“¾æŽ¥ =head2 SYNOPSIS L<https://developer.work.weixin.qq.com/document/path/94665> =head3 请求说明: ä¼ä¸šå¯é€šè¿‡æ¤æŽ¥å£èŽ·å–带有ä¸åŒå‚数的客æœé“¾æŽ¥ï¼Œä¸åŒå®¢æœå¸å·å¯¹åº”ä¸åŒçš„客æœé“¾æŽ¥ã€‚获å–åŽï¼Œä¼ä¸šå¯å°†é“¾æŽ¥åµŒå…¥åˆ°ç½‘页ç‰åœºæ™¯ä¸ï¼Œå¾®ä¿¡ç”¨æˆ·ç‚¹å‡»é“¾æŽ¥å³å¯å‘对应的客æœå¸å·å‘起咨询。ä¼ä¸šå¯ä¾æ®å‚æ•°æ¥è¯†åˆ«ç”¨æˆ·çš„咨询æ¥æºç‰ã€‚ =head4 请求包结构体为: { "open_kfid": "OPEN_KFID", "scene": "12345" } =head4 å‚数说明: å‚æ•° å¿…é¡» 类型 说明 access_token 是 string 调用接å£å‡è¯ open_kfid 是 string 客æœå¸å·ID scene å¦ string 场景值,å—符串类型,由开å‘者自定义。 ä¸å¤šäºŽ32å—节 å—符串å–值范围(æ£åˆ™è¡¨è¾¾å¼):[0-9a-zA-Z_-]* 1. è‹¥sceneéžç©ºï¼Œè¿”回的客æœé“¾æŽ¥å¼€å‘者å¯æ‹¼æŽ¥scene_param=SCENE_PARAMå‚数使用,用户进入会è¯äº‹ä»¶ä¼šå°†SCENE_PARAMåŽŸæ ·è¿”å›žã€‚å…¶ä¸SCENE_PARAM需è¦urlencode,且长度ä¸èƒ½è¶…过128å—节。 如 https://work.weixin.qq.com/kf/kfcbf8f8d07ac7215f?enc_scene=ENCGFSDF567DF&scene_param=a%3D1%26b%3D2 2. 历å²è°ƒç”¨æŽ¥å£è¿”回的客æœé“¾æŽ¥ï¼ˆåŒ…å«encScene=XXXå‚数),ä¸æ”¯æŒscene_paramå‚数。 3. 返回的客æœé“¾æŽ¥ï¼Œä¸èƒ½ä¿®æ”¹æˆ–å¤åˆ¶å‚数到其他链接使用。å¦åˆ™è¿›å…¥ä¼šè¯äº‹ä»¶å‚æ•°æ ¡éªŒä¸é€šè¿‡ï¼Œå¯¼è‡´æ— 法回调。 =head3 æƒé™è¯´æ˜Ž ä¼ä¸šéœ€è¦ä½¿ç”¨â€œå¾®ä¿¡å®¢æœâ€secret所获å–çš„accesstokenæ¥è°ƒç”¨ï¼ˆaccesstoken如何获å–?) 第三方应用需具有“微信客æœ->获å–基础信æ¯â€æƒé™ =head3 RETURN 返回结果 { "errcode": 0, "errmsg": "ok", "url":"https://work.weixin.qq.com/kf/kfcbf8f8d07ac7215f?enc_scene=ENCGFSDF567DF" } =head4 RETURN å‚数说明 å‚æ•° 类型 说明 errcode int32 返回ç errmsg string 对返回ç 的文本æ述内容 url string 客æœé“¾æŽ¥ï¼Œå¼€å‘者å¯å°†è¯¥é“¾æŽ¥åµŒå…¥åˆ°H5页é¢ä¸ï¼Œç”¨æˆ·ç‚¹å‡»é“¾æŽ¥å³å¯å‘对应的微信客æœå¸å·å‘起咨询。开å‘者也å¯æ ¹æ®è¯¥url自行生æˆéœ€è¦çš„二维ç 图片 =cut sub add_contact_way { if ( @_ && $_[0] && ref $_[1] eq 'HASH' ) { my $access_token = $_[0]; my $json = $_[1]; my $ua = LWP::UserAgent->new; $ua->timeout(30); $ua->env_proxy; my $response = $ua->post("https://qyapi.weixin.qq.com/cgi-bin/kf/add_contact_way?access_token=$access_token",Content => to_json($json,{allow_nonref=>1}),Content_type =>'application/json'); if ($response->is_success) { return from_json($response->decoded_content,{utf8 => 1, allow_nonref => 1}); } } return 0; } =head2 sync_msg(access_token, hash); 读å–æ¶ˆæ¯ =head2 SYNOPSIS L<https://developer.work.weixin.qq.com/document/path/94670#读å–消æ¯> =head3 请求说明: 微信客户å‘é€çš„消æ¯ã€æŽ¥å¾…人员在ä¼ä¸šå¾®ä¿¡å›žå¤çš„消æ¯ã€å‘é€æ¶ˆæ¯æŽ¥å£å‘é€å¤±è´¥äº‹ä»¶ï¼ˆå¦‚被用户拒收)ã€å®¢æˆ·ç‚¹å‡»èœå•æ¶ˆæ¯çš„回å¤æ¶ˆæ¯ï¼Œå¯ä»¥é€šè¿‡è¯¥æŽ¥å£èŽ·å–具体的消æ¯å†…容和事件。ä¸æ”¯æŒè¯»å–通过å‘é€æ¶ˆæ¯æŽ¥å£å‘é€çš„消æ¯ã€‚ 支æŒçš„消æ¯ç±»åž‹ï¼šæ–‡æœ¬ã€å›¾ç‰‡ã€è¯éŸ³ã€è§†é¢‘ã€æ–‡ä»¶ã€ä½ç½®ã€é“¾æŽ¥ã€å片ã€å°ç¨‹åºã€èœå•ã€äº‹ä»¶ã€‚ 接å£å®šä¹‰ =head4 请求包结构体为: { "cursor": "4gw7MepFLfgF2VC5npN", "token": "ENCApHxnGDNAVNY4AaSJKj4Tb5mwsEMzxhFmHVGcra996NR", "limit": 1000, "voice_format": 0 } =head4 å‚数说明: å‚æ•° å¿…é¡» 类型 说明 access_token 是 string 调用接å£å‡è¯ cursor å¦ string 上一次调用时返回的next_cursor,第一次拉å–å¯ä»¥ä¸å¡«ã€‚ ä¸å¤šäºŽ64å—节 token å¦ string 回调事件返回的tokenå—段,10分钟内有效;å¯ä¸å¡«ï¼Œå¦‚æžœä¸å¡«æŽ¥å£æœ‰ä¸¥æ ¼çš„频率é™åˆ¶ã€‚ ä¸å¤šäºŽ128å—节 limit å¦ uint32 期望请求的数æ®é‡ï¼Œé»˜è®¤å€¼å’Œæœ€å¤§å€¼éƒ½ä¸º1000。 注æ„:å¯èƒ½ä¼šå‡ºçŽ°è¿”回æ¡æ•°å°‘于limit的情况,需结åˆè¿”回的has_moreå—段判æ–是å¦ç»§ç»è¯·æ±‚。 voice_format å¦ uint32 è¯éŸ³æ¶ˆæ¯ç±»åž‹ï¼Œ0-Amr 1-Silk,默认0。å¯é€šè¿‡è¯¥å‚数控制返回的è¯éŸ³æ ¼å¼ =head3 æƒé™è¯´æ˜Ž ä¼ä¸šéœ€è¦ä½¿ç”¨â€œå¾®ä¿¡å®¢æœâ€secret所获å–çš„accesstokenæ¥è°ƒç”¨ï¼ˆaccesstoken如何获å–?) 第三方应用需具有“微信客æœæƒé™->管ç†å¸å·ã€åˆ†é…会è¯å’Œæ”¶å‘消æ¯â€æƒé™ =head3 RETURN 返回结果 { "errcode": 0, "errmsg": "ok", "next_cursor": "4gw7MepFLfgF2VC5npN", "has_more": 1, "msg_list": [ { "msgid": "from_msgid_4622416642169452483", "open_kfid": "wkAJ2GCAAASSm4_FhToWMFea0xAFfd3Q", "external_userid": "wmAJ2GCAAAme1XQRC-NI-q0_ZM9ukoAw", "send_time": 1615478585, "origin": 3, "servicer_userid": "Zhangsan", "msgtype": "MSG_TYPE" } ] } =head4 RETURN å‚数说明 å‚æ•° 类型 说明 errcode int32 返回ç errmsg string 错误ç æè¿° next_cursor string 下次调用带上该值,则从当å‰çš„ä½ç½®ç»§ç»å¾€åŽæ‹‰ï¼Œä»¥å®žçŽ°å¢žé‡æ‹‰å–。 强烈建议对改该å—段入库ä¿å˜ï¼Œæ¯æ¬¡è¯·æ±‚读å–带上,请求结æŸåŽæ›´æ–°ã€‚é¿å…å› æ„外丢,导致必须从头开始拉å–,引起消æ¯å»¶è¿Ÿã€‚ has_more uint32 是å¦è¿˜æœ‰æ›´å¤šæ•°æ®ã€‚0-å¦ï¼›1-是。 ä¸èƒ½é€šè¿‡åˆ¤æ–msg_list是å¦ç©ºæ¥åœæ¢æ‹‰å–,å¯èƒ½ä¼šå‡ºçŽ°has_more为1,而msg_list为空的情况 msg_list obj[] 消æ¯åˆ—表 msg_list.msgid string 消æ¯ID msg_list.open_kfid string 客æœå¸å·ID(msgtype为event,该å—段ä¸è¿”回) msg_list.external_userid string 客户UserID(msgtype为event,该å—段ä¸è¿”回) msg_list.send_time uint64 消æ¯å‘é€æ—¶é—´ msg_list.origin uint32 消æ¯æ¥æºã€‚3-微信客户å‘é€çš„æ¶ˆæ¯ 4-系统推é€çš„äº‹ä»¶æ¶ˆæ¯ 5-接待人员在ä¼ä¸šå¾®ä¿¡å®¢æˆ·ç«¯å‘é€çš„æ¶ˆæ¯ msg_list.servicer_userid string 从ä¼ä¸šå¾®ä¿¡ç»™å®¢æˆ·å‘消æ¯çš„接待人员userid(msgtype为event,该å—段ä¸è¿”回) msg_list.msgtype string 对ä¸åŒçš„msgtype,有相应的结构æ述,下é¢è¿›ä¸€æ¥è¯´æ˜Ž =cut sub sync_msg { if ( @_ && $_[0] && ref $_[1] eq 'HASH' ) { my $access_token = $_[0]; my $json = $_[1]; my $ua = LWP::UserAgent->new; $ua->timeout(30); $ua->env_proxy; my $response = $ua->post("https://qyapi.weixin.qq.com/cgi-bin/kf/sync_msg?access_token=$access_token",Content => to_json($json,{allow_nonref=>1}),Content_type =>'application/json'); if ($response->is_success) { return from_json($response->decoded_content,{utf8 => 1, allow_nonref => 1}); } } return 0; } =head2 send_msg(access_token, hash); 微信客æœ-会è¯åˆ†é…与消æ¯æ”¶å‘-å‘é€æ¶ˆæ¯ =head2 SYNOPSIS L<https://developer.work.weixin.qq.com/document/path/94677> =head3 请求说明: 当微信客户处于“新接入待处ç†â€æˆ–“由智能助手接待â€çŠ¶æ€ä¸‹ï¼Œå¯è°ƒç”¨è¯¥æŽ¥å£ç»™ç”¨æˆ·å‘é€æ¶ˆæ¯ã€‚ 注æ„仅当微信客户在主动å‘é€æ¶ˆæ¯ç»™å®¢æœåŽçš„48å°æ—¶å†…,ä¼ä¸šå¯å‘é€æ¶ˆæ¯ç»™å®¢æˆ·ï¼Œæœ€å¤šå¯å‘é€5æ¡æ¶ˆæ¯ï¼›è‹¥ç”¨æˆ·ç»§ç»å‘é€æ¶ˆæ¯ï¼Œä¼ä¸šå¯å†æ¬¡ä¸‹å‘消æ¯ã€‚ 支æŒå‘é€æ¶ˆæ¯ç±»åž‹ï¼šæ–‡æœ¬ã€å›¾ç‰‡ã€è¯éŸ³ã€è§†é¢‘ã€æ–‡ä»¶ã€å›¾æ–‡ã€å°ç¨‹åºã€èœå•æ¶ˆæ¯ã€åœ°ç†ä½ç½®ã€‚ ç›®å‰è¯¥æŽ¥å£å…许下å‘消æ¯æ¡æ•°å’Œä¸‹å‘æ—¶é™å¦‚下: 用户动作 å…许下å‘æ¡æ•°é™åˆ¶ 下å‘æ—¶é™ ç”¨æˆ·å‘é€æ¶ˆæ¯ 5æ¡ 48 å°æ—¶ =head4 请求包结构体为: =head4 å‚数说明: å‚æ•° å¿…é¡» 类型 说明 access_token 是 string 调用接å£å‡è¯ =head3 æƒé™è¯´æ˜Ž ä¼ä¸šéœ€è¦ä½¿ç”¨â€œå¾®ä¿¡å®¢æœâ€secret所获å–çš„accesstokenæ¥è°ƒç”¨ï¼ˆaccesstoken如何获å–?) 第三方应用需具有“微信客æœæƒé™->管ç†å¸å·ã€åˆ†é…会è¯å’Œæ”¶å‘消æ¯â€æƒé™ =head3 RETURN 返回结果 { "errcode": 0, "errmsg": "ok", "msgid": "MSG_ID" } =head4 RETURN å‚数说明 å‚æ•° 类型 说明 errcode int32 返回ç errmsg string 错误ç æè¿° msgid string 消æ¯ID。如果请求å‚数指定了msgidï¼Œåˆ™åŽŸæ ·è¿”å›žï¼Œå¦åˆ™ç³»ç»Ÿè‡ªåŠ¨ç”Ÿæˆå¹¶è¿”回。若指定msgid,开å‘者需确ä¿å®¢æœè´¦å·å†…唯一,å¦åˆ™æŽ¥å£è¿”回错误。 ä¸å¤šäºŽ32å—节 å—符串å–值范围(æ£åˆ™è¡¨è¾¾å¼):[0-9a-zA-Z_-]* =cut sub send_msg { if ( @_ && $_[0] && ref $_[1] eq 'HASH' ) { my $access_token = $_[0]; my $json = $_[1]; my $ua = LWP::UserAgent->new; $ua->timeout(30); $ua->env_proxy; my $response = $ua->post("https://qyapi.weixin.qq.com/cgi-bin/kf/send_msg?access_token=$access_token",Content => to_json($json,{allow_nonref=>1}),Content_type =>'application/json'); if ($response->is_success) { return from_json($response->decoded_content,{utf8 => 1, allow_nonref => 1}); } } return 0; } =head2 send_msg_on_event(access_token, hash); 微信客æœ-会è¯åˆ†é…与消æ¯æ”¶å‘-å‘é€æ¬¢è¿Žè¯ç‰äº‹ä»¶å“åº”æ¶ˆæ¯ =head2 SYNOPSIS L<https://developer.work.weixin.qq.com/document/path/95122> =head3 请求说明: 当特定的事件回调消æ¯åŒ…å«codeå—段,或通过接å£å˜æ›´åˆ°ç‰¹å®šçš„会è¯çŠ¶æ€ï¼Œä¼šè¿”回codeå—段。 å¼€å‘者å¯ä»¥æ¤code为å‡è¯ï¼Œè°ƒç”¨è¯¥æŽ¥å£ç»™ç”¨æˆ·å‘é€ç›¸åº”事件场景下的消æ¯ï¼Œå¦‚客æœæ¬¢è¿Žè¯ã€å®¢æœæ示è¯å’Œä¼šè¯ç»“æŸè¯ç‰ã€‚ 除"用户进入会è¯äº‹ä»¶"以外,å“应消æ¯ä»…支æŒä¼šè¯å¤„于获å–该code的会è¯çŠ¶æ€æ—¶å‘é€ï¼Œå¦‚将会è¯è½¬å…¥å¾…æŽ¥å…¥æ± æ—¶èŽ·å¾—çš„code仅能在会è¯çŠ¶æ€ä¸ºâ€å¾…æŽ¥å…¥æ± æŽ’é˜Ÿä¸â€œæ—¶å‘é€ã€‚ ç›®å‰æ”¯æŒçš„事件场景和相关约æŸå¦‚下: 事件场景 å…许下å‘æ¡æ•° code有效期 支æŒçš„消æ¯ç±»åž‹ 获å–code途径 用户进入会è¯ï¼Œç”¨äºŽå‘é€å®¢æœæ¬¢è¿Žè¯ 1æ¡ 20秒 文本ã€èœå• 事件回调 è¿›å…¥æŽ¥å¾…æ± ï¼Œç”¨äºŽå‘é€æŽ’队æ示è¯ç‰ 1æ¡ 48å°æ—¶ 文本 转接会è¯æŽ¥å£ ä»ŽæŽ¥å¾…æ± æŽ¥å…¥ä¼šè¯ï¼Œç”¨äºŽå‘é€éžå·¥ä½œæ—¶é—´çš„æ示è¯æˆ–超时未回å¤çš„æ示è¯ç‰ 1æ¡ 48å°æ—¶ 文本 事件回调ã€è½¬æŽ¥ä¼šè¯æŽ¥å£ 结æŸä¼šè¯ï¼Œç”¨äºŽå‘é€ç»“æŸä¼šè¯æ示è¯æˆ–满æ„åº¦è¯„ä»·ç‰ 1æ¡ 20秒 文本ã€èœå• 事件回调ã€è½¬æŽ¥ä¼šè¯æŽ¥å£ =head4 请求包结构体为: { "code": "CODE", "msgid": "MSG_ID", "msgtype": "MSG_TYPE" } =head4 å‚数说明: å‚æ•° å¿…é¡» 类型 说明 access_token 是 string 调用接å£å‡è¯ code 是 string 事件å“应消æ¯å¯¹åº”çš„code。通过事件回调下å‘,仅å¯ä½¿ç”¨ä¸€æ¬¡ã€‚ msgid å¦ string 消æ¯ID。如果请求å‚数指定了msgidï¼Œåˆ™åŽŸæ ·è¿”å›žï¼Œå¦åˆ™ç³»ç»Ÿè‡ªåŠ¨ç”Ÿæˆå¹¶è¿”回。 ä¸å¤šäºŽ32å—节 å—符串å–值范围(æ£åˆ™è¡¨è¾¾å¼):[0-9a-zA-Z_-]* msgtype 是 string 消æ¯ç±»åž‹ã€‚对ä¸åŒçš„msgtype,有相应的结构æ述,详è§æ¶ˆæ¯ç±»åž‹ 「进入会è¯äº‹ä»¶ã€å“应消æ¯ï¼š 如果满足通过API下å‘欢迎è¯æ¡ä»¶ï¼ˆæ¡ä»¶ä¸ºï¼šç”¨æˆ·åœ¨è¿‡åŽ»48å°æ—¶é‡Œæœªæ”¶è¿‡æ¬¢è¿Žè¯ï¼Œä¸”未å‘客æœå‘过消æ¯ï¼‰ï¼Œåˆ™ç”¨æˆ·è¿›å…¥ä¼šè¯äº‹ä»¶ä¼šé¢å¤–返回一个welcome_code,开å‘者以æ¤ä¸ºå‡æ®è°ƒç”¨æŽ¥å£ï¼ˆå¡«åˆ°è¯¥æŽ¥å£codeå‚数),å³å¯å‘客户å‘é€å®¢æœæ¬¢è¿Žè¯ã€‚ =head3 æƒé™è¯´æ˜Ž ä¼ä¸šéœ€è¦ä½¿ç”¨â€œå¾®ä¿¡å®¢æœâ€secret所获å–çš„accesstokenæ¥è°ƒç”¨ï¼ˆaccesstoken如何获å–?) 第三方应用需具有“微信客æœæƒé™->管ç†å¸å·ã€åˆ†é…会è¯å’Œæ”¶å‘消æ¯â€æƒé™ =head3 RETURN 返回结果 { "errcode": 0, "errmsg": "ok", "msgid": "MSG_ID" } =head4 RETURN å‚数说明 å‚æ•° 类型 说明 errcode int32 返回ç errmsg string 错误ç æè¿° msgid string 消æ¯ID =cut sub send_msg_on_event { if ( @_ && $_[0] && ref $_[1] eq 'HASH' ) { my $access_token = $_[0]; my $json = $_[1]; my $ua = LWP::UserAgent->new; $ua->timeout(30); $ua->env_proxy; my $response = $ua->post("https://qyapi.weixin.qq.com/cgi-bin/kf/send_msg_on_event?access_token=$access_token",Content => to_json($json,{allow_nonref=>1}),Content_type =>'application/json'); if ($response->is_success) { return from_json($response->decoded_content,{utf8 => 1, allow_nonref => 1}); } } return 0; } 1; __END__