110 lines
4.5 KiB
PHP
110 lines
4.5 KiB
PHP
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Author: ywxapp<admin@ywxapp.cn>
|
|
// +----------------------------------------------------------------------
|
|
|
|
declare (strict_types = 1);
|
|
|
|
namespace addon\wxchat\wprker\handle;
|
|
|
|
use GatewayWorker\Lib\Gateway;
|
|
|
|
/**
|
|
* MessageHandle 类
|
|
*
|
|
* @author ywxapp <admin@ywxapp.cn>
|
|
*/
|
|
class MessageHandle
|
|
{
|
|
|
|
protected static $sensitiveWords = ['fuck', 'shit', '赌博', '色情'];
|
|
/**
|
|
* 敏感词过滤
|
|
*/
|
|
protected static function filterSensitiveWords($text)
|
|
{
|
|
foreach (self::$sensitiveWords as $word) {
|
|
$text = str_replace($word, '**', $text);
|
|
}
|
|
return $text;
|
|
}
|
|
|
|
/**
|
|
* 处理普通消息(文本/图片/文件)
|
|
*/
|
|
protected static function handle($client_id, $message)
|
|
{
|
|
$header = $message->header;
|
|
$payload = $message->payload;
|
|
|
|
$fromUid = $header->from ?? '';
|
|
$uid = Gateway::getUidByClientId($client_id);
|
|
echo "Received message from UID: $fromUid, ClientID: $client_id , $uid\n";
|
|
if (! $uid || $uid != $fromUid) {
|
|
self::sendError($client_id, '未认证用户,无法发送消息');
|
|
return;
|
|
}
|
|
if ($header->type == 'text' && ! empty($payload->content)) {
|
|
$filteredContent = self::filterSensitiveWords($payload->content);
|
|
if ($filteredContent !== $payload->content) {
|
|
// file_put_contents('/tmp/sensitive_log.log', date('Y-m-d H:i:s') . " {$fromUid} 发送敏感词: {$data['payload']['content']}\n", FILE_APPEND);
|
|
$message->payload->content = $filteredContent;
|
|
}
|
|
}
|
|
// 消息持久化(重要!写入数据库)
|
|
// self::saveMessageToDB($data);
|
|
// 转发消息
|
|
if ($header->subtype === 'single') {
|
|
// 单聊:发送给目标用户
|
|
if (Gateway::isUidOnline($header->to)) {
|
|
|
|
Gateway::sendToUid($header->to, json_encode($message));
|
|
// 发送ACK给发送方(表示已送达)
|
|
$ackMsg = new Message();
|
|
$ackMsg->header->type = MessageType::System;
|
|
$ackMsg->header->subtype = MessageType::Delivered;
|
|
$ackMsg->payload->content = '不支持的消息类型! ';
|
|
Gateway::sendToUid($header->from, json_encode($message));
|
|
} else {
|
|
// 对方不在线,存离线消息(写入Redis/DB)
|
|
// self::saveOfflineMessage($toId, $data);
|
|
|
|
$newMessage = new Message();
|
|
$newMessage->header->type = MessageType::Error;
|
|
$newMessage->payload->content = "用户 {$toId} 不在线,消息已存为离线";
|
|
Gateway::sendToClient($client_id, json_encode($message));
|
|
}
|
|
} elseif ($header->subtype === 'group') {
|
|
// 群聊:发送给群内所有成员(排除自己)
|
|
// TODO: 从数据库获取群成员列表
|
|
// $members = self::getGroupMembers($toId);
|
|
// foreach ($members as $memberUid) {
|
|
// if ($memberUid != $fromUid && Gateway::hasUid($memberUid)) {
|
|
// Gateway::sendToUid($memberUid, json_encode($data));
|
|
// }
|
|
// }
|
|
Gateway::sendToGroup($header->to, json_encode($message));
|
|
|
|
$ackMsg = new Message();
|
|
$ackMsg->header->type = MessageType::System;
|
|
$ackMsg->header->subtype = MessageType::Delivered;
|
|
$ackMsg->payload->content = '不支持的消息类型! ';
|
|
Gateway::sendToUid($header->from, json_encode($message));
|
|
} else {
|
|
$errorMsg = new Message();
|
|
$errorMsg->header->type = MessageType::Error;
|
|
$errorMsg->payload->content = "未知会话类型";
|
|
Gateway::sendToClient($client_id, json_encode($errorMsg));
|
|
return;
|
|
}
|
|
// 回复发送方:消息已接收(前端更新状态用)
|
|
$receivedMsg = new Message();
|
|
$receivedMsg->header->type = MessageType::Error;
|
|
Gateway::sendToClient($client_id, json_encode($receivedMsg));
|
|
}
|
|
}
|