mirror of
https://github.com/BushlanovDev/max-bot-api-client-php.git
synced 2026-08-19 19:32:54 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 46e7c2ef0a |
@@ -37,7 +37,7 @@
|
||||
- [x] `DELETE /chats/{chatId}` (`deleteChat`) — *Удаление чата.*
|
||||
- [x] `POST /chats/{chatId}/actions` (`sendAction`) — *Отправка действия в чат (например, "печатает...").*
|
||||
- [x] `GET /chats/{chatId}/pin` (`getPinnedMessage`) — *Получение закрепленного сообщения.*
|
||||
- [ ] `PUT /chats/{chatId}/pin` (`pinMessage`) — *Закрепление сообщения.*
|
||||
- [x] `PUT /chats/{chatId}/pin` (`pinMessage`) — *Закрепление сообщения.*
|
||||
- [x] `DELETE /chats/{chatId}/pin` (`unpinMessage`) — *Открепление сообщения.*
|
||||
- [x] `GET /chats/{chatId}/members/me` (`getMembership`) — *Получение информации о членстве бота в чате.*
|
||||
- [x] `DELETE /chats/{chatId}/members/me` (`leaveChat`) — *Выход бота из чата.*
|
||||
@@ -61,11 +61,11 @@
|
||||
|
||||
#### Messages
|
||||
|
||||
- [ ] `GET /messages` (`getMessages`) — *Получение списка сообщений из чата.*
|
||||
- [x] `GET /messages` (`getMessages`) — *Получение списка сообщений из чата.*
|
||||
- [x] `POST /messages` (`sendMessage`) — *Отправка сообщения.*
|
||||
- [ ] `PUT /messages` (`editMessage`) — *Редактирование сообщения.*
|
||||
- [ ] `DELETE /messages` (`deleteMessage`) — *Удаление сообщения.*
|
||||
- [ ] `GET /messages/{messageId}` (`getMessageById`) — *Получение сообщения по ID.*
|
||||
- [x] `DELETE /messages` (`deleteMessage`) — *Удаление сообщения.*
|
||||
- [x] `GET /messages/{messageId}` (`getMessageById`) — *Получение сообщения по ID.*
|
||||
- [ ] `GET /videos/{videoToken}` (`getVideoAttachmentDetails`) — *Получение детальной информации о видео.*
|
||||
- [ ] `POST /answers` (`answerOnCallback`) — *Ответ на нажатие callback-кнопки.*
|
||||
|
||||
|
||||
+112
-1
@@ -50,6 +50,7 @@ class Api
|
||||
private const string METHOD_POST = 'POST';
|
||||
private const string METHOD_DELETE = 'DELETE';
|
||||
// private const string METHOD_PATCH = 'PATCH';
|
||||
private const string METHOD_PUT = 'PUT';
|
||||
|
||||
private const string ACTION_ME = '/me';
|
||||
private const string ACTION_SUBSCRIPTIONS = '/subscriptions';
|
||||
@@ -653,7 +654,7 @@ class Api
|
||||
*
|
||||
* @param int $chatId Chat identifier to leave from.
|
||||
*
|
||||
* @return Result A simple success/fail result.
|
||||
* @return Result
|
||||
* @throws ClientApiException
|
||||
* @throws NetworkException
|
||||
* @throws ReflectionException
|
||||
@@ -668,4 +669,114 @@ class Api
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns messages in a chat. Messages are traversed in reverse chronological order.
|
||||
*
|
||||
* @param int $chatId Identifier of the chat to get messages from.
|
||||
* @param string[]|null $messageIds A comma-separated list of message IDs to retrieve.
|
||||
* @param int|null $from Start time (Unix timestamp in ms) for the requested messages.
|
||||
* @param int|null $to End time (Unix timestamp in ms) for the requested messages.
|
||||
* @param int|null $count Maximum amount of messages in the response (1-100, default 50).
|
||||
*
|
||||
* @return Message[]
|
||||
* @throws ClientApiException
|
||||
* @throws NetworkException
|
||||
* @throws ReflectionException
|
||||
* @throws SerializationException
|
||||
*/
|
||||
public function getMessages(
|
||||
int $chatId,
|
||||
?array $messageIds = null,
|
||||
?int $from = null,
|
||||
?int $to = null,
|
||||
?int $count = null,
|
||||
): array {
|
||||
$query = [
|
||||
'chat_id' => $chatId,
|
||||
'message_ids' => $messageIds !== null ? implode(',', $messageIds) : null,
|
||||
'from' => $from,
|
||||
'to' => $to,
|
||||
'count' => $count,
|
||||
];
|
||||
|
||||
$response = $this->client->request(
|
||||
self::METHOD_GET,
|
||||
self::ACTION_MESSAGES,
|
||||
array_filter($query, fn ($value) => $value !== null)
|
||||
);
|
||||
|
||||
return $this->modelFactory->createMessages($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a message in a dialog or in a chat if the bot has permission to delete messages.
|
||||
*
|
||||
* @param string $messageId Identifier of the message to be deleted.
|
||||
*
|
||||
* @return Result
|
||||
* @throws ClientApiException
|
||||
* @throws NetworkException
|
||||
* @throws ReflectionException
|
||||
* @throws SerializationException
|
||||
*/
|
||||
public function deleteMessage(string $messageId): Result
|
||||
{
|
||||
return $this->modelFactory->createResult(
|
||||
$this->client->request(
|
||||
self::METHOD_DELETE,
|
||||
self::ACTION_MESSAGES,
|
||||
['message_id' => $messageId],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single message by its identifier.
|
||||
*
|
||||
* @param string $messageId Message identifier (`mid`) to get.
|
||||
*
|
||||
* @return Message
|
||||
* @throws ClientApiException
|
||||
* @throws NetworkException
|
||||
* @throws ReflectionException
|
||||
* @throws SerializationException
|
||||
*/
|
||||
public function getMessageById(string $messageId): Message
|
||||
{
|
||||
return $this->modelFactory->createMessage(
|
||||
$this->client->request(
|
||||
self::METHOD_GET,
|
||||
self::ACTION_MESSAGES . '/' . $messageId,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pins a message in a chat or channel.
|
||||
*
|
||||
* @param int $chatId Chat identifier where the message should be pinned.
|
||||
* @param string $messageId Identifier of the message to pin.
|
||||
* @param bool $notify If true, participants will be notified with a system message.
|
||||
*
|
||||
* @return Result
|
||||
* @throws ClientApiException
|
||||
* @throws NetworkException
|
||||
* @throws ReflectionException
|
||||
* @throws SerializationException
|
||||
*/
|
||||
public function pinMessage(int $chatId, string $messageId, bool $notify = true): Result
|
||||
{
|
||||
return $this->modelFactory->createResult(
|
||||
$this->client->request(
|
||||
self::METHOD_PUT,
|
||||
sprintf(self::ACTION_CHATS_PIN, $chatId),
|
||||
[],
|
||||
[
|
||||
'message_id' => $messageId,
|
||||
'notify' => $notify,
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,20 @@ class ModelFactory
|
||||
return Message::fromArray($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* List of messages.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @return Message[]
|
||||
*/
|
||||
public function createMessages(array $data): array
|
||||
{
|
||||
return isset($data['messages']) && is_array($data['messages'])
|
||||
? array_map([$this, 'createMessage'], $data['messages'])
|
||||
: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint you should upload to your binaries.
|
||||
*
|
||||
|
||||
@@ -1500,4 +1500,183 @@ final class ApiTest extends TestCase
|
||||
|
||||
$this->assertSame($expectedResult, $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function getMessagesCallsClientWithAllParameters(): void
|
||||
{
|
||||
$chatId = 12345;
|
||||
$messageIds = ['mid.1', 'mid.2'];
|
||||
$from = 1678880000;
|
||||
$to = 1678886400;
|
||||
$count = 10;
|
||||
|
||||
$expectedQuery = [
|
||||
'chat_id' => $chatId,
|
||||
'message_ids' => 'mid.1,mid.2',
|
||||
'from' => $from,
|
||||
'to' => $to,
|
||||
'count' => $count,
|
||||
];
|
||||
|
||||
$messageData = [
|
||||
'timestamp' => 1,
|
||||
'body' => ['mid' => 'mid.1', 'seq' => 1],
|
||||
'recipient' => ['chat_type' => 'chat', 'chat_id' => $chatId],
|
||||
];
|
||||
$rawResponse = ['messages' => [$messageData]];
|
||||
$expectedMessages = [Message::fromArray($messageData)];
|
||||
|
||||
$this->clientMock->expects($this->once())
|
||||
->method('request')
|
||||
->with('GET', '/messages', $expectedQuery)
|
||||
->willReturn($rawResponse);
|
||||
|
||||
$this->modelFactoryMock->expects($this->once())
|
||||
->method('createMessages')
|
||||
->with($rawResponse)
|
||||
->willReturn($expectedMessages);
|
||||
|
||||
$result = $this->api->getMessages($chatId, $messageIds, $from, $to, $count);
|
||||
|
||||
$this->assertIsArray($result);
|
||||
$this->assertSame($expectedMessages, $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function getMessagesReturnsEmptyArrayForEmptyResponse(): void
|
||||
{
|
||||
$chatId = 54321;
|
||||
$rawResponse = ['messages' => []];
|
||||
|
||||
$this->clientMock->expects($this->once())
|
||||
->method('request')
|
||||
->with('GET', '/messages', ['chat_id' => $chatId])
|
||||
->willReturn($rawResponse);
|
||||
|
||||
$this->modelFactoryMock->expects($this->once())
|
||||
->method('createMessages')
|
||||
->with($rawResponse)
|
||||
->willReturn([]);
|
||||
|
||||
$result = $this->api->getMessages($chatId);
|
||||
|
||||
$this->assertIsArray($result);
|
||||
$this->assertEmpty($result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function deleteMessageCallsClientCorrectly(): void
|
||||
{
|
||||
$messageId = 'mid.12345.abcdef';
|
||||
$expectedQuery = ['message_id' => $messageId];
|
||||
$rawResponse = ['success' => true];
|
||||
$expectedResult = new Result(true, null);
|
||||
|
||||
$this->clientMock
|
||||
->expects($this->once())
|
||||
->method('request')
|
||||
->with(
|
||||
self::equalTo('DELETE'),
|
||||
self::equalTo('/messages'),
|
||||
self::equalTo($expectedQuery),
|
||||
)
|
||||
->willReturn($rawResponse);
|
||||
|
||||
$this->modelFactoryMock
|
||||
->expects($this->once())
|
||||
->method('createResult')
|
||||
->with($rawResponse)
|
||||
->willReturn($expectedResult);
|
||||
|
||||
$result = $this->api->deleteMessage($messageId);
|
||||
|
||||
$this->assertSame($expectedResult, $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function getMessageByIdCallsClientAndFactoryCorrectly(): void
|
||||
{
|
||||
$messageId = 'mid.abcdef.123456';
|
||||
$uri = sprintf('/messages/%s', $messageId);
|
||||
|
||||
$rawResponse = [
|
||||
'timestamp' => 1679000000,
|
||||
'body' => ['mid' => $messageId, 'seq' => 123, 'text' => 'This is a specific message.'],
|
||||
'recipient' => ['chat_type' => 'dialog', 'user_id' => 101],
|
||||
];
|
||||
$expectedMessage = Message::fromArray($rawResponse);
|
||||
|
||||
$this->clientMock
|
||||
->expects($this->once())
|
||||
->method('request')
|
||||
->with(self::equalTo('GET'), self::equalTo($uri))
|
||||
->willReturn($rawResponse);
|
||||
|
||||
$this->modelFactoryMock
|
||||
->expects($this->once())
|
||||
->method('createMessage')
|
||||
->with($rawResponse)
|
||||
->willReturn($expectedMessage);
|
||||
|
||||
$result = $this->api->getMessageById($messageId);
|
||||
|
||||
$this->assertSame($expectedMessage, $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function pinMessageCallsClientWithCorrectBody(): void
|
||||
{
|
||||
$chatId = 12345;
|
||||
$messageId = 'mid.to.pin';
|
||||
$notify = false;
|
||||
$uri = sprintf('/chats/%d/pin', $chatId);
|
||||
|
||||
$expectedBody = ['message_id' => $messageId, 'notify' => $notify];
|
||||
$rawResponse = ['success' => true];
|
||||
$expectedResult = new Result(true, null);
|
||||
|
||||
$this->clientMock
|
||||
->expects($this->once())
|
||||
->method('request')
|
||||
->with(
|
||||
self::equalTo('PUT'),
|
||||
self::equalTo($uri),
|
||||
self::equalTo([]),
|
||||
self::equalTo($expectedBody),
|
||||
)
|
||||
->willReturn($rawResponse);
|
||||
|
||||
$this->modelFactoryMock
|
||||
->expects($this->once())
|
||||
->method('createResult')
|
||||
->with($rawResponse)
|
||||
->willReturn($expectedResult);
|
||||
|
||||
$result = $this->api->pinMessage($chatId, $messageId, $notify);
|
||||
$this->assertSame($expectedResult, $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function pinMessageUsesDefaultNotificationValue(): void
|
||||
{
|
||||
$chatId = 54321;
|
||||
$messageId = 'mid.another.pin';
|
||||
$uri = sprintf('/chats/%d/pin', $chatId);
|
||||
|
||||
$expectedBody = ['message_id' => $messageId, 'notify' => true];
|
||||
$rawResponse = ['success' => true];
|
||||
$expectedResult = new Result(true, null);
|
||||
|
||||
$this->clientMock
|
||||
->expects($this->once())
|
||||
->method('request')
|
||||
->with('PUT', $uri, [], $expectedBody)
|
||||
->willReturn($rawResponse);
|
||||
|
||||
$this->modelFactoryMock
|
||||
->method('createResult')
|
||||
->willReturn($expectedResult);
|
||||
|
||||
$this->api->pinMessage($chatId, $messageId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,4 +386,37 @@ final class ModelFactoryTest extends TestCase
|
||||
$this->assertSame(ChatAdminPermission::Write, $chatMember->permissions[1]);
|
||||
$this->assertEquals($rawData, $chatMember->toArray());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function createMessagesReturnsArrayOfMessageObjects(): void
|
||||
{
|
||||
$data = [
|
||||
'messages' => [
|
||||
[
|
||||
'timestamp' => 1,
|
||||
'body' => ['mid' => 'mid.1', 'seq' => 1],
|
||||
'recipient' => ['chat_type' => 'chat', 'chat_id' => 123],
|
||||
],
|
||||
[
|
||||
'timestamp' => 2,
|
||||
'body' => ['mid' => 'mid.2', 'seq' => 2],
|
||||
'recipient' => ['chat_type' => 'chat', 'chat_id' => 123],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$messages = $this->factory->createMessages($data);
|
||||
|
||||
$this->assertIsArray($messages);
|
||||
$this->assertCount(2, $messages);
|
||||
$this->assertInstanceOf(Message::class, $messages[0]);
|
||||
$this->assertSame('mid.1', $messages[0]->body->mid);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function createMessagesHandlesEmptyOrMissingKey(): void
|
||||
{
|
||||
$this->assertEmpty($this->factory->createMessages(['messages' => []]));
|
||||
$this->assertEmpty($this->factory->createMessages([]));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user