# 消息管理

消息指用户发来的文本消息、图片消息、视频消息等,本章学习如何使用组件快速操作消息管理。

微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。

# 接收普通消息

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

# 消息类型

获取用户发送的消息类型,微信提供的消息类型请查看上面的微信官方文档查看。 在任何组件中都可以获取消息类型,比如 MessageMaterial 等等组件。

//消息管理模块
$instance = new Message;
$instance->getMessageType();

# 获取消息

获取消息内容可以使用几种方法:

  1. 通过content方法获取微信消息中的变量
$instance->content('Content');
  1. 使用属性方式获取。
$instance->->Content;
  1. getMessage()函数获取消息内容。
$instance->getMessage('MsgType');
# 不传递参数时获取所有微信返回的消息
$instance->getMessage();

# 文本消息

//消息管理模块
$instance = new Message;
//判断是否是文本消息
if ($instance->isTextMsg())
{
	//向用户回复消息
	return $instance->text('后盾人收到你的消息了...:' . $instance->Content);
}

# 图片消息

//判断是否是图片消息
if ($instance->isImageMsg())
{
	//向用户回复消息
	return $instance->text("图片url:{$instance->PicUrl},图片MediaId: {$instance->MediaId}");
}

# 语音消息

//判断是否是语音消息
if ($instance->isVoiceMsg())
{
	//向用户回复消息
	return $instance->text("你发送的语音消息MediaId: {$instance->MediaId} ,语音格式: {$instance->Format}");
}

# 地理位置

第三方在收到地理位置上报信息之后,只需要回复success表明收到即可,是不允许回复消息给粉丝的

//判断是否是地理位置消息
if ($instance->isLocationMsg())
{
	return $instance->text("你发送的地理位置消息,纬度: {$instance->Location_X} ,经度: {$instance->Location_Y},缩放级别: {$instance->Scale},位置: {$instance->Label}");
}

# 链接消息

微信默认将链接做为文本使用,所以链接消息指微信收藏夹中的消息

//判断是否是链接消息
if ($instance->isLinkMsg())
{
	//向用户回复消息
	return $instance->text("你发送的链接消息,标题: {$instance->Title},接要: {$instance->Description} ,链接: {$instance->Url}");
}

# 视频消息

视频指用手机拍摄的视频

//判断是否是视频消息
if ($instance->isVideoMsg())
{
	//向用户回复消息
	return $instance->text("你发送的视频消息 MediaId: {$instance->MediaId} ,缩略图的媒体id: {$instance->ThumbMediaId}");
}

# 小视频消息

用手机微信拍摄的小视频

//判断是否是小视频消息
if ($instance->isSmallVideoMsg())
{
	//获取消息内容
	$contents = $instance->getMessage();
	//向用户回复消息
	return $instance->text("你发送的小视频消息 MediaId: {$contents->MediaId} ,缩略图的媒体id: {$contents->ThumbMediaId}");
}

# 接收事件推送

在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者在开发者中心处设置的服务器地址,从而开发者可以获取到该信息。其中,某些事件推送在发生后,是允许开发者回复用户的,某些则不允许。

# 关注

用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑。

微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。

假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。

//消息管理模块
$instance = new Message;
//判断是否是关注事件
if ($instance->isSubscribeEvent())
{
	//向用户回复消息
	$instance->text("感谢你关注后盾网微信");
}

# 取消关注

网站捕获取消关注事件后可以对粉丝等数据进行后续处理。

//消息管理模块
$instance = new Message;
//判断是否是取消关注事件
if ($instance->isUnSubscribeEvent())
{
	//网站做后续处理...
}

# 扫描二维码事件

用户未关注时,进行关注后的事件推送

未关注时扫描二维码并点击了关注时触发此事件。如果在些事件处理之前设置了关注事件,那么这个事件不会被执行。如果关注事件与扫码关注事件都有情况下,将扫码关注事件放在关注事件前面处理。

//消息管理模块
$instance = new Message;
//未关注用户扫描二维码事件
if ($instance->isSubscribeScanEvent())
{
	//获取消息内容
	$message = $instance->getMessage();
	//向用户回复消息
	$instance->text("未关注用户扫描二维码关注了后盾网,EventKey: {$message->EventKey} ,二维码的Ticket: {$message->Ticket}");
}

用户已关注时的事件推送

已经关注的用户扫描了创建的微信二维码时触发这个事件。

//消息管理模块
$instance = new Message;
//关注用户扫描二维码事件
if ($instance->isScanEvent())
{
	//获取消息内容
	$message = $instance->getMessage();
	//向用户回复消息
	$instance->text("已关注用户扫描二维码,EventKey: {$message->EventKey} ,二维码的Ticket: {$message->Ticket}");
}

# 上报地理位置消息

用户同意上报地理位置后,每次进入公众号会话时,都会在进入时上报地理位置,或在进入会话后每5秒上报一次地理位置,公众号可以在公众平台网站中修改以上设置。上报地理位置时,微信会将上报地理位置事件推送到开发者填写的URL。

//消息管理模块
$instance = new Message;
//关注用户扫描二维码事件
if ($instance->isLocationEvent())
{
	//获取消息内容
	$message = $instance->getMessage();
	//向用户回复消息
	$instance->text("上报地理位置事件,纬度: {$message->Latitude} ,经度: {$message->Longitude}");
}

# 被动回复消息

当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。

# 回复文本消息

//消息管理模块
$instance = new Message;
//关注用户扫描二维码事件
if ($instance->isTextMsg())
{
	$message  = $instance->getMessage();
	//向用户回复消息
    return $instance->text("你发送的内容是".$message->Content);
}

# 回复图文消息

从2018年10月12日起,微信公众平台图文消息被限制为1条。

if ($instance->isTextMsg())
{
	//向用户回复消息
	$news=array(
		array(
			'title'=>'后盾人',
			'discription'=>'后盾人 人人做后盾',
			'picurl'=>'http://www.houdunwang.com/1.jpg',
			'url'=>'点击图文消息跳转链接'
		),	
		array(
			'title'=>'后盾云',
			'discription'=>'后盾云 快人一步',
			'picurl'=>'http://www.houdunyun.cn/2.jpg',
			'url'=>'点击图文消息跳转链接'
		),	
	)
   return $instance->news($news);
}

# 回复语音消息

if ($instance->isTextMsg())
{
	//向用户回复消息
	//$media_id 通过素材管理接口上传多媒体文件得到的media_id
   return $instance->voice($media_id);
}

# 回复视频消息

//关注用户扫描二维码事件
if ($instance->isTextMsg())
{
	//向用户回复消息
	//$video=array('media_id'=>'素材id','title'=>'视频标题','description'=>'描述');
  return $instance->video($video);
}

# 回复音乐消息

//关注用户扫描二维码事件
if ($instance->isTextMsg())
{
	//向用户回复消息
	//$video=array('title'=>'音乐标题','description'=>'描述','musicurl'=>'音乐链接','hqmusicurl'=>'高质量音乐链接,WIFI环境优先使用该链接播放音乐','thumbmediaid'=>'缩略图的媒体id,通过素材管理接口上传多媒体文件');
  return $instance->video($video);
}

# 消息群发

微信为订阅号提供了每天一条的群发权限,为服务号提供每月(自然月)4条的群发权限。 开发者可以使用预览接口校对消息样式和排版,通过预览接口可发送编辑好的消息给指定用户校验效果。

本接口中所有使用到media_id的地方,现在都可以使用素材管理中的永久素材media_id了。

# 消息预览

下面演示是图文消息的预览,如果想发送图片等消息预览,开发者可以查看微信官方文档的数据结构。

$data = [
	"touser"  => "oGiQGuMR-fR_WeD6gLRKnqgMxYGo",
	"mpnews"  => [
		"media_id" => "vwkQqqBXrV7ND7wUu-tCnL4Lb6Zqb-MymQA7dZbt4rU",
	],
	"msgtype" => "mpnews",
];
//消息管理模块
$instance = new Message;
$instance->preview($data);

# 群发消息

群发是将已经上传到微信的素材发送给粉丝,所以需要先行上传素材。

$data = [
	"filter"			=> [
		"is_to_all" 	=> true,
	],
	"mpnews"              => [
		"media_id" => "vwkQqqBXrV7ND7wUu-tCnL4Lb6Zqb-MymQA7dZbt4rU",
	],
	"msgtype"             => "mpnews",
	"send_ignore_reprint" => 0,
];
$res  = (new Message)->sendAll($data);

# 删除群发

群发之后,随时可以通过该接口删除群发。只有已经发送成功的消息才能删除,删除群发消息只能删除图文消息和视频消息,其他类型的消息一经发送,无法删除。

$data = [
	//群发消息的编号
	"msg_id":30124
];
(new Message)>delMassMessage($data);

返回说明

[
   "errcode"=>0,
   "errmsg"=>"ok"
]

# 查询群发消息发送状态

$data = [
	//群发消息的编号
	"msg_id":30124
];
(new Message)->getMassMessageState($data);

返回状态

[
   "msg_id"=>201053012,
   "msg_status"=>"SEND_SUCCESS"
]

# 事件推送群发结果

由于群发任务提交后,群发任务可能在一定时间后才完成,因此,群发接口调用时,仅会给出群发任务是否提交成功的提示,若群发任务提交成功,则在群发任务结束时,会向开发者在公众平台填写的开发者URL(callback URL)推送事件。

需要注意,由于群发任务彻底完成需要较长时间,将会在群发任务即将完成的时候,就推送群发结果,此时的推送人数数据将会与实际情形存在一定误差。

//判断是否是群发消息推送事件
if ($instance->isMassMessage())
{
	//执行处理代码...
}