Skip to content

Commit f5acd0e

Browse files
committed
Added editBotInfo & editChat & getVideoAttachmentDetails
1 parent 8fa63fa commit f5acd0e

15 files changed

+627
-66
lines changed

README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22

33
[![Actions status](https://github.com/BushlanovDev/max-bot-api-client-php/actions/workflows/ci.yml/badge.svg?style=flat-square)](https://github.com/BushlanovDev/max-bot-api-client-php/actions)
44
[![Coverage](https://raw.githubusercontent.com/BushlanovDev/max-bot-api-client-php/refs/heads/master/badge-coverage.svg?v=1)](https://github.com/BushlanovDev/max-bot-api-client-php/actions)
5+
[![Packagist Version](https://img.shields.io/packagist/v/bushlanov-dev/max-bot-api-client-php.svg?style=flat-square)](https://packagist.org/packages/bushlanov-dev/max-bot-api-client-php)
56
[![PHP version](https://img.shields.io/badge/php-%3E%3D%208.3-8892BF.svg?style=flat-square)](https://github.com/BushlanovDev/max-bot-api-client-php)
67
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
78

89
> [!CAUTION]
910
> На мой взгляд `Max Messenger` является ни чем иным как малварью, созданной для слежки за гражданами РФ. Настоятельно
1011
> не рекомендую использовать его на реальных устройствах, с настоящим номером телефона, и для личной переписки.
1112
12-
> [!IMPORTANT]
13-
> Библиотека в стадии активной разработки.
14-
1513
## Быстрый старт
1614

1715
> Если вы новичок, то можете прочитать [официальную документацию](https://dev.max.ru/), написанную разработчиками Max.
@@ -81,14 +79,14 @@ $webhookHandler->addHandler(UpdateType::BotStarted, function (BotStartedUpdate $
8179
#### Bots
8280

8381
- [x] `GET /me` (`getBotInfo`) - *Получение информации о боте.*
84-
- [ ] `PATCH /me` (`editBotInfo`) - *Редактирование информации о боте.*
82+
- [x] `PATCH /me` (`editBotInfo`) - *Редактирование информации о боте.*
8583

8684
#### Chats
8785

8886
- [x] `GET /chats` (`getChats`) - *Получение списка всех чатов бота.*
8987
- [x] `GET /chats/{chatLink}` (`getChatByLink`) - *Получение информации о чате по ссылке.*
9088
- [x] `GET /chats/{chatId}` (`getChat`) - *Получение информации о чате по ID.*
91-
- [ ] `PATCH /chats/{chatId}` (`editChat`) - *Редактирование информации о чате.*
89+
- [x] `PATCH /chats/{chatId}` (`editChat`) - *Редактирование информации о чате.*
9290
- [x] `DELETE /chats/{chatId}` (`deleteChat`) - *Удаление чата.*
9391
- [x] `POST /chats/{chatId}/actions` (`sendAction`) - *Отправка действия в чат (например, "печатает...").*
9492
- [x] `GET /chats/{chatId}/pin` (`getPinnedMessage`) - *Получение закрепленного сообщения.*
@@ -121,7 +119,7 @@ $webhookHandler->addHandler(UpdateType::BotStarted, function (BotStartedUpdate $
121119
- [x] `PUT /messages` (`editMessage`) - *Редактирование сообщения.*
122120
- [x] `DELETE /messages` (`deleteMessage`) - *Удаление сообщения.*
123121
- [x] `GET /messages/{messageId}` (`getMessageById`) - *Получение сообщения по ID.*
124-
- [ ] `GET /videos/{videoToken}` (`getVideoAttachmentDetails`) - *Получение детальной информации о видео.*
122+
- [x] `GET /videos/{videoToken}` (`getVideoAttachmentDetails`) - *Получение детальной информации о видео.*
125123
- [x] `POST /answers` (`answerOnCallback`) - *Ответ на нажатие callback-кнопки.*
126124

127125
## Лицензия

src/Api.php

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,21 @@
1919
use BushlanovDev\MaxMessengerBot\Models\Attachments\Requests\PhotoAttachmentRequest;
2020
use BushlanovDev\MaxMessengerBot\Models\Attachments\Requests\VideoAttachmentRequest;
2121
use BushlanovDev\MaxMessengerBot\Models\BotInfo;
22+
use BushlanovDev\MaxMessengerBot\Models\BotPatch;
2223
use BushlanovDev\MaxMessengerBot\Models\Chat;
2324
use BushlanovDev\MaxMessengerBot\Models\ChatAdmin;
2425
use BushlanovDev\MaxMessengerBot\Models\ChatList;
2526
use BushlanovDev\MaxMessengerBot\Models\ChatMember;
2627
use BushlanovDev\MaxMessengerBot\Models\ChatMembersList;
28+
use BushlanovDev\MaxMessengerBot\Models\ChatPatch;
2729
use BushlanovDev\MaxMessengerBot\Models\Message;
2830
use BushlanovDev\MaxMessengerBot\Models\MessageLink;
2931
use BushlanovDev\MaxMessengerBot\Models\Result;
3032
use BushlanovDev\MaxMessengerBot\Models\Subscription;
3133
use BushlanovDev\MaxMessengerBot\Models\UpdateList;
3234
use BushlanovDev\MaxMessengerBot\Models\Updates\AbstractUpdate;
3335
use BushlanovDev\MaxMessengerBot\Models\UploadEndpoint;
36+
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
3437
use InvalidArgumentException;
3538
use LogicException;
3639
use Psr\Http\Message\ServerRequestInterface;
@@ -51,7 +54,7 @@ class Api
5154
private const string METHOD_GET = 'GET';
5255
private const string METHOD_POST = 'POST';
5356
private const string METHOD_DELETE = 'DELETE';
54-
// private const string METHOD_PATCH = 'PATCH';
57+
private const string METHOD_PATCH = 'PATCH';
5558
private const string METHOD_PUT = 'PUT';
5659

5760
private const string ACTION_ME = '/me';
@@ -67,6 +70,7 @@ class Api
6770
private const string ACTION_CHATS_MEMBERS = '/chats/%d/members';
6871
private const string ACTION_UPDATES = '/updates';
6972
private const string ACTION_ANSWERS = '/answers';
73+
private const string ACTION_VIDEO_DETAILS = '/videos/%s';
7074

7175
private readonly ClientApiInterface $client;
7276

@@ -1068,6 +1072,81 @@ public function editMessage(
10681072
);
10691073
}
10701074

1075+
/**
1076+
* Edits the bot info.
1077+
*
1078+
* Example: editBotInfo(new BotPatch(name: 'New Bot Name', description: null));
1079+
*
1080+
* @param BotPatch $botPatch
1081+
*
1082+
* @return BotInfo
1083+
* @throws ClientApiException
1084+
* @throws NetworkException
1085+
* @throws ReflectionException
1086+
* @throws SerializationException
1087+
*/
1088+
public function editBotInfo(BotPatch $botPatch): BotInfo
1089+
{
1090+
return $this->modelFactory->createBotInfo(
1091+
$this->client->request(
1092+
self::METHOD_PATCH,
1093+
self::ACTION_ME,
1094+
[],
1095+
$botPatch->toArray(),
1096+
)
1097+
);
1098+
}
1099+
1100+
/**
1101+
* Edits chat info such as title, icon, etc.
1102+
* Instantiate ChatPatch with named arguments for the fields you want to change.
1103+
*
1104+
* Example:
1105+
* $patch = new ChatPatch(title: 'New Cool Title');
1106+
* $api->editChat(12345, $patch);
1107+
*
1108+
* @param int $chatId The identifier of the chat to edit.
1109+
* @param ChatPatch $chatPatch An object containing the fields to update.
1110+
*
1111+
* @return Chat
1112+
* @throws ClientApiException
1113+
* @throws NetworkException
1114+
* @throws ReflectionException
1115+
* @throws SerializationException
1116+
*/
1117+
public function editChat(int $chatId, ChatPatch $chatPatch): Chat
1118+
{
1119+
return $this->modelFactory->createChat(
1120+
$this->client->request(
1121+
self::METHOD_PATCH,
1122+
self::ACTION_CHATS . '/' . $chatId,
1123+
[],
1124+
$chatPatch->toArray(),
1125+
)
1126+
);
1127+
}
1128+
1129+
/**
1130+
* Returns detailed information about a video attachment, including playback URLs.
1131+
*
1132+
* @param string $videoToken The token of the video attachment.
1133+
*
1134+
* @return VideoAttachmentDetails
1135+
* @throws ClientApiException
1136+
* @throws NetworkException
1137+
* @throws ReflectionException
1138+
* @throws SerializationException
1139+
*/
1140+
public function getVideoAttachmentDetails(string $videoToken): VideoAttachmentDetails
1141+
{
1142+
return $this->modelFactory->createVideoAttachmentDetails(
1143+
$this->client->request(
1144+
self::METHOD_GET,
1145+
sprintf(self::ACTION_VIDEO_DETAILS, $videoToken),
1146+
)
1147+
);
1148+
}
1149+
10711150
/**
10721151
* A helper to build the 'NewMessageBody' array structure consistently.
10731152
*

src/ModelFactory.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use BushlanovDev\MaxMessengerBot\Models\Updates\UserAddedToChatUpdate;
2828
use BushlanovDev\MaxMessengerBot\Models\Updates\UserRemovedFromChatUpdate;
2929
use BushlanovDev\MaxMessengerBot\Models\UploadEndpoint;
30+
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
3031
use LogicException;
3132
use ReflectionException;
3233

@@ -234,4 +235,17 @@ public function createChatMembersList(array $data): ChatMembersList
234235
{
235236
return ChatMembersList::fromArray($data);
236237
}
238+
239+
/**
240+
* Creates a VideoAttachmentDetails object from raw API data.
241+
*
242+
* @param array<string, mixed> $data
243+
*
244+
* @return VideoAttachmentDetails
245+
* @throws ReflectionException
246+
*/
247+
public function createVideoAttachmentDetails(array $data): VideoAttachmentDetails
248+
{
249+
return VideoAttachmentDetails::fromArray($data);
250+
}
237251
}

src/Models/AbstractModel.php

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,65 @@ public static function fromArray(array $data): static
4242
return new static(...$constructorArgs); // @phpstan-ignore-line
4343
}
4444

45+
/**
46+
* @return array<string, mixed>
47+
* @throws ReflectionException
48+
*/
49+
public function toArray(): array
50+
{
51+
$reflectionClass = new ReflectionClass($this);
52+
$properties = $reflectionClass->getProperties(ReflectionProperty::IS_PUBLIC);
53+
$result = [];
54+
55+
foreach ($properties as $property) {
56+
if (!$property->isInitialized($this)) {
57+
continue;
58+
}
59+
60+
$phpPropertyName = $property->getName();
61+
$value = $property->getValue($this);
62+
63+
$jsonKey = self::toSnakeCase($phpPropertyName);
64+
65+
$result[$jsonKey] = $this->convertValue($value);
66+
}
67+
68+
return $result;
69+
}
70+
71+
/**
72+
* @param string $input
73+
*
74+
* @return string
75+
*/
76+
protected static function toSnakeCase(string $input): string
77+
{
78+
return strtolower((string)preg_replace('/(?<!^)[A-Z]/', '_$0', $input));
79+
}
80+
81+
/**
82+
* @param mixed $value
83+
*
84+
* @return mixed
85+
* @throws ReflectionException
86+
*/
87+
protected function convertValue(mixed $value): mixed
88+
{
89+
if ($value instanceof AbstractModel) {
90+
return $value->toArray();
91+
}
92+
93+
if (is_array($value)) {
94+
return array_map([$this, 'convertValue'], $value);
95+
}
96+
97+
if ($value instanceof BackedEnum) {
98+
return $value->value;
99+
}
100+
101+
return $value;
102+
}
103+
45104
/**
46105
* @param mixed $value
47106
* @param ReflectionProperty $property
@@ -114,63 +173,4 @@ private static function castArray(mixed $value, ReflectionProperty $property): a
114173

115174
return $value;
116175
}
117-
118-
/**
119-
* @param string $input
120-
*
121-
* @return string
122-
*/
123-
private static function toSnakeCase(string $input): string
124-
{
125-
return strtolower((string)preg_replace('/(?<!^)[A-Z]/', '_$0', $input));
126-
}
127-
128-
/**
129-
* @return array<string, mixed>
130-
* @throws ReflectionException
131-
*/
132-
public function toArray(): array
133-
{
134-
$reflectionClass = new ReflectionClass($this);
135-
$properties = $reflectionClass->getProperties(ReflectionProperty::IS_PUBLIC);
136-
$result = [];
137-
138-
foreach ($properties as $property) {
139-
if (!$property->isInitialized($this)) {
140-
continue;
141-
}
142-
143-
$phpPropertyName = $property->getName();
144-
$value = $property->getValue($this);
145-
146-
$jsonKey = self::toSnakeCase($phpPropertyName);
147-
148-
$result[$jsonKey] = $this->convertValue($value);
149-
}
150-
151-
return $result;
152-
}
153-
154-
/**
155-
* @param mixed $value
156-
*
157-
* @return mixed
158-
* @throws ReflectionException
159-
*/
160-
private function convertValue(mixed $value): mixed
161-
{
162-
if ($value instanceof AbstractModel) {
163-
return $value->toArray();
164-
}
165-
166-
if (is_array($value)) {
167-
return array_map([$this, 'convertValue'], $value);
168-
}
169-
170-
if ($value instanceof BackedEnum) {
171-
return $value->value;
172-
}
173-
174-
return $value;
175-
}
176176
}

src/Models/AbstractPatchModel.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace BushlanovDev\MaxMessengerBot\Models;
6+
7+
/**
8+
* An abstract base for PATCH request models. It uses a variadic constructor
9+
* to capture named arguments, tracking which fields were explicitly set.
10+
*/
11+
abstract readonly class AbstractPatchModel extends AbstractModel
12+
{
13+
/**
14+
* @var array<int|string, mixed>
15+
*/
16+
protected array $patchData;
17+
18+
/**
19+
* Captures all passed named arguments into an associative array.
20+
*
21+
* @param mixed ...$params
22+
*/
23+
public function __construct(...$params)
24+
{
25+
$this->patchData = $params;
26+
}
27+
28+
/**
29+
* @return array<string, mixed>
30+
* @throws \ReflectionException
31+
*/
32+
final public function toArray(): array
33+
{
34+
$result = [];
35+
foreach ($this->patchData as $key => $value) {
36+
$jsonKey = $this->toSnakeCase((string)$key);
37+
$result[$jsonKey] = $this->convertValue($value);
38+
}
39+
40+
return $result;
41+
}
42+
}

src/Models/BotPatch.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace BushlanovDev\MaxMessengerBot\Models;
6+
7+
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
8+
9+
/**
10+
* Represents the data to patch for a bot. Instantiate with named arguments.
11+
*
12+
* Example: new BotPatch(name: 'New Bot Name', description: null);
13+
*
14+
* @property-read string|null $name
15+
* @property-read string|null $description
16+
* @property-read BotCommand[]|null $commands
17+
* @property-read PhotoAttachmentRequestPayload|null $photo
18+
*/
19+
final readonly class BotPatch extends AbstractPatchModel
20+
{
21+
}

0 commit comments

Comments
 (0)