1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-12-02 14:37:48 +01:00

Improve message splitting logic
Some checks failed
ci/woodpecker/push/build Pipeline failed
ci/woodpecker/tag/build Pipeline was successful
ci/woodpecker/tag/deploy Pipeline was successful

This commit is contained in:
Daniil Gentili 2023-01-12 14:58:14 +01:00
parent 43c68b3a46
commit d0a0b17b8b
4 changed files with 53 additions and 54 deletions

View File

@ -392,6 +392,9 @@ trait BotAPI
} }
return $arguments; return $arguments;
} }
private const MAX_ENTITY_LENGTH = 100;
private const MAX_ENTITY_SIZE = 8110;
/** /**
* Split too long message into chunks. * Split too long message into chunks.
* *
@ -402,34 +405,41 @@ trait BotAPI
public function splitToChunks($args): array public function splitToChunks($args): array
{ {
$args = $this->parseMode($args); $args = $this->parseMode($args);
if (!isset($args['entities'])) { $args['entities'] ??= [];
$args['entities'] = [];
} var_dump($args);
// UTF-8 length, not UTF-16
$max_length = isset($args['media']) ? $this->config['caption_length_max'] : $this->config['message_length_max']; $max_length = isset($args['media']) ? $this->config['caption_length_max'] : $this->config['message_length_max'];
$max_entity_length = 100; $cur_len = 0;
$max_entity_size = 8110; $cur = '';
$text_arr = [];
foreach ($this->multipleExplodeKeepDelimiters(["\n"], $args['message']) as $word) {
if (\mb_strlen($word, 'UTF-8') > $max_length) {
foreach (StrTools::mbStrSplit($word, $max_length) as $vv) {
$text_arr[] = $vv;
}
} else {
$text_arr[] = $word;
}
}
$multiple_args_base = \array_merge($args, ['entities' => [], 'parse_mode' => 'text', 'message' => '']); $multiple_args_base = \array_merge($args, ['entities' => [], 'parse_mode' => 'text', 'message' => '']);
$multiple_args = [$multiple_args_base]; $multiple_args = [];
$i = 0; foreach (\explode("\n", $args['message']) as $word) {
foreach ($text_arr as $word) { foreach (\mb_str_split($word."\n", $max_length, 'UTF-8') as $vv) {
if (StrTools::mbStrlen($multiple_args[$i]['message'].$word) <= $max_length) { $len = \mb_strlen($vv, 'UTF-8');
$multiple_args[$i]['message'] .= $word; if ($cur_len + $len <= $max_length) {
} else { $cur .= $vv;
$i++; $cur_len += $len;
$multiple_args[$i] = $multiple_args_base; } else {
$multiple_args[$i]['message'] .= $word; if (\trim($cur) !== '') {
$multiple_args[] = [
...$multiple_args_base,
'message' => $cur
];
}
$cur = $vv;
$cur_len = $len;
}
} }
} }
if (\trim($cur) !== '') {
$multiple_args[] = [
...$multiple_args_base,
'message' => $cur
];
}
var_dump($multiple_args);
$i = 0; $i = 0;
$offset = 0; $offset = 0;
for ($k = 0; $k < \count($args['entities']); $k++) { for ($k = 0; $k < \count($args['entities']); $k++) {
@ -480,8 +490,8 @@ trait BotAPI
} }
$total = 0; $total = 0;
foreach ($multiple_args as $args) { foreach ($multiple_args as $args) {
if (\count($args['entities']) > $max_entity_length) { if (\count($args['entities']) > self::MAX_ENTITY_LENGTH) {
$total += \count($args['entities']) - $max_entity_length; $total += \count($args['entities']) - self::MAX_ENTITY_LENGTH;
} }
$c = 0; $c = 0;
foreach ($args['entities'] as $entity) { foreach ($args['entities'] as $entity) {
@ -489,7 +499,7 @@ trait BotAPI
$c += \strlen($entity['url']); $c += \strlen($entity['url']);
} }
} }
if ($c >= $max_entity_size) { if ($c >= self::MAX_ENTITY_SIZE) {
$this->logger->logger('Entity size limit possibly exceeded, you may get an error indicating that the entities are too long. Reduce the number of entities and/or size of the URLs used.', Logger::FATAL_ERROR); $this->logger->logger('Entity size limit possibly exceeded, you may get an error indicating that the entities are too long. Reduce the number of entities and/or size of the URLs used.', Logger::FATAL_ERROR);
} }
} }
@ -498,25 +508,6 @@ trait BotAPI
} }
return $multiple_args; return $multiple_args;
} }
/**
* @return string[]
*
* @psalm-return list<string>
*/
private function multipleExplodeKeepDelimiters($delimiters, $string): array
{
$initialArray = \explode(\chr(1), \str_replace($delimiters, \chr(1), $string));
$finalArray = [];
/** @var int */
$delimOffset = 0;
foreach ($initialArray as $item) {
$delimOffset += StrTools::mbStrlen($item);
/** @var int $delimOffset */
$finalArray[] = $item.($delimOffset < StrTools::mbStrlen($string) ? $string[$delimOffset] : '');
$delimOffset++;
}
return $finalArray;
}
/** /**
* @return ((array|string)[][]|string)[] * @return ((array|string)[][]|string)[]
* *

View File

@ -43,15 +43,15 @@ trait Ads
if ($cache && $cache[0] > \time()) { if ($cache && $cache[0] > \time()) {
return $cache[1]; return $cache[1];
} }
$result = (yield from $this->methodCallAsyncRead('channels.getSponsoredMessages', ['channel' => $peer])); $result = (yield from $this->methodCallAsyncRead('channels.getSponsoredMessages', ['channel' => $peer]));
if (array_key_exists('messages', $result)) { if (\array_key_exists('messages', $result)) {
$result = $result['messages']; $result = $result['messages'];
} else { } else {
$result = null; $result = null;
} }
$this->sponsoredMessages->set($peer, [\time() + 5*60, $result]); $this->sponsoredMessages->set($peer, [\time() + 5*60, $result]);
return $result; return $result;
} }
/** /**
* Mark sponsored message as read. * Mark sponsored message as read.

View File

@ -293,6 +293,9 @@ $MadelineProto->loop(function () use ($MadelineProto) {
$sentMessage = yield $MadelineProto->messages->sendMessage(['peer' => $peer, 'message' => $message, 'entities' => [['_' => 'inputMessageEntityMentionName', 'offset' => 0, 'length' => mb_strlen($message), 'user_id' => $mention]]]); $sentMessage = yield $MadelineProto->messages->sendMessage(['peer' => $peer, 'message' => $message, 'entities' => [['_' => 'inputMessageEntityMentionName', 'offset' => 0, 'length' => mb_strlen($message), 'user_id' => $mention]]]);
$MadelineProto->logger($sentMessage, \danog\MadelineProto\Logger::NOTICE); $MadelineProto->logger($sentMessage, \danog\MadelineProto\Logger::NOTICE);
$sentMessage = yield $MadelineProto->messages->sendMessage(['peer' => $peer, 'message' => str_repeat('a', 4096*4)]);
$MadelineProto->logger($sentMessage, \danog\MadelineProto\Logger::NOTICE);
foreach ($media as $type => $inputMedia) { foreach ($media as $type => $inputMedia) {
if ($type !== 'sticker' && $type !== 'voice') { if ($type !== 'sticker' && $type !== 'voice') {
$MadelineProto->logger("Sending multi $type"); $MadelineProto->logger("Sending multi $type");

View File

@ -4,5 +4,10 @@
"ennexa/amp-update-cache": "dev-master", "ennexa/amp-update-cache": "dev-master",
"phpunit/phpunit": "^9", "phpunit/phpunit": "^9",
"amphp/php-cs-fixer-config": "v2.x-dev" "amphp/php-cs-fixer-config": "v2.x-dev"
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
} }
} }