f试ssefahah可能卡卡卡马卡卡计算机视觉事实上事实上飒飒飒gj◐◐◐◐hfkttkgdgkmcuocucocucoc顶顶顶顶顶顶顶顶顶顶顶顶uco朵朵可可放2巍峨2555555666369🌹 �����ѩ�����һ����dddf2qevf2fv69666 ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!telegram-bot-sdk/src/TelegramClient.php000064400000010027152665541660014124 0ustar00httpClientHandler = $httpClientHandler ?? new GuzzleHttpClient; $this->baseBotUrl = $baseBotUrl ?? self::BASE_BOT_URL; } public function getHttpClientHandler(): HttpClientInterface { return $this->httpClientHandler ?? new GuzzleHttpClient; } public function setHttpClientHandler(HttpClientInterface $httpClientHandler): self { $this->httpClientHandler = $httpClientHandler; return $this; } public function sendRequest(TelegramRequest $request): TelegramResponse { [$url, $method, $headers, $isAsyncRequest] = $this->prepareRequest($request); $options = $this->getOptions($request, $method); $rawResponse = $this->httpClientHandler ->setTimeOut($request->getTimeOut()) ->setConnectTimeOut($request->getConnectTimeOut()) ->send($url, $method, $headers, $options, $isAsyncRequest); $response = $this->getResponse($request, $rawResponse); if ($response->isError()) { throw $response->getThrownException(); } return $response; } /** * Get File URL. */ public function getFileUrl(string $path, TelegramRequest $request): string { $baseFileUrl = str_replace('/bot', '', $this->baseBotUrl); return str_replace( ['{BASE_BOT_URL}', '{TOKEN}', '{FILE_PATH}'], [$baseFileUrl, $request->getAccessToken(), $path], $this->fileUrl ); } /** * Download file from Telegram server for given file path. * * @param string $filePath File path on Telegram server. * @param string $filename Download path to save file. * * @throws TelegramSDKException */ public function download(string $filePath, string $filename, TelegramRequest $request): string { $fileDir = dirname($filename); // Ensure dir is created. if (! @mkdir($fileDir, 0755, true) && ! is_dir($fileDir)) { throw TelegramSDKException::fileDownloadFailed('Directory '.$fileDir.' can\'t be created'); } $response = $this->httpClientHandler ->setTimeOut($request->getTimeOut()) ->setConnectTimeOut($request->getConnectTimeOut()) ->send( $url = $this->getFileUrl($filePath, $request), $request->getMethod(), $request->getHeaders(), ['sink' => $filename], $request->isAsyncRequest() ); if ($response->getStatusCode() !== 200) { throw TelegramSDKException::fileDownloadFailed($response->getReasonPhrase(), $url); } return $filename; } public function prepareRequest(TelegramRequest $request): array { $url = $this->baseBotUrl.$request->getAccessToken().'/'.$request->getEndpoint(); return [$url, $request->getMethod(), $request->getHeaders(), $request->isAsyncRequest()]; } public function getBaseBotUrl(): string { return $this->baseBotUrl; } private function getResponse(TelegramRequest $request, ResponseInterface|PromiseInterface|null $response): TelegramResponse { return new TelegramResponse($request, $response); } private function getOptions(TelegramRequest $request, string $method): array { return $method === 'POST' ? $request->getPostParams() : ['query' => $request->getParams()]; } } telegram-bot-sdk/src/Objects/UserProfilePhotos.php000064400000001122152665541660016246 0ustar00 [PhotoSize::class], ]; } } telegram-bot-sdk/src/Objects/VideoNote.php000064400000001527152665541660014517 0ustar00 PhotoSize::class, ]; } } telegram-bot-sdk/src/Objects/EditedMessage.php000064400000000150152665541660015315 0ustar00, entities: string[], caption_entities: string[], audio: string, dice: string, animation: string, document: string, game: string, photo: string[], sticker: string, video: string, voice: string, video_note: string, contact: string, location: string, venue: string, poll: string, new_chat_member: string, new_chat_members: string[], left_chat_member: string, new_chat_photo: string[], delete_chat_photo: string, pinned_message: class-string, invoice: string, successful_payment: string, passport_data: string, sender_chat: string, proximity_alert_triggered: string, voice_chat_started: string, voice_chat_ended: string, voice_chat_participants_invited: string, web_app_data: string} */ public function relations(): array { return [ 'from' => User::class, 'chat' => Chat::class, 'forward_from' => User::class, 'forward_from_chat' => Chat::class, 'reply_to_message' => self::class, 'entities' => [MessageEntity::class], 'caption_entities' => [MessageEntity::class], 'audio' => Audio::class, 'dice' => Dice::class, 'animation' => Animation::class, 'document' => Document::class, 'game' => Game::class, 'photo' => [PhotoSize::class], 'sticker' => Sticker::class, 'video' => Video::class, 'voice' => Voice::class, 'video_note' => VideoNote::class, 'contact' => Contact::class, 'location' => Location::class, 'venue' => Venue::class, 'poll' => Poll::class, 'new_chat_member' => ChatMember::class, 'new_chat_members' => [User::class], 'left_chat_member' => User::class, 'new_chat_photo' => [PhotoSize::class], 'delete_chat_photo' => ChatPhoto::class, 'pinned_message' => self::class, 'invoice' => Invoice::class, 'successful_payment' => SuccessfulPayment::class, 'passport_data' => PassportData::class, 'sender_chat' => Chat::class, 'proximity_alert_triggered' => ProximityAlertTriggered::class, 'voice_chat_started' => VoiceChatStarted::class, 'voice_chat_ended' => VoiceChatEnded::class, 'voice_chat_participants_invited' => VoiceChatParticipantsInvited::class, 'web_app_data' => WebAppData::class, ]; } /** * Determine if the message is of given type. */ public function isType(string $type): bool { if ($this->has(strtolower($type))) { return true; } return $this->detectType() === $type; } /** * Detect type based on properties. */ public function objectType(): ?string { return $this->detectType(); } /** * Detect type based on properties. * * @deprecated Will be removed in v4.0, please use {@see Message::objectType} instead. */ public function detectType(): ?string { return $this->findType(static::TYPES); } /** * Does this message contain a command entity. */ public function hasCommand(): bool { return $this->get('entities', collect())->contains('type', 'bot_command'); } } telegram-bot-sdk/src/Objects/User.php000064400000002023152665541660013531 0ustar00 Location::class, ]; } } telegram-bot-sdk/src/Objects/PollAnswer.php000064400000001177152665541660014712 0ustar00 User::class, ]; } } telegram-bot-sdk/src/Objects/Game.php000064400000002351152665541660013470 0ustar00 [PhotoSize::class], 'text_entities' => [MessageEntity::class], 'animation' => Animation::class, ]; } } telegram-bot-sdk/src/Objects/ChatInviteLink.php000064400000002457152665541660015502 0ustar00 User::class, ]; } } telegram-bot-sdk/src/Objects/BaseObject.php000064400000011343152665541660014621 0ustar00getRawResult($data)); } /** * Returns raw result. */ public function getRawResult($data): mixed { return data_get($data, 'result', $data); } /** * Magically access collection data. * * @return mixed */ public function __get($key) { return $this->getPropertyValue($key); } public function __set(string $name, mixed $value): void { throw new InvalidArgumentException(sprintf('Cannot set property “%s” on “%s” immutable object.', $name, static::class)); } /** * Magically map to an object class (if exists) and return data. * * @param string $property Name of the property or relation. * @param mixed $default Default value or \Closure that returns default value. */ protected function getPropertyValue(string $property, mixed $default = null): mixed { $property = Str::snake($property); if (! $this->offsetExists($property)) { return value($default); } $value = $this->items[$property]; $relations = $this->relations(); if (isset($relations[$property])) { return $this->getRelationValue($property, $value); } /** @var BaseObject $class */ $class = 'Telegram\Bot\Objects\\'.Str::studly($property); if (class_exists($class)) { return $class::make($value); } if (is_array($value)) { return TelegramObject::make($value); } return $value; } /** * Property relations. */ abstract public function relations(): array; /** * @return array|Enumerable|EnumeratesValues|BaseObject */ protected function getRelationValue(string $relativeName, iterable $relativeData): mixed { /** @var class-string|list> $relative */ $relative = $this->relations()[$relativeName]; if (is_string($relative)) { if (! class_exists($relative)) { throw new InvalidArgumentException(sprintf('Could not load “%s” relative: class “%s” not found.', $relativeName, $relative)); } return $relative::make($relativeData); } /** @var class-string $relativeClass */ $relativeClass = $relative[0]; $relatedObjects = Collection::make(); // @todo array type can be used in v4 foreach ($relativeData as $data) { $relatedObjects->add($relativeClass::make($data)); } return $relatedObjects; } public function __isset(string $name): bool { return $this->getPropertyValue($name) !== null; } /** * Get an item from the collection by key. * * @param mixed $key * @param mixed $default */ public function get($key, $default = null): mixed { $value = parent::get($key, $default); if (is_array($value)) { return $this->getPropertyValue($key, $default); } return $value; } /** * Returns raw response. * * @return array|mixed */ public function getRawResponse(): mixed { return $this->items; } /** * Get Status of request. */ public function getStatus(): mixed { return data_get($this->items, 'ok', false); } /** * Determine if the object is of given type. */ public function isType(string $type): bool { if ($this->offsetExists($type)) { return true; } return $this->objectType() === $type; } /** * Detect type based on fields. */ public function objectType(): ?string { return null; } /** * Magic method to get properties dynamically. * * @return mixed */ public function __call($method, $parameters) { if (! Str::startsWith($method, 'get')) { return false; } $property = substr($method, 3); return $this->getPropertyValue($property); } /** * Determine the type by given types. */ protected function findType(array $types): ?string { return $this->keys() ->intersect($types) ->pop(); } } telegram-bot-sdk/src/Objects/ChatMember.php000064400000007013152665541660014626 0ustar00 User::class, ]; } } telegram-bot-sdk/src/Objects/Chat.php000064400000006610152665541660013500 0ustar00 links only in chats with the user. Returned only in getChat. * @property string|null $description (Optional). Description, for groups, supergroups and channel chats. Returned only in getChat. * @property string|null $inviteLink (Optional). Chat invite link, for groups, supergroups and channel chats. Each administrator in a chat generates their own invite links, so the bot must first generate the link using exportChatInviteLink. Returned only in getChat. * @property Message|null $pinnedMessage (Optional). Pinned message, for groups, supergroups and channels. Returned only in getChat. * @property ChatPermissions|null $permissions (Optional). Pinned message, for groups, supergroups and channels. Returned only in getChat. * @property int|null $slowModeDelay (Optional). For supergroups, the minimum allowed delay between consecutive messages sent by each unpriviledged user. Returned only in getChat. * @property bool|null $hasProtectedContent (Optional). True, if messages from the chat can't be forwarded to other chats. Returned only in getChat. * @property string|null $stickerSetName (Optional). For supergroups, name of group sticker set. Returned only in getChat. * @property bool|null $canSetStickerSet (Optional). True, if the bot can change the group sticker set. Returned only in getChat. * @property int|null $linkedChatId (Optional). Unique identifier for the linked chat, i.e. the discussion group identifier for a channel and vice versa; for supergroups and channel chats. This identifier may be greater than 32 bits and some programming languages may have difficulty/silent defects in interpreting it. But it is smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier. Returned only in getChat. * @property ChatLocation|null $location (Optional). For supergroups, the location to which the supergroup is connected. Returned only in getChat. */ class Chat extends BaseObject { /** * {@inheritdoc} * * @return array{photo: string, pinned_message: string, permissions: string, location: string} */ public function relations(): array { return [ 'photo' => InputMedia::class, 'pinned_message' => Message::class, 'permissions' => ChatPermissions::class, 'location' => ChatLocation::class, ]; } } telegram-bot-sdk/src/Objects/Sticker.php000064400000002357152665541660014231 0ustar00 PhotoSize::class, 'mask_position' => MaskPosition::class, ]; } } telegram-bot-sdk/src/Objects/Passport/PassportScopeElementOne.php000064400000002602152665541660021212 0ustar00 SecureData::class, ]; } } telegram-bot-sdk/src/Objects/Passport/EncryptedCredentials.php000064400000001315152665541660020544 0ustar00 SecureValue::class, 'passport' => SecureValue::class, 'internal_passport' => SecureValue::class, 'driver_license' => SecureValue::class, 'identity_card' => SecureValue::class, 'address' => SecureValue::class, 'utility_bill' => SecureValue::class, 'bank_statement' => SecureValue::class, 'rental_agreement' => SecureValue::class, 'passport_registration' => SecureValue::class, 'temporary_registration' => SecureValue::class, ]; } } telegram-bot-sdk/src/Objects/Passport/PassportElementError.php000064400000000633152665541660020572 0ustar00 DataCredentials::class, 'front_side' => FileCredentials::class, 'reverse_side' => FileCredentials::class, 'selfie' => FileCredentials::class, 'translation' => [FileCredentials::class], 'files' => [FileCredentials::class], ]; } } telegram-bot-sdk/src/Objects/Passport/PassportElementErrorFrontSide.php000064400000001300152665541660022400 0ustar00 [PassportFile::class], 'front_side' => PassportFile::class, 'reverse_side' => PassportFile::class, 'selfie' => PassportFile::class, 'translation' => [PassportFile::class], ]; } } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultCachedVideo.php000064400000005005152665541660022604 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'video_file_id => '', // string - Required. A valid file identifier for the video file * 'title' => '', // string - Required. Title for the result * 'description' => '', // string - (Optional). Short description of the result * 'caption' => '', // string - (Optional). Caption of the video to be sent, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultcachedvideo * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setVideoFileId(string) A valid file identifier for the video file * @method $this setTitle(string) Title for the result * @method $this setDescription(string) (Optional). Short description of the result * @method $this setCaption(string) (Optional). Caption of the video to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultCachedVideo extends InlineBaseObject { protected $type = 'video'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultCachedSticker.php000064400000002576152665541660023154 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 Bytes * 'sticker_file_id' => '', // string - Required. A valid file identifier of the sticker * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultcachedsticker * * @method $this setId(string) Unique identifier for this result, 1-64 Bytes * @method $this setStickerFileId(string) A valid file identifier of the sticker * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultCachedSticker extends InlineBaseObject { protected $type = 'sticker'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultGif.php000064400000006042152665541660021155 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'gif_url' => '', // string - Required. A valid URL for the GIF file. File size must not exceed 1MB * 'gif_width' => '', // int - (Optional). Width of the GIF * 'gif_height' => '', // int - (Optional). Height of the GIF * 'gif_duration' => '', // int - (Optional). Duration of the GIF * 'thumb_url' => '', // string - Required. URL of the static thumbnail for the result (jpeg or gif) * 'title' => '', // string - (Optional). Title for the result * 'caption' => '', // string - (Optional). Caption of the GIF file to be sent, 0-200 characters * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultgif * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setGifUrl(string) A valid URL for the GIF file. File size must not exceed 1MB * @method $this setGifWidth(int) (Optional). Width of the GIF * @method $this setGifHeight(int) (Optional). Height of the GIF * @method $this setGifDuration(int) (Optional). Duration of the GIF * @method $this setThumbUrl(string) URL of the static thumbnail for the result (jpeg or gif) * @method $this setTitle(string) (Optional). Title for the result * @method $this setCaption(string) (Optional). Caption of the GIF file to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultGif extends InlineBaseObject { protected $type = 'gif'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultCachedVoice.php000064400000004414152665541660022606 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'voice_file_id' => '', // string - Required. A valid file identifier for the voice message * 'title' => '', // string - Required. Voice message title * 'caption' => '', // string - (Optional). Caption, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultcachedvoice * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setVoiceFileId(string) A valid file identifier for the voice message * @method $this setTitle(string) Voice message title * @method $this setCaption(string) (Optional). Caption, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultCachedVoice extends InlineBaseObject { protected $type = 'voice'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultDocument.php000064400000006507152665541660022234 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'title' => '', // string - Required. Title for the result * 'caption' => '', // string - (Optional). Caption of the document to be sent, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'document_url' => '', // string - Required. A valid URL for the file * 'mime_type' => '', // string - Required. Mime type of the content of the file, either “application/pdf” or “application/zip” * 'description' => '', // string - (Optional). Short description of the result * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the file * 'thumb_url' => '', // string - (Optional). URL of the thumbnail (jpeg only) for the file * 'thumb_width' => '', // int - (Optional). Thumbnail width * 'thumb_height' => '', // int - (Optional). Thumbnail height * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultdocument * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setTitle(string) Title for the result * @method $this setCaption(string) (Optional). Caption of the document to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setDocumentUrl(string) A valid URL for the file * @method $this setMimeType(string) Mime type of the content of the file, either “application/pdf” or “application/zip” * @method $this setDescription(string) (Optional). Short description of the result * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the file * @method $this setThumbUrl(string) (Optional). URL of the thumbnail (jpeg only) for the file * @method $this setThumbWidth(int) (Optional). Thumbnail width * @method $this setThumbHeight(int) (Optional). Thumbnail height */ class InlineQueryResultDocument extends InlineBaseObject { protected $type = 'document'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultArticle.php000064400000004245152665541660022036 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 Bytes * 'title' => '', // string - Required. Title of the result * 'input_message_content' => '', // InputMessageContent - Required. Content of the message to be sent. * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'url' => '', // string - (Optional). URL of the result * 'hide_url' => '', // bool - (Optional). Pass True, if you don't want the URL to be shown in the message * 'description' => '', // string - (Optional). Short description of the result * 'thumb_url' => '', // string - (Optional). Url of the thumbnail for the result * 'thumb_width' => '', // int - (Optional). Thumbnail width * 'thumb_height' => '', // int - (Optional). Thumbnail height * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultarticle * * @method $this setId(string) Unique identifier for this result, 1-64 Bytes * @method $this setTitle(string) Title of the result * @method $this setInputMessageContent(object) Content of the message to be sent. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setUrl(string) (Optional). URL of the result * @method $this setHideUrl(bool) (Optional). Pass True, if you don't want the URL to be shown in the message * @method $this setDescription(string) (Optional). Short description of the result * @method $this setThumbUrl(string) (Optional). Url of the thumbnail for the result * @method $this setThumbWidth(int) (Optional). Thumbnail width * @method $this setThumbHeight(int) (Optional). Thumbnail height */ class InlineQueryResultArticle extends InlineBaseObject { protected $type = 'article'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultMpeg4Gif.php000064400000006113152665541660022051 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'mpeg4_url' => '', // string - Required. A valid URL for the MP4 file. File size must not exceed 1MB * 'mpeg4_width' => '', // int - (Optional). Video width * 'mpeg4_height' => '', // int - (Optional). Video height * 'mpeg4_duration' => '', // int - (Optional). Video duration * 'thumb_url' => '', // string - Required. URL of the static thumbnail (jpeg or gif) for the result * 'title' => '', // string - (Optional). Title for the result * 'caption' => '', // string - (Optional). Caption of the MPEG-4 file to be sent, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultmpeg4gif * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setMpeg4Url(string) A valid URL for the MP4 file. File size must not exceed 1MB * @method $this setMpeg4Width(int) (Optional). Video width * @method $this setMpeg4Height(int) (Optional). Video height * @method $this setMpeg4Duration(int) (Optional). Video duration * @method $this setThumbUrl(string) URL of the static thumbnail (jpeg or gif) for the result * @method $this setTitle(string) (Optional). Title for the result * @method $this setCaption(string) (Optional). Caption of the MPEG-4 file to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultMpeg4Gif extends InlineBaseObject { protected $type = 'mpeg4_gif'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultCachedMpeg4Gif.php000064400000004640152665541660023144 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'mpeg4_file_id' => '', // string - Required. A valid file identifier for the MP4 file * 'title' => '', // string - (Optional). Title for the result * 'caption' => '', // string - (Optional). Caption of the MPEG-4 file to be sent, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultcachedmpeg4gif * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setMpeg4FileId(string) A valid file identifier for the MP4 file * @method $this setTitle(string) (Optional). Title for the result * @method $this setCaption(string) (Optional). Caption of the MPEG-4 file to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultCachedMpeg4Gif extends InlineBaseObject { protected $type = 'mpeg4_gif'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultPhoto.php000064400000006051152665541660021541 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 Bytes * 'photo_url' => '', // string - Required. A valid URL of the photo. Photo must be in jpeg format. Photo size must not exceed 5MB * 'thumb_url' => '', // string - Required. URL of the thumbnail for the photo * 'photo_width' => '', // int - (Optional). Width of the photo * 'photo_height' => '', // int - (Optional). Height of the photo * 'title' => '', // string - (Optional). Title for the result * 'description' => '', // string - (Optional). Short description of the result * 'caption' => '', // string - (Optional). Caption of the photo to be sent, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultphoto * * @method $this setId(string) Unique identifier for this result, 1-64 Bytes * @method $this setPhotoUrl(string) A valid URL of the photo. Photo must be in jpeg format. Photo size must not exceed 5MB * @method $this setThumbUrl(string) URL of the thumbnail for the photo * @method $this setPhotoWidth(int) (Optional). Width of the photo * @method $this setPhotoHeight(int) (Optional). Height of the photo * @method $this setTitle(string) (Optional). Title for the result * @method $this setDescription(string) (Optional). Short description of the result * @method $this setCaption(string) (Optional). Caption of the photo to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultPhoto extends InlineBaseObject { protected $type = 'photo'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultLocation.php000064400000005557152665541660022232 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 Bytes * 'latitude' => '', // float - Required. Location latitude in degrees * 'longitude' => '', // float - Required. Location longitude in degrees * 'title' => '', // string - Required. Location title * 'horizontal_accuracy' => '', // float - (Optional). The radius of uncertainty for the location, measured in meters; 0-1500 * 'live_period' => '', // int - (Optional). Period in seconds for which the location can be updated, should be between 60 and 86400. * 'heading' => '', // int - (Optional). For live locations, a direction in which the user is moving, in degrees. Must be between 1 and 360 if specified. * 'proximity_alert_radius' => '', // int - (Optional). For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified. * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the location * 'thumb_url' => '', // string - (Optional). Url of the thumbnail for the result * 'thumb_width' => '', // int - (Optional). Thumbnail width * 'thumb_height' => '', // int - (Optional). Thumbnail height * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultlocation * * @method $this setId(string) Unique identifier for this result, 1-64 Bytes * @method $this setLatitude(float) Location latitude in degrees * @method $this setLongitude(float) Location longitude in degrees * @method $this setTitle(string) Location title * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the location * @method $this setThumbUrl(string) (Optional). Url of the thumbnail for the result * @method $this setThumbWidth(int) (Optional). Thumbnail width * @method $this setThumbHeight(int) (Optional). Thumbnail height */ class InlineQueryResultLocation extends InlineBaseObject { protected $type = 'location'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultAudio.php000064400000004750152665541660021515 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'audio_url' => '', // string - Required. A valid URL for the audio file * 'title' => '', // string - Required. Title * 'caption' => '', // string - (Optional). Caption, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'performer' => '', // string - (Optional). Performer * 'audio_duration' => '', // int - (Optional). Audio duration in seconds * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultaudio * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setAudioUrl(string) A valid URL for the audio file * @method $this setTitle(string) Title * @method $this setCaption(string) (Optional). Caption, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setPerformer(string) (Optional). Performer * @method $this setAudioDuration(int) (Optional). Audio duration in seconds * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultAudio extends InlineBaseObject { protected $type = 'audio'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultCachedPhoto.php000064400000004775152665541660022644 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 Bytes * 'photo_file_id' => '', // string - Required. A valid file identifier of the photo * 'title' => '', // string - (Optional). Title for the result * 'description' => '', // string - (Optional). Short description of the result * 'caption' => '', // string - (Optional). Caption of the photo to be sent, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultcachedphoto * * @method $this setId(string) Unique identifier for this result, 1-64 Bytes * @method $this setPhotoFileId(string) A valid file identifier of the photo * @method $this setTitle(string) (Optional). Title for the result * @method $this setDescription(string) (Optional). Short description of the result * @method $this setCaption(string) (Optional). Caption of the photo to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultCachedPhoto extends InlineBaseObject { protected $type = 'photo'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineBaseObject.php000064400000001653152665541660020227 0ustar00put('type', $this->type); } /** * Magic method to set properties dynamically. * * @return $this|mixed */ public function __call($name, $arguments) { if (! Str::startsWith($name, 'set')) { throw new BadMethodCallException(sprintf('Method %s does not exist.', $name)); } $property = Str::snake(substr($name, 3)); $this->put($property, $arguments[0]); return $this; } } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultContact.php000064400000004617152665541660022051 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 Bytes * 'phone_number' => '', // string - Required. Contact's phone number * 'first_name' => '', // string - Required. Contact's first name * 'last_name' => '', // string - (Optional). Contact's last name * 'vcard' => '', // string - (Optional). Additional data about the contact in the form of a vCard, 0-2048 bytes * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the contact * 'thumb_url' => '', // string - (Optional). Url of the thumbnail for the result * 'thumb_width' => '', // int - (Optional). Thumbnail width * 'thumb_height' => '', // int - (Optional). Thumbnail height * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultcontact * * @method $this setId(string) Unique identifier for this result, 1-64 Bytes * @method $this setPhoneNumber(string) Contact's phone number * @method $this setFirstName(string) Contact's first name * @method $this setLastName(string) (Optional). Contact's last name * @method $this setVcard(string) (Optional). Additional data about the contact in the form of a vCard, 0-2048 bytes * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the contact * @method $this setThumbUrl(string) (Optional). Url of the thumbnail for the result * @method $this setThumbWidth(int) (Optional). Thumbnail width * @method $this setThumbHeight(int) (Optional). Thumbnail height */ class InlineQueryResultContact extends InlineBaseObject { protected $type = 'contact'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultCachedAudio.php000064400000004147152665541660022605 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'audio_file_id' => '', // string - Required. A valid file identifier for the audio file * 'caption' => '', // string - (Optional). Caption, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultcachedaudio * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setAudioFileId(string) A valid file identifier for the audio file * @method $this setCaption(string) (Optional). Caption, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultCachedAudio extends InlineBaseObject { protected $type = 'audio'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultVenue.php000064400000006243152665541660021535 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 Bytes * 'latitude' => '', // float - Required. Latitude of the venue location in degrees * 'longitude' => '', // float - Required. Longitude of the venue location in degrees * 'title' => '', // string - Required. Title of the venue * 'address' => '', // string - Required. Address of the venue * 'foursquare_id' => '', // string - (Optional). Foursquare identifier of the venue if known * 'foursquare_type' => '', // string - (Optional). Foursquare type of the venue, if known. (For example, “arts_entertainment/default”, “arts_entertainment/aquarium” or “food/icecream”.) * 'google_place_id' => '', // string - (Optional). Google Places identifier of the venue * 'google_place_type' => '', // string - (Optional). Google Places type of the venue. * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the venue * 'thumb_url' => '', // string - (Optional). Url of the thumbnail for the result * 'thumb_width' => '', // int - (Optional). Thumbnail width * 'thumb_height' => '', // int - (Optional). Thumbnail height * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultvenue * * @method $this setId(string) Unique identifier for this result, 1-64 Bytes * @method $this setLatitude(float) Latitude of the venue location in degrees * @method $this setLongitude(float) Longitude of the venue location in degrees * @method $this setTitle(string) Title of the venue * @method $this setAddress(string) Address of the venue * @method $this setFoursquareId(string) (Optional). Foursquare identifier of the venue if known * @method $this setFoursquareType(string) (Optional). Foursquare type of the venue, if known. (For example, “arts_entertainment/default”, “arts_entertainment/aquarium” or “food/icecream”.) * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the venue * @method $this setThumbUrl(string) (Optional). Url of the thumbnail for the result * @method $this setThumbWidth(int) (Optional). Thumbnail width * @method $this setThumbHeight(int) (Optional). Thumbnail height */ class InlineQueryResultVenue extends InlineBaseObject { protected $type = 'venue'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultCachedGif.php000064400000004530152665541660022245 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'gif_file_id' => '', // string - Required. A valid file identifier for the GIF file * 'title' => '', // string - (Optional). Title for the result * 'caption' => '', // string - (Optional). Caption of the GIF file to be sent, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultcachedgif * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setGifFileId(string) A valid file identifier for the GIF file * @method $this setTitle(string) (Optional). Title for the result * @method $this setCaption(string) (Optional). Caption of the GIF file to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultCachedGif extends InlineBaseObject { protected $type = 'gif'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultCachedDocument.php000064400000004777152665541660023333 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'title' => '', // string - Required. Title for the result * 'document_file_id' => '', // string - Required. A valid file identifier for the file * 'description' => '', // string - (Optional). Short description of the result * 'caption' => '', // string - (Optional). Caption of the document to be sent, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the file * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultcacheddocument * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setTitle(string) Title for the result * @method $this setDocumentFileId(string) A valid file identifier for the file * @method $this setDescription(string) (Optional). Short description of the result * @method $this setCaption(string) (Optional). Caption of the document to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the file */ class InlineQueryResultCachedDocument extends InlineBaseObject { protected $type = 'document'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultVideo.php000064400000007163152665541660021523 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'video_url' => '', // string - Required. A valid URL for the embedded video player or video file * 'mime_type' => '', // string - Required. Mime type of the content of video url, “text/html” or “video/mp4” * 'thumb_url' => '', // string - Required. URL of the thumbnail (jpeg only) for the video * 'title' => '', // string - Required. Title for the result * 'caption' => '', // string - (Optional). Caption of the video to be sent, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'video_width' => '', // int - (Optional). Video width * 'video_height' => '', // int - (Optional). Video height * 'video_duration' => '', // int - (Optional). Video duration in seconds * 'description' => '', // string - (Optional). Short description of the result * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultvideo * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setVideoUrl(string) A valid URL for the embedded video player or video file * @method $this setMimeType(string) Mime type of the content of video url, “text/html” or “video/mp4” * @method $this setThumbUrl(string) URL of the thumbnail (jpeg only) for the video * @method $this setTitle(string) Title for the result * @method $this setCaption(string) (Optional). Caption of the video to be sent, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setVideoWidth(int) (Optional). Video width * @method $this setVideoHeight(int) (Optional). Video height * @method $this setVideoDuration(int) (Optional). Video duration in seconds * @method $this setDescription(string) (Optional). Short description of the result * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultVideo extends InlineBaseObject { protected $type = 'video'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultGame.php000064400000001545152665541660021324 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 Bytes. * 'game_short_name' => '', // string - Required. Short name of the game. * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultgame * * @method $this setId(string) Unique identifier for this result, 1-64 Bytes. * @method $this setGameShortName(string) Short name of the game. * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message */ class InlineQueryResultGame extends InlineBaseObject { protected $type = 'game'; } telegram-bot-sdk/src/Objects/InlineQuery/InlineQueryResultVoice.php000064400000004660152665541660021521 0ustar00 * [ * 'id' => '', // string - Required. Unique identifier for this result, 1-64 bytes * 'voice_url' => '', // string - Required. A valid URL for the voice recording * 'title' => '', // string - Required. Recording title * 'caption' => '', // string - (Optional). Caption, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'voice_duration' => '', // int - (Optional). Recording duration in seconds * 'reply_markup' => '', // InlineKeyboardMarkup - (Optional). Inline keyboard attached to the message * 'input_message_content' => '', // InputMessageContent - (Optional). Content of the message to be sent instead of the photo * ] * * * @link https://core.telegram.org/bots/api#inlinequeryresultvoice * * @method $this setId(string) Unique identifier for this result, 1-64 bytes * @method $this setVoiceUrl(string) A valid URL for the voice recording * @method $this setTitle(string) Recording title * @method $this setCaption(string) (Optional). Caption, 0-200 characters * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @method $this setVoiceDuration(int) (Optional). Recording duration in seconds * @method $this setReplyMarkup(object) (Optional). Inline keyboard attached to the message * @method $this setInputMessageContent(object) (Optional). Content of the message to be sent instead of the photo */ class InlineQueryResultVoice extends InlineBaseObject { protected $type = 'voice'; } telegram-bot-sdk/src/Objects/Payments/ShippingQuery.php000064400000001406152665541660017226 0ustar00 User::class, 'shipping_address' => ShippingAddress::class, ]; } } telegram-bot-sdk/src/Objects/Payments/ShippingAddress.php000064400000001172152665541660017506 0ustar00 [LabeledPrice::class], ]; } } telegram-bot-sdk/src/Objects/Payments/Invoice.php000064400000001252152665541660016012 0ustar00 ShippingAddress::class, ]; } } telegram-bot-sdk/src/Objects/Payments/SuccessfulPayment.php000064400000001745152665541660020102 0ustar00 OrderInfo::class, ]; } } telegram-bot-sdk/src/Objects/Payments/LabeledPrice.php000064400000000723152665541660016733 0ustar00 User::class, 'order_info' => OrderInfo::class, ]; } public function objectType(): ?string { return $this->findType(['shipping_option_id', 'order_info']); } } telegram-bot-sdk/src/Objects/ForumTopic.php000064400000001073152665541660014706 0ustar00 PhotoSize::class, ]; } } telegram-bot-sdk/src/Objects/StickerSet.php000064400000001524152665541660014700 0ustar00>, thumb: string} */ public function relations(): array { return [ 'stickers' => [Sticker::class], 'thumb' => PhotoSize::class, ]; } } telegram-bot-sdk/src/Objects/CallbackQuery.php000064400000002741152665541660015344 0ustar00 User::class, 'message' => Message::class, ]; } public function objectType(): ?string { // TODO - Check if message and inline_message_id are exclusive to each other return $this->findType(['data', 'game_short_name']); } } telegram-bot-sdk/src/Objects/WebApp/WebAppData.php000064400000001113152665541660015740 0ustar00 User::class, ]; } } telegram-bot-sdk/src/Objects/ReactionType.php000064400000002033152665541660015222 0ustar00 PhotoSize::class, ]; } } telegram-bot-sdk/src/Objects/WebhookInfo.php000064400000002264152665541660015034 0ustar00 PhotoSize::class, ]; } } telegram-bot-sdk/src/Objects/ChosenInlineResult.php000064400000002260152665541660016373 0ustar00 User::class, 'location' => Location::class, ]; } public function objectType(): ?string { return $this->findType(['location', 'inline_message_id']); } } telegram-bot-sdk/src/Objects/ResponseParameters.php000064400000001535152665541660016444 0ustar00 [PollOption::class], ]; } } telegram-bot-sdk/src/Objects/ChatPermissions.php000064400000002674152665541660015742 0ustar00 Chat::class, 'from' => User::class, 'invite_link' => ChatInviteLink::class, ]; } } telegram-bot-sdk/src/Objects/BotCommand.php000064400000000734152665541660014645 0ustar00” to upload a new one using multipart/form-data under name. * @property InputFile|string|null $thumb (Optional). Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 90. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new file, so you can pass “attach://” if the thumbnail was uploaded using multipart/form-data under * @property string|null $caption (Optional). Caption of the video to be sent, 0-200 characters * @property string|null $parseMode (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @property int|null $width (Optional). Video width * @property int|null $height (Optional). Video height * @property int|null $duration (Optional). Video duration * @property bool|null $supportsStreaming (Optional). Pass True, if the uploaded video is suitable for streaming */ class InputMediaVideo extends InputMedia { /** * {@inheritdoc} * * @return array{thumb: string} */ public function relations(): array { return [ 'thumb' => InputFile::class, ]; } } telegram-bot-sdk/src/Objects/InputMedia/InputMediaAnimation.php000064400000003444152665541660020561 0ustar00” to upload a new one using multipart/form-data under name. * @property InputFile|string|null $thumb (Optional). Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 90. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new file, so you can pass “attach://” if the thumbnail was uploaded using multipart/form-data under * @property string|null $caption (Optional). Caption of the animation to be sent, 0-200 characters * @property string|null $parseMode (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @property int|null $width (Optional). Animation width * @property int|null $height (Optional). Animation height * @property int|null $duration (Optional). Animation duration */ class InputMediaAnimation extends InputMedia { /** * {@inheritdoc} * * @return array{thumb: string} */ public function relations(): array { return [ 'thumb' => InputFile::class, ]; } } telegram-bot-sdk/src/Objects/InputMedia/InputMediaPhoto.php000064400000001542152665541660017730 0ustar00” to upload a new one using multipart/form-data under name. * @property string|null $caption (Optional). Caption of the photo to be sent, 0-200 characters * @property string|null $parseMode (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. */ class InputMediaPhoto extends InputMedia {} telegram-bot-sdk/src/Objects/InputMedia/InputMedia.php000064400000000532152665541660016714 0ustar00” to upload a new one using multipart/form-data under name. * @property InputFile|string|null $thumb (Optional). Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 90. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new file, so you can pass “attach://” if the thumbnail was uploaded using multipart/form-data under * @property string|null $caption (Optional). Caption of the document to be sent, 0-200 characters * @property string|null $parseMode (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. */ class InputMediaDocument extends InputMedia { /** * {@inheritdoc} * * @return array{thumb: string} */ public function relations(): array { return [ 'thumb' => InputFile::class, ]; } } telegram-bot-sdk/src/Objects/InputMedia/InputMediaAudio.php000064400000003425152665541660017702 0ustar00” to upload a new one using multipart/form-data under name. * @property InputFile|string|null $thumb (Optional). Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 90. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new file, so you can pass “attach://” if the thumbnail was uploaded using multipart/form-data under * @property string|null $caption (Optional). Caption of the audio to be sent, 0-200 characters * @property string|null $parseMode (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * @property int|null $duration (Optional). Duration of the audio in seconds * @property string|null $performer (Optional). Performer of the audio * @property string|null $title (Optional). Title of the audio */ class InputMediaAudio extends InputMedia { /** * {@inheritdoc} * * @return array{thumb: string} */ public function relations(): array { return [ 'thumb' => InputFile::class, ]; } } telegram-bot-sdk/src/Objects/VoiceChatParticipantsInvited.php000064400000000742152665541660020373 0ustar00 [User::class], ]; } } telegram-bot-sdk/src/Objects/Update.php000064400000016254152665541660014050 0ustar00 Message::class, 'edited_message' => EditedMessage::class, 'channel_post' => Message::class, 'edited_channel_post' => EditedMessage::class, 'inline_query' => InlineQuery::class, 'chosen_inline_result' => ChosenInlineResult::class, 'callback_query' => CallbackQuery::class, 'shipping_query' => ShippingQuery::class, 'pre_checkout_query' => PreCheckoutQuery::class, 'poll' => Poll::class, 'poll_answer' => PollAnswer::class, 'my_chat_member' => ChatMemberUpdated::class, 'chat_member' => ChatMemberUpdated::class, 'chat_join_request' => ChatJoinRequest::class, ]; } /** * @deprecated Will be removed in SDK v4 * Get recent message. */ public function recentMessage(): self { return new self($this->last()); } /** * Determine if the update is of given type. */ public function isType(string $type): bool { if ($this->has(strtolower($type))) { return true; } return $this->detectType() === $type; } /** * Update type. */ public function objectType(): ?string { if ($this->updateType === null) { $isWebAppData = (bool) $this->getMessage()->get('web_app_data'); $updateType = $this->except('update_id')->keys()->first(); $this->updateType = $isWebAppData ? 'web_app_data' : $updateType; } return $this->updateType; } /** * Detect type based on properties. * * @deprecated Will be removed in v4.0, please use {@see \Telegram\Bot\Objects\Update::objectType} instead. */ public function detectType(): ?string { return $this->keys() ->intersect(static::TYPES) ->pop(); } /** * Get the message contained in the Update. */ public function getMessage(): Collection { return match ($this->detectType()) { 'message' => $this->message, 'edited_message' => $this->editedMessage, 'channel_post' => $this->channelPost, 'edited_channel_post' => $this->editedChannelPost, 'inline_query' => $this->inlineQuery, 'chosen_inline_result' => $this->chosenInlineResult, 'callback_query' => $this->callbackQuery->has('message') ? $this->callbackQuery->message : collect(), 'shipping_query' => $this->shippingQuery, 'pre_checkout_query' => $this->preCheckoutQuery, 'poll' => $this->poll, default => collect(), }; } /** * Borrowed from {@see \Telegram\Bot\Objects\Update::getMessage()} from SDK v4. * Get the message contained in the Update. */ public function getRelatedObject(): Message|InlineQuery|ChosenInlineResult|CallbackQuery|ShippingQuery|PreCheckoutQuery|Poll|PollAnswer { return $this->{$this->objectType()}; } /** * Get chat object (if exists). */ public function getChat(): Collection { if ($this->has('my_chat_member')) { // message is not available in such case return $this->myChatMember->chat; } if ($this->has('chat_boost')) { // message is not available in such case return $this->chat_boost->chat; } $message = $this->getMessage(); return $message->has('chat') ? $message->get('chat') : collect(); } /** * @deprecated This method will be removed in SDK v4 * Is there a command entity in this update object. */ public function hasCommand(): bool { return (bool) $this->getMessage()->get('entities', collect())->contains('type', 'bot_command'); } } telegram-bot-sdk/src/Objects/File.php000064400000001272152665541660013477 0ustar00/' to get the file. */ class File extends BaseObject { /** * {@inheritdoc} */ public function relations(): array { return []; } } telegram-bot-sdk/src/Objects/Voice.php000064400000001332152665541660013662 0ustar00 User::class, 'location' => Location::class, ]; } public function objectType(): ?string { return $this->findType(['location']); } } telegram-bot-sdk/src/Objects/UnknownObject.php000064400000000336152665541660015406 0ustar00 * [ * 'latitude' => '', // float - Required. Latitude of the location in degrees * 'longitude' => '', // float - Required. Longitude of the location in degrees * 'title' => '', // string - Required. Name of the venue * 'address' => '', // string - Required. Address of the venue * 'foursquare_id' => '', // string - (Optional). Foursquare identifier of the venue, if known * 'foursquare_type' => '', // string - (Optional). Foursquare type of the venue, if known. (For example, “arts_entertainment/default”, “arts_entertainment/aquarium” or “food/icecream”.) * 'google_place_id' => '', // string - (Optional). Google Places identifier of the venue * 'google_place_type' => '', // string - (Optional). Google Places type of the venue. * ] * * * @link https://core.telegram.org/bots/api#inputvenuemessagecontent * * @method $this setLatitude(float) Latitude of the location in degrees * @method $this setLongitude(float) Longitude of the location in degrees * @method $this setTitle(string) Name of the venue * @method $this setAddress(string) Address of the venue * @method $this setFoursquareIdTitle(string) (Optional). Foursquare identifier of the venue, if known * @method $this setFoursquareType(string) (Optional). Foursquare type of the venue, if known. (For example, “arts_entertainment/default”, “arts_entertainment/aquarium” or “food/icecream”.) */ class InputVenueMessageContent extends InlineBaseObject {} telegram-bot-sdk/src/Objects/InputContent/InputTextMessageContent.php000064400000002547152665541660022064 0ustar00 * [ * 'message_text' => '', // string - Required. Text of the message to be sent, 1-4096 characters. * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. * 'entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'disable_web_page_preview' => '', // bool - (Optional). Disables link previews for links in the sent message * ] * * * @link https://core.telegram.org/bots/api#inputtextmessagecontent * * @method $this setMessageText(string) Text of the message to be sent, 1-4096 characters. * @method $this setParseMode(string) (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. * @method $this setDisableWebPagePreview(bool) (Optional). Disables link previews for links in the sent message */ class InputTextMessageContent extends InlineBaseObject {} telegram-bot-sdk/src/Objects/InputContent/InputLocationMessageContent.php000064400000003042152665541660022677 0ustar00 * [ * 'latitude' => '', // float - Required. Latitude of the location in degrees * 'longitude' => '', // float - Required. Longitude of the location in degrees * 'horizontal_accuracy' => '', // float - (Optional). The radius of uncertainty for the location, measured in meters; 0-1500 * 'live_period' => '', // int - (Optional). Period in seconds for which the location can be updated, should be between 60 and 86400. * 'heading' => '', // int - (Optional). For live locations, a direction in which the user is moving, in degrees. Must be between 1 and 360 if specified. * 'proximity_alert_radius' => '', // int - (Optional). For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified. * ] * * @link https://core.telegram.org/bots/api#inputlocationmessagecontent * * @method $this setLatitude(float) Latitude of the location in degrees * @method $this setLongitude(float) Longitude of the location in degrees * @method $this setLivePeriod(int) (Optional). Period in seconds for which the location can be updated, should be between 60 and 86400. */ class InputLocationMessageContent extends InlineBaseObject {} telegram-bot-sdk/src/Objects/InputContent/InputContactMessageContent.php000064400000002070152665541660022522 0ustar00 * [ * 'phone_number' => '', // string - Required. Contact's phone number * 'first_name' => '', // string - Required. Contact's first name * 'last_name' => '', // string - (Optional). Contact's last name * 'vcard' => '', // string - (Optional). Additional data about the contact in the form of a vCard, 0-2048 bytes * ] * * * @link https://core.telegram.org/bots/api#inputcontactmessagecontent * * @method $this setPhoneNumber(string) Contact's phone number * @method $this setFirstName(string) Contact's first name * @method $this setLastName(string) (Optional). Contact's last name * @method $this setVcard(string) (Optional). Additional data about the contact in the form of a vCard, 0-2048 bytes */ class InputContactMessageContent extends InlineBaseObject {} telegram-bot-sdk/src/Objects/ChatMemberUpdated.php000064400000002224152665541660016134 0ustar00 Chat::class, 'from' => User::class, 'old_chat_member' => ChatMember::class, 'new_chat_member' => ChatMember::class, 'invite_link' => ChatInviteLink::class, ]; } } telegram-bot-sdk/src/Objects/GameHighScore.php000064400000000765152665541660015273 0ustar00 User::class, ]; } } telegram-bot-sdk/src/Objects/VoiceChatEnded.php000064400000000517152665541660015426 0ustar00} */ public function relations(): array { return [ 'user' => User::class, ]; } } telegram-bot-sdk/src/Objects/VoiceChatScheduled.php000064400000000643152665541660016307 0ustar00 Location::class, ]; } } telegram-bot-sdk/src/Objects/Document.php000064400000001624152665541660014377 0ustar00 PhotoSize::class, ]; } } telegram-bot-sdk/src/Objects/PollOption.php000064400000000625152665541660014720 0ustar00setContents($contents); } /** * Creates a new InputFile entity. * * @param string|resource|StreamInterface|null $file */ public function __construct(private mixed $file = null, private ?string $filename = null) {} /** * Return the file. * * @return string|resource|StreamInterface|null */ public function getFile() { return $this->file; } /** * Set File. * * @param string|resource|StreamInterface $file */ public function setFile(mixed $file): self { $this->file = $file; return $this; } /** * Return the name of the file. * * * @throws CouldNotUploadInputFile */ public function getFilename(): string { if ($this->filename === null && $this->isFileResourceOrStream()) { return $this->filename = $this->attemptFileNameDetection(); } return $this->filename ?? basename($this->file); } /** * Attempts to access the metadata in the stream or resource to determine what * the filename should be if the user did not supply one. * * * @throws CouldNotUploadInputFile */ private function attemptFileNameDetection(): string { if ($uri = $this->getUriMetaDataFromStream()) { return basename($uri); } throw CouldNotUploadInputFile::filenameNotProvided($this->file); } /** * Depending on if supplied Input was a resource or stream, call the appropriate * stream_meta command to get information required. * * Note: We can only get here if the file is a resource or a stream. */ private function getUriMetaDataFromStream(): ?string { $meta = is_resource($this->file) ? stream_get_meta_data($this->file) : $this->file->getMetadata(); return $meta['uri'] ?? null; } /** * Set a filename. * * * @throws InvalidArgumentException */ public function setFilename(?string $filename): self { if (! $this->isStringOrNull($filename)) { throw new InvalidArgumentException( 'Filename must be a string or null' ); } $this->filename = $filename; return $this; } /** * Get contents. * * @return StreamInterface|resource|string * * @throws CouldNotUploadInputFile */ public function getContents(): mixed { return $this->contents ?? $this->open(); } /** * Set contents of the file. */ public function setContents(string $contents): self { $this->contents = $contents; return $this; } /** * Opens remote & local file. * * @return StreamInterface|resource|string * * @throws CouldNotUploadInputFile */ private function open() { if ($this->isFileRemote()) { return $this->contents = new LazyOpenStream($this->file, 'r'); } if ($this->isFileLocalAndExists()) { return $this->contents = new LazyOpenStream($this->file, 'r'); } return $this->contents = $this->file; } /** * Determine if given param is a string or null. * * @return bool true if it's a string or null, false otherwise. */ private function isStringOrNull(mixed $param): bool { return is_string($param) || is_null($param); } /** * Determine if it's a remote file. * * @return bool true if it's a valid URL, false otherwise. */ public function isFileRemote(): bool { return is_string($this->file) && preg_match('#^(?:https?|ftps?|sftp|ssh2)://#', $this->file) === 1; } /** * Determine if it's a resource file. * * @return bool true if it's a resource file or an instance of * \Psr\Http\Message\StreamInterface, false otherwise. */ private function isFileResourceOrStream(): bool { return is_resource($this->file) || $this->file instanceof StreamInterface; } /** * Determine if it's a local file and exists. * * @return bool true if the file exists and readable, false if it's not a * local file. Throws exception if the file doesn't exist or * is not readable otherwise. * * @throws CouldNotUploadInputFile */ private function isFileLocalAndExists(): bool { if (! is_string($this->file)) { return false; } if (is_file($this->file) && is_readable($this->file)) { return true; } throw CouldNotUploadInputFile::fileDoesNotExistOrNotReadable($this->file); } } telegram-bot-sdk/src/Keyboard/Button.php000064400000003320152665541660014236 0ustar00 */ final class Button extends Base { /** * Button Label Text. */ public function setText(string $text): self { $this->items['text'] = $text; return $this; } } telegram-bot-sdk/src/Keyboard/Keyboard.php000064400000010734152665541660014532 0ustar00 * // For Standard Keyboard * $params = [ * 'keyboard' => '', * 'is_persistent' => '', * 'resize_keyboard' => '', * 'one_time_keyboard' => '', * 'selective' => '', * ]; * * * OR * * * // For Inline Keyboard * $params = [ * 'inline_keyboard' => '', * ]; * * * @method $this setIsPersistent($boolean) Optional. Requests clients to always show the keyboard when the regular keyboard is hidden. * @method $this setResizeKeyboard($boolean) Optional. Requests clients to resize the keyboard vertically for optimal fit. * @method $this setOneTimeKeyboard($boolean) Optional. Requests clients to hide the keyboard as soon as it's been used. * @method $this setSelective($boolean) Optional. Use this parameter if you want to show the keyboard to specific users only. * * @template TKey of array-key * @template TValue * * @extends Base */ final class Keyboard extends Base { /** @var bool Make an Inline Keyboard */ private bool $inline = false; /** * Represents one button of an inline keyboard. * * You must use exactly one of the optional fields. * You can also utilise the fluent API to build the params payload. * * * $params = [ * 'text' => '', * 'url' => '', * 'login_url' => '', * 'callback_data' => '', * 'switch_inline_query' => '', * 'switch_inline_query_current_chat' => '', * 'callback_game' => '', * 'pay' => '', * ]; * * * @link https://core.telegram.org/bots/api#inlinekeyboardbutton */ public static function inlineButton(string|array $params = []): string|array|Button { return self::button($params); } /** * Represents one button of the Reply keyboard. * * For simple text buttons String can be used instead of an array. * You can also utilise the fluent API to build the params payload. * * * $params = 'string' * * OR * * $params = [ * 'text' => '', * 'request_contact' => '', * 'request_location' => '', * ]; * * * @link https://core.telegram.org/bots/api#keyboardbutton */ public static function button(string|array $params = []): string|array|Button { if (is_string($params)) { return $params; } return Button::make($params); } /** * Represents the `ReplyKeyboardRemove` class in the Telegram Bot API, which is used to request clients to remove * the custom keyboard and display the default letter-keyboard. * * * $params = [ * 'remove_keyboard' => true, * 'selective' => false, * ]; * * * @link https://core.telegram.org/bots/api#replykeyboardremove */ public static function remove(array $params = []): self { return new self(array_merge(['remove_keyboard' => true, 'selective' => false], $params)); } /** * Display a reply interface to the user (act as if the user has selected the bots message and tapped "Reply"). * * * $params = [ * 'force_reply' => true, * 'selective' => false, * ]; * * * @link https://core.telegram.org/bots/api#forcereply */ public static function forceReply(array $params = []): self { return new self(array_merge(['force_reply' => true, 'selective' => false], $params)); } /** * Make this keyboard inline, So it appears right next to the message it belongs to. * * @link https://core.telegram.org/bots/api#inlinekeyboardmarkup */ public function inline(): self { $this->inline = true; return $this; } /** * Determine if it's an inline keyboard. */ public function isInlineKeyboard(): bool { return $this->inline; } /** * Create a new row in keyboard to add buttons. */ public function row(array $buttons = []): self { $property = $this->inline ? 'inline_keyboard' : 'keyboard'; $this->items[$property][] = $buttons; return $this; } } telegram-bot-sdk/src/Keyboard/Base.php000064400000001233152665541660013636 0ustar00 */ class Base extends Collection { /** * Dynamically build params. * * @param string $method * @return $this */ public function __call($method, $parameters) { if (! Str::startsWith($method, 'set')) { return parent::__call($method, $parameters); } $property = Str::snake(substr($method, 3)); $this->items[$property] = $parameters[0]; return $this; } } telegram-bot-sdk/src/Helpers/Emojify.php000064400000011325152665541660014233 0ustar00setupEmojiMaps(); } /** * Returns the *Singleton* instance of this class. * * @return Emojify The *Singleton* instance. */ public static function getInstance(): ?\Telegram\Bot\Helpers\Emojify { if (! self::$instance instanceof \Telegram\Bot\Helpers\Emojify) { self::$instance = new self; } return self::$instance; } /** * Set File Path to Emoji Map File. * * @param string $emojiMapFile */ public function setEmojiMapFile($emojiMapFile): self { $this->emojiMapFile = $emojiMapFile; $this->setupEmojiMaps(); return $this; } /** * Translate Word to Emoji. * * @return mixed */ public function toEmoji($text) { return $this->replace($text, $this->emojiMap); } /** * Alias of toEmoji(). * * @return mixed */ public static function text($text) { return self::getInstance()->toEmoji($text); } /** * Translate Emoji to Word. * * @return mixed */ public function toWord($text) { return $this->replace($text, $this->wordMap, true); } /** * Alias of toWord(). * * @return mixed */ public static function translate($text) { return self::getInstance()->toWord($text); } /** * Replace. * * @return mixed */ private function replace($line, array $replace, bool $toWord = false, string $delimiter = ':') { if ($toWord) { return $this->emojiToWordReplace($line, $replace, $delimiter); } return $this->wordToEmojiReplace($line, $replace, $delimiter); } /** * Finds words enclosed by the delimiter and converts them to the * appropriate emoji character. * * @return mixed */ private function wordToEmojiReplace($line, array $replace, string $delimiter) { foreach ($replace as $key => $value) { $line = str_replace($delimiter.$key.$delimiter, $value, $line); } return $line; } /** * Finds emojis and replaces them with text enclosed by the delimiter. * * @return mixed */ private function emojiToWordReplace($line, array $replace, string $delimiter) { foreach ($replace as $key => $value) { $line = str_replace($key, $delimiter.$value.$delimiter, $line); } return $line; } /** * Get Emoji Map Array. * * @return array * * @throws TelegramEmojiMapFileNotFoundException */ private function getEmojiMap() { if ($this->emojiMapFile === null) { $this->emojiMapFile = realpath(__DIR__.self::DEFAULT_EMOJI_MAP_FILE); } if (! file_exists($this->emojiMapFile)) { throw new TelegramEmojiMapFileNotFoundException; } return json_decode(file_get_contents($this->emojiMapFile), true, 512, JSON_THROW_ON_ERROR); } /** * Setup Emoji Maps. * * @throws TelegramEmojiMapFileNotFoundException */ private function setupEmojiMaps(): void { $this->emojiMap = $this->getEmojiMap(); $this->wordMap = array_flip($this->emojiMap); } /** * Throw an exception when the user tries to clone the *Singleton* * instance. * * @throws LogicException always */ public function __clone() { throw new LogicException('The Emojify helper cannot be cloned'); } /** * Throw an exception when the user tries to unserialize the *Singleton* * instance. * * @throws LogicException always */ public function __wakeup() { throw new LogicException('The Emojify helper cannot be serialised'); } } telegram-bot-sdk/src/Helpers/Entities.php000064400000005143152665541660014416 0ustar00entities = $entities; return $this; } /** * Format it to markdown style. */ public function toMarkdown(): string { $this->mode = 0; return $this->apply(); } /** * Format it to HTML syntax. */ public function toHTML(): string { $this->mode = 1; return $this->apply(); } /** * Apply format for given text and entities. */ private function apply(): string { $syntax = $this->syntax(); foreach (array_reverse($this->entities) as $entity) { $value = mb_substr($this->text, $entity['offset'], $entity['length']); $type = $entity['type']; $replacement = match ($type) { 'text_link' => sprintf($syntax[$type][$this->mode], $value, $entity['url']), 'text_mention' => sprintf($syntax[$type][$this->mode], $entity['user']['username']), default => sprintf($syntax[$type][$this->mode], $value), }; $this->text = substr_replace($this->text, $replacement, $entity['offset'], $entity['length']); } return $this->text; } /** * Formatting Syntax. * * @return array{bold: string[], italic: string[], code: string[], pre: string[], text_mention: string[], text_link: string[]} */ private function syntax(): array { // No need of any special formatting for these entity types. // 'url', 'bot_command', 'hashtag', 'cashtag', 'email', 'phone_number', 'mention' return [ 'bold' => ['*%s*', '%s'], 'italic' => ['_%s_', '%s'], 'code' => ['`%s`', '%s'], 'pre' => ["```\n%s```", '
%s
'], 'text_mention' => ['[%1$s](tg://user?id=%1$s)', '%1$s'], 'text_link' => ['[%s](%s)', '%1$s'], // underline doesn't have a markdown style 'underline' => ['%s', '%s'], ]; } } telegram-bot-sdk/src/Exceptions/TelegramEmojiMapFileNotFoundException.php000064400000000246152665541660022666 0ustar00responseData = $response->getDecodedBody(); $errorMessage = $this->get('description', 'Unknown error from API Response.'); $errorCode = $this->get('error_code', -1); parent::__construct($errorMessage, $errorCode, $previousException); } /** * Checks isset and returns that or a default value. * * @param string $key * @return mixed */ public function get($key, mixed $default = null) { return $this->responseData[$key] ?? $default; } /** * A factory for creating the appropriate exception based on the response from Telegram. * * @param TelegramResponse $response The response that threw the exception. */ public static function create(TelegramResponse $response): self { $data = $response->getDecodedBody(); $code = null; $message = null; if (isset($data['ok'], $data['error_code']) && $data['ok'] === false) { $code = $data['error_code']; $message = $data['description'] ?? 'Unknown error from API.'; } // Others return new self($response, new TelegramOtherException($message, $code)); } /** * Returns the HTTP status code. */ public function getHttpStatusCode(): ?int { return $this->response->getHttpStatusCode(); } /** * Returns the error type. */ public function getErrorType(): string { return $this->get('type', ''); } /** * Returns the raw response used to create the exception. */ public function getRawResponse(): string { return $this->response->getBody(); } /** * Returns the decoded response used to create the exception. */ public function getResponseData(): array { return $this->responseData; } /** * Returns the response entity used to create the exception. */ public function getResponse(): TelegramResponse { return $this->response; } } telegram-bot-sdk/src/Exceptions/TelegramOtherException.php000064400000000227152665541660017770 0ustar00setAccessToken($accessToken); $this->setMethod($method); $this->setEndpoint($endpoint); $this->setParams($params); $this->setAsyncRequest($isAsyncRequest); } /** * Make this request asynchronous (non-blocking). */ public function setAsyncRequest(bool $isAsyncRequest): self { $this->isAsyncRequest = $isAsyncRequest; return $this; } /** * Validate that bot access token exists for this request. * * @throws TelegramSDKException */ public function validateAccessToken(): void { if ($this->accessToken === null) { throw new TelegramSDKException('You must provide your bot access token to make any API requests.'); } } /** * Return the bot access token for this request. */ public function getAccessToken(): ?string { return $this->accessToken; } /** * Set the bot access token for this request. */ public function setAccessToken(?string $accessToken): self { $this->accessToken = $accessToken; return $this; } /** * Validate that the HTTP method is set. * * @throws TelegramSDKException */ public function validateMethod(): void { if ($this->method === '' || $this->method === '0') { throw new TelegramSDKException('HTTP method not specified.'); } if (! in_array($this->method, ['GET', 'POST'])) { throw new TelegramSDKException('Invalid HTTP method specified. Must be GET or POST'); } } /** * Return the API Endpoint for this request. */ public function getEndpoint(): string { return $this->endpoint; } /** * Set the endpoint for this request. */ public function setEndpoint(?string $endpoint): self { $this->endpoint = $endpoint; return $this; } /** * Return the headers for this request. */ public function getHeaders(): array { $headers = $this->getDefaultHeaders(); return array_merge($this->headers, $headers); } /** * Set the headers for this request. */ public function setHeaders(array $headers): self { $this->headers = array_merge($this->headers, $headers); return $this; } /** * The default headers used with every request. */ public function getDefaultHeaders(): array { return [ 'User-Agent' => 'Telegram Bot PHP SDK v'.Api::VERSION.' (https://github.com/irazasyed/telegram-bot-sdk)', ]; } /** * Check if this is an asynchronous request (non-blocking). */ public function isAsyncRequest(): bool { return $this->isAsyncRequest; } /** * Only return params on POST requests. */ public function getPostParams(): array { if ($this->method === 'POST') { return $this->params; } return []; } /** * Return the HTTP method for this request. */ public function getMethod(): string { return $this->method; } /** * Set the HTTP method for this request. */ public function setMethod(?string $method): self { $this->method = strtoupper($method); return $this; } /** * Return the params for this request. */ public function getParams(): array { return $this->params; } /** * Set the params for this request. */ public function setParams(array $params = []): self { $this->params = array_merge($this->params, $params); return $this; } /** * Get Timeout. */ public function getTimeOut(): int { return $this->timeOut; } /** * Set Timeout. */ public function setTimeOut(int $timeOut): self { $this->timeOut = $timeOut; return $this; } /** * Get Connection Timeout. */ public function getConnectTimeOut(): int { return $this->connectTimeOut; } /** * Set Connection Timeout. */ public function setConnectTimeOut(int $connectTimeOut): self { $this->connectTimeOut = $connectTimeOut; return $this; } } telegram-bot-sdk/src/Methods/Message.php000064400000123231152665541660014216 0ustar00 * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'text' => '', // string - Required. Text of the message to be sent * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. * 'entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'disable_web_page_preview' => '', // bool - (Optional). Disables link previews for links in this message * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply' => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // object - (Optional). One of either InlineKeyboardMarkup|ReplyKeyboardMarkup|ReplyKeyboardRemove|ForceReply for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendmessage * * @throws TelegramSDKException */ public function sendMessage(array $params): MessageObject { $response = $this->post('sendMessage', $params); return new MessageObject($response->getDecodedBody()); } /** * Forward messages of any kind. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'from_chat_id' => '', // int - Required. Unique identifier for the chat where the original message was sent (or channel username in the format "@channelusername") * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'message_id' => '', // int - Required. Message identifier in the chat specified in from_chat_id * ] * * * @link https://core.telegram.org/bots/api#forwardmessage * * @throws TelegramSDKException */ public function forwardMessage(array $params): MessageObject { $response = $this->post('forwardMessage', $params); return new MessageObject($response->getDecodedBody()); } /** * Copy messages of any kind. * * The method is analogous to the method forwardMessages, but the copied message doesn't have a link to the original message. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'from_chat_id' => '', // int - Required. Unique identifier for the chat where the original message was sent (or channel username in the format "@channelusername") * 'message_id' => '', // int - Required. Message identifier in the chat specified in from_chat_id * 'caption' => '', // string - (Optional). New caption for media, 0-1024 characters after entities parsing. If not specified, the original caption is kept * 'parse_mode' => '', // string - (Optional). Mode for parsing entities in the new caption. See formatting options for more details. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the new caption, which can be specified instead of parse_mode * 'disable_notification' => '', // bool - (Optional). Sends the message silently. Users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply' => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#copymessage * * @throws TelegramSDKException */ public function copyMessage(array $params): MessageObject { $response = $this->post('copyMessage', $params); return new MessageObject($response->getDecodedBody()); } /** * Send Photo. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'photo' => InputFile::file($file), // InputFile|string - Required. Photo to send. Pass a file_id as String to send a photo that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a photo from the Internet, or upload a new photo using multipart/form-data. * 'caption' => '', // string - (Optional). Photo caption (may also be used when resending photos by file_id), 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply' => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendphoto * * @throws TelegramSDKException */ public function sendPhoto(array $params): MessageObject { $response = $this->uploadFile('sendPhoto', $params, 'photo'); return new MessageObject($response->getDecodedBody()); } /** * Send regular audio files. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'audio' => InputFile::file($file), // InputFile|string - Required. Audio file to send. Pass a file_id as String to send an audio file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an audio file from the Internet, or upload a new one using multipart/form-data. * 'caption' => '', // string - (Optional). Audio caption, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'duration' => '', // int - (Optional). Duration of the audio in seconds * 'performer' => '', // string - (Optional). Performer * 'title' => '', // string - (Optional). Track name * 'thumb' => InputFile::file($file), // InputFile|string - (Optional). Thumbnail can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Thumbnails can't be reused and can be only uploaded as a new file. * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply' => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * @link https://core.telegram.org/bots/api#sendaudio * * * @throws TelegramSDKException */ public function sendAudio(array $params): MessageObject { $response = $this->uploadFile('sendAudio', $params, 'audio'); return new MessageObject($response->getDecodedBody()); } /** * Send general files. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'document' => InputFile::file($file), // InputFile|string - Required. File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. * 'thumb' => InputFile::file($file), // InputFile|string - (Optional). Thumbnail can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Thumbnails can't be reused and can be only uploaded as a new file. * 'caption' => '', // string - (Optional). Document caption (may also be used when resending documents by file_id), 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'disable_content_type_detection' => '', // bool - (Optional). Disables automatic server-side content type detection for files uploaded using multipart/form-data * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#senddocument * * @throws TelegramSDKException */ public function sendDocument(array $params): MessageObject { $response = $this->uploadFile('sendDocument', $params, 'document'); return new MessageObject($response->getDecodedBody()); } /** * Send Video File, Telegram clients support mp4 videos (other formats may be sent as Document). * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'video' => InputFile::file($file), // InputFile|string - Required. Video to send. Pass a file_id as String to send a video that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a video from the Internet, or upload a new video using multipart/form-data. * 'duration' => '', // int - (Optional). Duration of sent video in seconds * 'width' => '', // int - (Optional). Video width * 'height' => '', // int - (Optional). Video height * 'thumb' => InputFile::file($file), // InputFile|string - (Optional). Thumbnail can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Thumbnails can't be reused and can be only uploaded as a new file. * 'caption' => '', // string - (Optional). Video caption (may also be used when resending videos by file_id), 0-200 characters. * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'supports_streaming' => '', // bool - (Optional). Pass True, if the uploaded video is suitable for streaming * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply' => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendvideo * @see sendDocument * * @throws TelegramSDKException */ public function sendVideo(array $params): MessageObject { $response = $this->uploadFile('sendVideo', $params, 'video'); return new MessageObject($response->getDecodedBody()); } /** * Send send animation files (GIF or H.264/MPEG-4 AVC video without sound). * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'animation' => InputFile::file($file), // InputFile|string - Required. Animation to send. Pass a file_id as String to send an animation that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an animation from the Internet, or upload a new animation using multipart/form-data. * 'duration' => '', // int - (Optional). Duration of sent animation in seconds * 'width' => '', // int - (Optional). Animation width * 'height' => '', // int - (Optional). Animation height * 'thumb' => InputFile::file($file), // InputFile|string - (Optional). Thumbnail can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Thumbnails can't be reused and can be only uploaded as a new file. * 'caption' => '', // string - (Optional). Document caption (may also be used when resending documents by file_id), 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply' => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendanimation * * @throws TelegramSDKException */ public function sendAnimation(array $params): MessageObject { $response = $this->uploadFile('sendAnimation', $params, 'animation'); return new MessageObject($response->getDecodedBody()); } /** * Send voice audio files. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'voice' => InputFile::file($file), // InputFile|string - Required. Audio file to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. * 'caption' => '', // string - (Optional). Voice message caption, 0-200 characters * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'duration' => '', // int - (Optional). Duration of the voice message in seconds * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply' => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendvoice * * @throws TelegramSDKException */ public function sendVoice(array $params): MessageObject { $response = $this->uploadFile('sendVoice', $params, 'voice'); return new MessageObject($response->getDecodedBody()); } /** * Send rounded square mp4 videos of up to 1 minute long. Use this method to send video messages. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'video_note' => InputFile::file($file), // InputFile|string - Required. Video note to send. Pass a file_id as String to send a video note that exists on the Telegram servers (recommended) or upload a new video using multipart/form-data. * 'duration' => '', // int - (Optional). Duration of sent video in seconds * 'length' => '', // int - (Optional). Video width and height * 'thumb' => InputFile::file($file), // InputFile|string - (Optional). Thumbnail can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Thumbnails can't be reused and can be only uploaded as a new file. * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendvideonote * * @throws TelegramSDKException */ public function sendVideoNote(array $params): MessageObject { $response = $this->uploadFile('sendVideoNote', $params, 'video_note'); return new MessageObject($response->getDecodedBody()); } /** * Send a group of photos, audio, documents or videos as an album. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'media' => [], // array - Required. A JSON-serialized array describing messages to be sent, must include 2-10 items. Array of InputMediaAudio, InputMediaDocument, InputMediaPhoto and InputMediaVideo * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent messages from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * ] * * * @link https://core.telegram.org/bots/api#sendmediagroup * * @throws TelegramSDKException * //TODO Check this return type. */ public function sendMediaGroup(array $params): MessageObject { $response = $this->uploadFile('sendMediaGroup', $params, 'media'); return new MessageObject($response->getDecodedBody()); } /** * Send information about a venue. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'latitude' => '', // float - Required. Latitude of the venue * 'longitude' => '', // float - Required. Longitude of the venue * 'title' => '', // string - Required. Name of the venue * 'address' => '', // string - Required. Address of the venue * 'foursquare_id' => '', // string - (Optional). Foursquare identifier of the venue * 'foursquare_type' => '', // string - (Optional). Foursquare type of the venue, if known. (For example, “arts_entertainment/default”, “arts_entertainment/aquarium” or “food/icecream”.) * 'google_place_id' => '', // string - (Optional). Google Places identifier of the venue * 'google_place_type' => '', // string - (Optional). Google Places type of the venue. * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendvenue * * @throws TelegramSDKException */ public function sendVenue(array $params): MessageObject { $response = $this->post('sendVenue', $params); return new MessageObject($response->getDecodedBody()); } /** * Send phone contacts. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'phone_number' => '', // string - Required. Contact's phone number * 'first_name' => '', // string - Required. Contact's first name * 'last_name' => '', // string - Required. Contact's last name * 'vcard' => '', // string - (Optional). Additional data about the contact in the form of a vCard, 0-2048 bytes * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendcontact * * @throws TelegramSDKException */ public function sendContact(array $params): MessageObject { $response = $this->post('sendContact', $params); return new MessageObject($response->getDecodedBody()); } /** * Send a poll. * * Use this method to send a native poll. A native poll can't be sent to a private chat. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername"). A native poll can't be sent to a private chat. * 'question' => '', // string - Required. Poll question, 1-255 characters * 'options' => '', // array - Required. List of answer options, 2-10 strings 1-100 characters each * 'is_anonymous' => '', // bool - (Optional). True, if the poll needs to be anonymous, defaults to True * 'type' => '', // string - (Optional). Poll type, “quiz” or “regular”, defaults to “regular” * 'allows_multiple_answers' => '', // bool - (Optional). True, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to False * 'correct_option_id' => '', // int - (Optional). 0-based identifier of the correct answer option, required for polls in quiz mode * 'explanation' => '', // string - (Optional). Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing * 'explanation_parse_mode' => '', // string - (Optional). Mode for parsing entities in the explanation. See formatting options for more details. * 'explanation_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'open_period' => '', // int - (Optional). Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with close_date. * 'close_date' => '', // int - (Optional). Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with open_period. * 'is_closed' => '', // bool - (Optional). Pass True, if the poll needs to be immediately closed. This can be useful for poll preview. * 'disable_notification' => '', // bool - (Optional). Sends the message silently. Users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply' => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendpoll * * @throws TelegramSDKException */ public function sendPoll(array $params): MessageObject { $params['options'] = is_string($params['options']) ? $params['options'] : json_encode($params['options'], JSON_THROW_ON_ERROR); $response = $this->post('sendPoll', $params); return new MessageObject($response->getDecodedBody()); } /** * Send a dice. * * Use this method to send a dice, which will have a random value from 1 to 6 * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername"). A native poll can't be sent to a private chat. * 'emoji' => '', // string - (Optional). Emoji on which the dice throw animation is based. Currently, must be one of “🎲”, “🎯”, “🏀”, “⚽”, “🎳”, or “🎰”. Dice can have values 1-6 for “🎲”, “🎯” and “🎳”, values 1-5 for “🏀” and “⚽”, and values 1-64 for “🎰”. Defaults to “🎲” * 'disable_notification' => '', // bool - (Optional). Sends the message silently. Users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#senddice * * @throws TelegramSDKException */ public function sendDice(array $params): MessageObject { $response = $this->post('sendDice', $params); return new MessageObject($response->getDecodedBody()); } /** * Broadcast a Chat Action. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'action' => '', // string - Required. Type of action to broadcast. Choose one, depending on what the user is about to receive: typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_voice or upload_voice for voice notes, upload_document for general files, choose_sticker for stickers, find_location for location data, record_video_note or upload_video_note for video notes. * ] * * * @link https://core.telegram.org/bots/api#sendchataction * * @throws TelegramSDKException */ public function sendChatAction(array $params): bool { Actions::isActionValid($params['action']); return $this->post('sendChatAction', $params)->getResult(); } /** * Send a poll. * * Use this method to send a native poll. A native poll can't be sent to a private chat. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername"). A native poll can't be sent to a private chat. * 'message_id' => '', // int - Required. Identifier of the target message. If the message belongs to a media group, the reaction is set to the first non-deleted message in the group instead. * 'reaction' => '', // ReactionType[] - (Optional). A JSON-serialized list of reaction types to set on the message. Currently, as non-premium users, bots can set up to one reaction per message. A custom emoji reaction can be used if it is either already present on the message or explicitly allowed by chat administrators. * 'is_big' => '', // bool - (Optional). Pass True to set the reaction with a big animation * ] * * * @link https://core.telegram.org/bots/api#setmessagereaction * * @throws TelegramSDKException */ public function setMessageReaction(array $params): bool { $params['reaction'] = json_encode(Arr::wrap($params['reaction']), JSON_THROW_ON_ERROR); return $this->post('setMessageReaction', $params)->getResult(); } } telegram-bot-sdk/src/Methods/Game.php000064400000010433152665541660013502 0ustar00 * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'game_short_name' => '', // string - Required. Short name of the game, serves as the unique identifier for the game. Set up your games via Botfather. * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). A JSON-serialized object for an inline keyboard. If empty, one ‘Play game_title’ button will be shown. If not empty, the first button must launch the game. * ] * * * @link https://core.telegram.org/bots/api#sendgame * * @throws TelegramSDKException */ public function sendGame(array $params): Message { $response = $this->post('sendGame', $params); return new Message($response->getDecodedBody()); } /** * Set the score of the specified user in a game. * * * $params = [ * 'user_id' => '', // int - Required. User identifier * 'score' => '', // int - Required. New score, must be non-negative * 'force' => '', // bool - (Optional). Pass True, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters * 'disable_edit_message' => '', // bool - (Optional). Pass True, if the game message should not be automatically edited to include the current scoreboard * 'chat_id' => '', // int - (Optional). Required if inline_message_id is not specified. Unique identifier for the target chat * 'message_id' => '', // int - (Optional). Required if inline_message_id is not specified. Identifier of the sent message * 'inline_message_id' => '', // string - (Optional). Required if chat_id and message_id are not specified. Identifier of the inline message * ] * * * @link https://core.telegram.org/bots/api#setgamescore * * @throws TelegramSDKException */ public function setGameScore(array $params): Message { $response = $this->post('setGameScore', $params); return new Message($response->getDecodedBody()); } /** * Set the score of the specified user in a game. * * * $params = [ * 'user_id' => '', // int - Required. Target user id * 'chat_id' => '', // int|string - (Optional). Required if inline_message_id is not specified. Unique identifier for the target chat * 'message_id' => '', // int - (Optional). Required if inline_message_id is not specified. Identifier of the sent message * 'inline_message_id' => '', // string - (Optional). Required if chat_id and message_id are not specified. Identifier of the inline message * ] * * * @link https://core.telegram.org/bots/api#getgamehighscores * * @return GameHighScore[] * * @throws TelegramSDKException */ public function getGameHighScores(array $params): array { return collect($this->get('getGameHighScores', $params)->getResult()) ->mapInto(GameHighScore::class) ->all(); } } telegram-bot-sdk/src/Methods/Chat.php000064400000065676152665541660013533 0ustar00 * $params = [ * 'chat_id' => '', * 'user_id' => '', * 'until_date' => '' * ]; * * @link https://core.telegram.org/bots/api#kickchatmember * * @param array $params [ * * @var int|string Required. Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername) * @var int Required. Unique identifier of the target user. * @var int (Optional). Unique identifier of the target user. * * ] * * @throws TelegramSDKException */ public function kickChatMember(array $params): bool { return $this->get('kickChatMember', $params)->getResult(); } /** * Ban a user in a group, a supergroup or a channel * * In the case of supergroups, the user will not be able to return to the group on their own using * invite links etc., unless unbanned first. * * The bot must be an administrator in the group for this to work. * * Note: This will method only work if the ‘All Members Are Admins’ setting is off in the target group. * Otherwise members may only be removed by the group's creator or by the member that added them. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target group or username of the target supergroup (in the format "@supergroupusername") * 'user_id' => '', // int - Required. Unique identifier of the target user. * 'until_date' => '', // int - (Optional). Date when the user will be unbanned, unix time. If user is banned for more than 366 days or less than 30 seconds from the current time they are considered to be banned forever. Applied for supergroups and channels only. * 'revoke_messages' => '', // bool - (Optional). Pass True to delete all messages from the chat for the user that is being removed. If False, the user will be able to see messages in the group that were sent before the user was removed. Always True for supergroups and channels. * ] * * * @link https://core.telegram.org/bots/api#banchatmember * * @throws TelegramSDKException */ public function banChatMember(array $params): bool { return $this->get('banChatMember', $params)->getResult(); } /** * Export an invite link to a supergroup or a channel. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * ] * * * @link https://core.telegram.org/bots/api#exportchatinvitelink * * @throws TelegramSDKException */ public function exportChatInviteLink(array $params): string { return $this->post('exportChatInviteLink', $params)->getResult(); } /** * Create an additional invite link for a chat * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format @channelusername) * 'name' => '', // string - (Optional). Invite link name; 0-32 characters * 'expire_date' => '', // int - (Optional). Point in time (Unix timestamp) when the link will expire * 'member_limit' => '', // int - (Optional). Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999 * 'creates_join_request' => '', // bool - (Optional). True, if users joining the chat via the link need to be approved by chat administrators. If True, member_limit can't be specified * ] * * * @link https://core.telegram.org/bots/api#createchatinvitelink * * @throws TelegramSDKException */ public function createChatInviteLink(array $params): ChatInviteLink { return new ChatInviteLink($this->post('createChatInviteLink', $params)->getDecodedBody()); } /** * Edit a non-primary invite link created by the bot. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format @channelusername) * 'invite_link' => '', // string - Required. The invite link to edit * 'name' => '', // string - (Optional). Invite link name; 0-32 characters * 'expire_date' => '', // int - (Optional). Point in time (Unix timestamp) when the link will expire * 'member_limit' => '', // int - (Optional). Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999 * 'creates_join_request' => '', // bool - (Optional). True, if users joining the chat via the link need to be approved by chat administrators. If True, member_limit can't be specified * ] * * * @link https://core.telegram.org/bots/api#editchatinvitelink * * @throws TelegramSDKException */ public function editChatInviteLink(array $params): ChatInviteLink { return new ChatInviteLink($this->post('editChatInviteLink', $params)->getDecodedBody()); } /** * Revoke an invite link created by the bot. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format @channelusername) * 'invite_link' => '', // string - Required. The invite link to revoke * ] * * * @link https://core.telegram.org/bots/api#revokechatinvitelink * * @throws TelegramSDKException */ public function revokeChatInviteLink(array $params): ChatInviteLink { return new ChatInviteLink($this->post('revokeChatInviteLink', $params)->getDecodedBody()); } /** * Approve a chat join request * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format @channelusername) * 'user_id' => '', // int - Required. Unique identifier of the target user * ] * * * @link https://core.telegram.org/bots/api#approvechatjoinrequest */ public function approveChatJoinRequest(array $params): bool { return $this->post('approveChatJoinRequest', $params)->getResult(); } /** * Decline a chat join request * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format @channelusername) * 'user_id' => '', // int - Required. Unique identifier of the target user * ] * * * @link https://core.telegram.org/bots/api#declinechatjoinrequest */ public function declineChatJoinRequest(array $params): bool { return $this->post('declineChatJoinRequest', $params)->getResult(); } /** * Set a new profile photo for the chat. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'photo' => InputFile::file($file), // InputFile - Required. New chat photo, uploaded using multipart/form-data * ] * * * @link https://core.telegram.org/bots/api#setchatphoto * * @throws TelegramSDKException */ public function setChatPhoto(array $params): bool { return $this->uploadFile('setChatPhoto', $params, 'photo')->getResult(); } /** * Delete a chat photo. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * ] * * * @link https://core.telegram.org/bots/api#deletechatphoto * * @throws TelegramSDKException */ public function deleteChatPhoto(array $params): bool { return $this->post('deleteChatPhoto', $params)->getResult(); } /** * Set the title of a chat. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'title' => '', // string - Required. New chat title, 1-255 characters * ] * * * @link https://core.telegram.org/bots/api#setchattitle * * @throws TelegramSDKException */ public function setChatTitle(array $params): bool { return $this->post('setChatTitle', $params)->getResult(); } /** * Set the description of a supergroup or a channel. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'description' => '', // string - (Optional). New chat description, 0 - 255 characters. * ] * * * @link https://core.telegram.org/bots/api#setchatdescription * * @throws TelegramSDKException */ public function setChatDescription(array $params): bool { return $this->post('setChatDescription', $params)->getResult(); } /** * Pin a message in a group, a supergroup, or a channel. * * The bot must be an administrator in the chat for this to work and must have the ‘can_pin_messages’ admin right in the supergroup * or ‘can_edit_messages’ admin right in the channel. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - Required. Identifier of a message to pin * 'disable_notification' => '', // bool - (Optional). Pass True, if it is not necessary to send a notification to all group members about the new pinned message * ] * * * @link https://core.telegram.org/bots/api#pinchatmessage * * @throws TelegramSDKException */ public function pinChatMessage(array $params): bool { return $this->post('pinChatMessage', $params)->getResult(); } /** * Unpin a message in a group, a supergroup, or a channel. * * The bot must be an administrator in the chat for this to work and must have the ‘can_pin_messages’ admin right in the supergroup * or ‘can_edit_messages’ admin right in the channel. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - (Optional). Identifier of a message to unpin. If not specified, the most recent pinned message (by sending date) will be unpinned. * ] * * * @link https://core.telegram.org/bots/api#unpinchatmessage * * @throws TelegramSDKException */ public function unpinChatMessage(array $params): bool { return $this->post('unpinChatMessage', $params)->getResult(); } /** * Unpin/clear the list of pinned messages in a chat. * * If the chat is not a private chat, the bot must be an administrator in the chat for this to work * and must have the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right * in a channel. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * ] * * * @link https://core.telegram.org/bots/api#unpinallchatmessages * * @throws TelegramSDKException */ public function unpinAllChatMessages(array $params): bool { return $this->post('unpinAllChatMessages', $params)->getResult(); } /** * Use this method for your bot to leave a group, supergroup or channel. * * * $params = [ * 'chat_id' => '', // string|int - Unique identifier for the target chat or username of the target supergroup or channel (in the format "@channelusername") * ] * * * @link https://core.telegram.org/bots/api#leavechat * * @throws TelegramSDKException */ public function leaveChat(array $params): bool { return $this->get('leaveChat', $params)->getResult(); } /** * Unban a previously kicked user in a supergroup. * * The user will not return to the group automatically, but will be able to join via link, etc. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // int|string - Unique identifier for the target group or username of the target supergroup (in the format "@supergroupusername") * 'user_id' => '', // int - Unique identifier of the target user. * 'only_if_banned' => '', // bool - (Optional). Do nothing if the user is not banned * ] * * * @link https://core.telegram.org/bots/api#unbanchatmember * * @throws TelegramSDKException */ public function unbanChatMember(array $params): bool { return $this->get('unbanChatMember', $params)->getResult(); } /** * Restrict a user in a supergroup. * * Pass True for all boolean parameters to lift restrictions from a user. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target group or username of the target supergroup (in the format "@supergroupusername") * 'user_id' => '', // int - Required. Unique identifier of the target user. * 'permissions' => '', // ChatPermissions - Required. New user permissions * 'until_date' => '', // int - (Optional). Date when restrictions will be lifted for the user, unix time. If user is restricted for more than 366 days or less than 30 seconds from the current time, they are considered to be restricted forever. * ] * * * @link https://core.telegram.org/bots/api#restrictchatmember * * @throws TelegramSDKException */ public function restrictChatMember(array $params): bool { return $this->post('restrictChatMember', $params)->getResult(); } /** * Promote or demote a user in a supergroup or a channel. * * Pass False for all boolean parameters to demote a user. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target group or username of the target supergroup (in the format "@supergroupusername") * 'user_id' => '', // int - Required. Unique identifier of the target user. * 'is_anonymous' => '', // bool - (Optional). Pass True, if the administrator's presence in the chat is hidden * 'can_manage_chat ' => '', // bool - (Optional). Pass True, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege * 'can_change_info' => '', // bool - (Optional). Pass True, if the administrator can change chat title, photo and other settings * 'can_post_messages' => '', // bool - (Optional). Pass True, if the administrator can create channel posts, channels only * 'can_edit_messages' => '', // bool - (Optional). Pass True, if the administrator can edit messages of other users, channels only * 'can_delete_messages' => '', // bool - (Optional). Pass True, if the administrator can delete messages of other users * 'can_invite_users' => '', // bool - (Optional). Pass True, if the administrator can invite new users to the chat * 'can_manage_voice_chats'=> '', // bool - (Optional). Pass True, if the administrator can manage voice chats * 'can_restrict_members' => '', // bool - (Optional). Pass True, if the administrator can restrict, ban or unban chat members * 'can_pin_messages' => '', // bool - (Optional). Pass True, if the administrator can pin messages, supergroups only * 'can_promote_members' => '', // bool - (Optional). Pass True, if the administrator can add new administrators with a subset of his own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) * ] * * * @link https://core.telegram.org/bots/api#restrictchatmember * * @throws TelegramSDKException */ public function promoteChatMember(array $params): bool { return $this->post('promoteChatMember', $params)->getResult(); } /** * Use this method to set a custom title for an administrator in a supergroup promoted by the bot. * * Returns True on success. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target supergroup (in the format "@supergroupusername") * 'user_id' => '', // int - Required. Unique identifier of the target user * 'custom_title' => '', // string - Required. New custom title for the administrator; 0 - 16 characters, emoji are not allowed * ] * * * @link https://core.telegram.org/bots/api#setchatadministratorcustomtitle * * @throws TelegramSDKException */ public function setChatAdministratorCustomTitle(array $params): bool { return $this->post('setChatAdministratorCustomTitle', $params)->getResult(); } /** * Ban a channel chat in a supergroup or a channel. Until the chat is unbanned, the owner of the banned chat * won't be able to send messages on behalf of any of their channels. * * Returns True on success. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format @channelusername) * 'sender_chat_id' => '', // int - Required. Unique identifier of the target sender chat * ] * * * @link https://core.telegram.org/bots/api#banchatsenderchat * * @throws TelegramSDKException */ public function banChatSenderChat(array $params): bool { return $this->post('banChatSenderChat', $params)->getResult(); } /** * Unban a previously banned channel chat in a supergroup or channel. * * The bot must be an administrator for this to work * * Returns True on success. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format @channelusername) * 'sender_chat_id' => '', // int - Required. Unique identifier of the target sender chat * ] * * * @link https://core.telegram.org/bots/api#unbanchatsenderchat * * @throws TelegramSDKException */ public function unbanChatSenderChat(array $params): bool { return $this->post('unbanChatSenderChat', $params)->getResult(); } /** * Use this method to set default chat permissions for all members. * The bot must be an administrator in the group or a supergroup for this to work and * must have the can_restrict_members admin rights. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target group or username of the target supergroup (in the format "@supergroupusername") * 'permissions' => '', // ChatPermissions - Required. New default chat permissions * ] * * * @link https://core.telegram.org/bots/api#setchatpermissions * * @throws TelegramSDKException */ public function setChatPermissions(array $params): bool { return $this->post('setChatPermissions', $params)->getResult(); } /** * Get up to date information about the chat (current name of the user for one-on-one conversations, * current username of a user, group or channel, etc.). * * * $params = [ * 'chat_id' => '', // string|int - Unique identifier for the target chat or username of the target supergroup or channel (in the format "@channelusername") * ] * * * @link https://core.telegram.org/bots/api#getchat * * @throws TelegramSDKException */ public function getChat(array $params): ChatObject { $response = $this->get('getChat', $params); return new ChatObject($response->getDecodedBody()); } /** * Get a list of administrators in a chat. * * * $params = [ * 'chat_id' => '', // string|int - Unique identifier for the target chat or username of the target supergroup or channel (in the format "@channelusername"); * ] * * * @link https://core.telegram.org/bots/api#getchatadministrators * * @return ChatMember[] * * @throws TelegramSDKException */ public function getChatAdministrators(array $params): array { $response = $this->get('getChatAdministrators', $params); return collect($response->getResult()) ->mapInto(ChatMember::class) ->all(); } /** * Get the number of members in a chat. * * * $params = [ * 'chat_id' => '', // string|int - Unique identifier for the target chat or username of the target supergroup or channel (in the format "@channelusername"). * ] * * * @link https://core.telegram.org/bots/api#getchatmembercount * * @throws TelegramSDKException */ public function getChatMemberCount(array $params): int { return $this->get('getChatMemberCount', $params)->getResult(); } /** * Get information about a member of a chat. * * * $params = [ * 'chat_id' => '', // string|int - Unique identifier for the target chat or username of the target supergroup or channel (in the format "@channelusername"). * 'user_id' => '', // int - Unique identifier of the target user. * ] * * * @link https://core.telegram.org/bots/api#getchatmember * * @throws TelegramSDKException */ public function getChatMember(array $params): ChatMember { $response = $this->get('getChatMember', $params); return new ChatMember($response->getDecodedBody()); } /** * Set a new group sticker set for a supergroup. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target supergroup (in the format "@supergroupusername") * 'sticker_set_name' => '', // int - Required. Name of the sticker set to be set as the group sticker set * ] * * * @link https://core.telegram.org/bots/api#setchatstickerset * * @throws TelegramSDKException */ public function setChatStickerSet(array $params): bool { return $this->post('setChatStickerSet', $params)->getResult(); } /** * Delete a group sticker set from a supergroup. * * The bot must be an administrator in the group for this to work. * * * $params = [ * 'chat_id' => '', // string|int - Required. Unique identifier for the target chat or username of the target supergroup (in the format "@supergroupusername") * ] * * * @link https://core.telegram.org/bots/api#deletechatstickerset * * @throws TelegramSDKException */ public function deleteChatStickerSet(array $params): bool { return $this->post('deleteChatStickerSet', $params)->getResult(); } } telegram-bot-sdk/src/Methods/Passport.php000064400000001162152665541660014443 0ustar00 * $params = [ * 'user_id' => '', // int - Required. User identifier * 'errors' => '', // PassportElementError[] - Required. A JSON-serialized array describing the errors * ] * * * @link https://core.telegram.org/bots/api#setpassportdataerrors * * @return bool */ public function setPassportDataErrors(array $params) { return $this->post('setPassportDataErrors', $params)->getResult(); } } telegram-bot-sdk/src/Methods/EditMessage.php000064400000022037152665541660015026 0ustar00 * $params = [ * 'chat_id' => '', // int|string - (Optional). Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - (Optional). Required if inline_message_id is not specified. Identifier of the sent message * 'inline_message_id' => '', // string - (Optional). Required if chat_id and message_id are not specified. Identifier of the inline message * 'text' => '', // string - Required. New text of the message. * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. * 'entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'disable_web_page_preview' => '', // bool - (Optional). Disables link previews for links in this message * 'reply_markup' => '', // string - (Optional). A JSON-serialized object for an inline keyboard. * ] * * * @link https://core.telegram.org/bots/api#editmessagetext * * @return Message|bool * * @throws TelegramSDKException */ public function editMessageText(array $params): Message { $response = $this->post('editMessageText', $params); return new Message($response->getDecodedBody()); } /** * Edit captions of messages sent by the bot or via the bot (for inline bots). * * $params = [ * 'chat_id' => '', // int|string - (Optional). Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - (Optional). Required if inline_message_id is not specified. Identifier of the sent message * 'inline_message_id' => '', // string - (Optional). Required if chat_id and message_id are not specified. Identifier of the inline message * 'caption' => '', // string - (Optional). New caption of the message * 'parse_mode' => '', // string - (Optional). Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. * 'caption_entities' => '', // array - (Optional). List of special entities that appear in the caption, which can be specified instead of parse_mode * 'reply_markup' => '', // string - (Optional). A JSON-serialized object for an inline keyboard. * ] * * * @link https://core.telegram.org/bots/api#editmessagecaption * * @return Message|bool * * @throws TelegramSDKException */ public function editMessageCaption(array $params): Message { $response = $this->post('editMessageCaption', $params); return new Message($response->getDecodedBody()); } /** * Edit audio, document, photo, or video messages sent by the bot or via the bot. * * * $params = [ * 'chat_id' => '', // int|string - (Optional). Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - (Optional). Required if inline_message_id is not specified. Identifier of the sent message * 'inline_message_id' => '', // string - (Optional). Required if chat_id and message_id are not specified. Identifier of the inline message * 'media' => '', // InputMedia - Required. A JSON-serialized object for a new media content of the message * 'reply_markup' => '', // string - (Optional). A JSON-serialized object for an inline keyboard. * ] * * * @link https://core.telegram.org/bots/api#editmessagemedia * * @return Message|bool * * @throws TelegramSDKException */ public function editMessageMedia(array $params): Message { $response = $this->post('editMessageMedia', $params); return new Message($response->getDecodedBody()); } /** * Edit only the reply markup of messages sent by the bot or via the bot (for inline bots). * * * $params = [ * 'chat_id' => '', // int|string - (Optional). Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - (Optional). Required if inline_message_id is not specified. Identifier of the sent message * 'inline_message_id' => '', // string - (Optional). Required if chat_id and message_id are not specified. Identifier of the inline message * 'reply_markup' => '', // string - (Optional). A JSON-serialized object for an inline keyboard. * ] * * * @link https://core.telegram.org/bots/api#editmessagereplymarkup * * @return Message|bool * * @throws TelegramSDKException */ public function editMessageReplyMarkup(array $params): Message { $response = $this->post('editMessageReplyMarkup', $params); return new Message($response->getDecodedBody()); } /** * Stop Poll. * * Stop a poll which was sent by the bot. On success, the stopped Poll with the final results is returned. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - Required. Identifier of the original message with the poll * 'reply_markup' => '', // string - (Optional). A JSON-serialized object for an inline keyboard. * ] * * * @link https://core.telegram.org/bots/api#stoppoll * * @throws TelegramSDKException */ public function stopPoll(array $params): Poll { $response = $this->post('stopPoll', $params); return new Poll($response->getDecodedBody()); } /** * Delete a message, including service messages, with the following limitations:. * * - A message can only be deleted if it was sent less than 48 hours ago. * - Bots can delete outgoing messages in private chats, groups, and supergroups. * - Bots can delete incoming messages in private chats. * - Bots granted can_post_messages permissions can delete outgoing messages in channels. * - If the bot is an administrator of a group, it can delete any message there. * - If the bot has can_delete_messages permission in a supergroup or a channel, it can delete any message there. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - Required. Identifier of the message to delete. * ] * * * @link https://core.telegram.org/bots/api#deletemessage * * @return bool * * @throws TelegramSDKException */ public function deleteMessage(array $params) { return $this->post('deleteMessage', $params)->getResult(); } /** * Delete multiple messages simultaneously. If some of the specified messages can't be found, they are skipped. Returns True on success. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_ids' => [], // int[] - Required. List of 1-100 identifiers of messages to delete. @see self::deleteMessage() for limitations on which messages can be deleted * ] * * * @link https://core.telegram.org/bots/api#deletemessages * * @return bool * * @throws TelegramSDKException */ public function deleteMessages(array $params) { if (isset($params['message_ids'])) { $params['message_ids'] = json_encode($params['message_ids'], JSON_THROW_ON_ERROR); } return $this->post('deleteMessages', $params)->getResult(); } } telegram-bot-sdk/src/Methods/Get.php000064400000004264152665541660013355 0ustar00get('getMe'); return new User($response->getDecodedBody()); } /** * Returns a list of profile pictures for a user. * * * @link https://core.telegram.org/bots/api#getuserprofilephotos * * * $params = [ * 'user_id' => '', // int - Required. Unique identifier of the target user * 'offset' => '', // int - (Optional). Sequential number of the first photo to be returned. By default, all photos are returned. * 'limit' => '', // int - (Optional). Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100. * ] * * * @throws TelegramSDKException */ public function getUserProfilePhotos(array $params): UserProfilePhotos { $response = $this->get('getUserProfilePhotos', $params); return new UserProfilePhotos($response->getDecodedBody()); } /** * Returns basic info about a file and prepare it for downloading. * * * The file can then be downloaded via the link * https://api.telegram.org/file/bot/, * where is taken from the response. * * @link https://core.telegram.org/bots/api#getFile * * * $params = [ * 'file_id' => '', // string - Required. File identifier to get info about * ] * * * @throws TelegramSDKException */ public function getFile(array $params): File { $response = $this->get('getFile', $params); return new File($response->getDecodedBody()); } } telegram-bot-sdk/src/Methods/Query.php000064400000007163152665541660013744 0ustar00 * $params = [ * 'callback_query_id' => '', // string - Required. Unique identifier for the query to be answered * 'text' => '', // string - (Optional). Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters * 'show_alert' => '', // bool - (Optional). If true, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to false. * 'url' => '', // string - (Optional). URL that will be opened by the user's client. If you have created a Game and accepted the conditions via "@Botfather", specify the URL that opens your game – note that this will only work if the query comes from a callback_game button. Otherwise, you may use links like telegram.me/your_bot?start=XXXX that open your bot with a parameter. * 'cache_time' => '', // int - (Optional). The maximum amount of time in seconds that the result of the callback query may be cached client-side. Telegram apps will support caching starting in version 3.14. Defaults to 0. * ] * * * @link https://core.telegram.org/bots/api#answercallbackquery * * @throws TelegramSDKException */ public function answerCallbackQuery(array $params): bool { $this->post('answerCallbackQuery', $params); return true; } /** * Send answers to an inline query. * * No more than 50 results per query are allowed. * * * $params = [ * 'inline_query_id' => '', // string - Required. Unique identifier for the answered query * 'results' => '', // array - Required. A JSON-serialized array of results for the inline query * 'cache_time' => '', // int - (Optional). The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300. * 'is_personal' => '', // bool - (Optional). Pass True, if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query * 'next_offset' => '', // string - (Optional). Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don‘t support pagination. Offset length can’t exceed 64 bytes. * 'switch_pm_text' => '', // string - (Optional). If passed, clients will display a button with specified text that switches the user to a private chat with the bot and sends the bot a start message with the parameter switch_pm_parameter * 'switch_pm_parameter' => '', // string - (Optional). Deep-linking parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed. * ] * * * @link https://core.telegram.org/bots/api#answerinlinequery * * @throws TelegramSDKException */ public function answerInlineQuery(array $params): bool { $this->post('answerInlineQuery', $params); return true; } } telegram-bot-sdk/src/Methods/Commands.php000064400000006036152665541660014376 0ustar00 * $params = [ * 'commands' => '', // array - Required. A JSON-serialized list of bot commands to be set as the list of the bot's commands. At most 100 commands can be specified. * 'scope' => '', // BotCommandScope - (Optional). A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to BotCommandScopeDefault. * 'language_code' => '', // String - (Optional). A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands * ] * * * @link https://core.telegram.org/bots/api#setmycommands * * @param array $params Where "commands" key is required, where value is a serialized array of commands. * * @throws TelegramSDKException */ public function setMyCommands(array $params): bool { $params['commands'] = is_string($params['commands']) ? $params['commands'] : json_encode($params['commands'], JSON_THROW_ON_ERROR); return $this->post('setMyCommands', $params)->getResult(); } /** * Delete the list of the bot's commands for the given scope and user language * * * $params = [ * 'scope' => '', // BotCommandScope - (Optional). A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to BotCommandScopeDefault. * 'language_code' => '', // String - (Optional). A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands * ] * * * @link https://core.telegram.org/bots/api#deletemycommands * * @param mixed[] $params */ public function deleteMyCommands(array $params = []): bool { return $this->post('deleteMyCommands', $params)->getResult(); } /** * Get the current list of the bot's commands. * * * $params = [ * 'scope' => '', // BotCommandScope - (Optional). A JSON-serialized object, describing scope of users. Defaults to BotCommandScopeDefault. * 'language_code' => '', // String - (Optional). A two-letter ISO 639-1 language code or an empty string * ] * * * @link https://core.telegram.org/bots/api#getmycommands * * @return BotCommand[] * * @throws TelegramSDKException */ public function getMyCommands(array $params = []): array { return collect($this->get('getMyCommands', $params)->getResult()) ->mapInto(BotCommand::class) ->all(); } } telegram-bot-sdk/src/Methods/Update.php000064400000017612152665541660014061 0ustar00 * $params = [ * 'offset' => '', * 'limit' => '', * 'timeout' => '', * 'allowed_updates' => '', * ]; * * * @link https://core.telegram.org/bots/api#getupdates * * @param array $params [ * * @var int Optional. Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will forgotten. * @var int Optional. Limits the number of updates to be retrieved. Values between 1—100 are accepted. Defaults to 100. * @var int Optional. Timeout in seconds for long polling. Defaults to 0, i.e. usual short polling. Should be positive, short polling should be used for testing purposes only. * @var array Optional. List the types of updates you want your bot to receive. For example, specify [“message”, “edited_channel_post”, “callback_query”] to only receive updates of these types. See Update for a complete list of available update types. Specify an empty list to receive all updates regardless of type (default). If not specified, the previous setting will be used. * * ] * * @return UpdateObject[] * * @throws TelegramSDKException */ public function getUpdates(array $params = [], bool $shouldDispatchEvents = true): array { $response = $this->get('getUpdates', $params); return collect($response->getResult()) ->map(function ($data) use ($shouldDispatchEvents): UpdateObject { $update = new UpdateObject($data); if ($shouldDispatchEvents) { $this->dispatchUpdateEvent($update); } return $update; }) ->all(); } /** * Set a Webhook to receive incoming updates via an outgoing webhook. * * * $params = [ * 'url' => '', * 'certificate' => '', * 'max_connections' => '', * 'allowed_updates' => '', * ]; * * * @link https://core.telegram.org/bots/api#setwebhook * * @param array $params [ * * @var string Required. HTTPS url to send updates to. Use an empty string to remove webhook integration * @var InputFile Optional. Upload your public key certificate so that the root certificate in use can be checked. See our self-signed guide for details. * @var int Optional. Maximum allowed number of simultaneous HTTPS connections to the webhook for update delivery, 1-100. Defaults to 40. Use lower values to limit the load on your bot‘s server, and higher values to increase your bot’s throughput. * @var array Optional. List the types of updates you want your bot to receive. For example, specify [“message”, “edited_channel_post”, “callback_query”] to only receive updates of these types. See Update for a complete list of available update types. Specify an empty list to receive all updates regardless of type (default). If not specified, the previous setting will be used. * * ] * * @throws TelegramSDKException */ public function setWebhook(array $params): bool { $this->validateHookUrl($params['url']); if (isset($params['allowed_updates'])) { $params['allowed_updates'] = json_encode($params['allowed_updates'], JSON_THROW_ON_ERROR); } if (isset($params['certificate'])) { $params['certificate'] = $this->formatCertificate($params['certificate']); return $this->uploadFile('setWebhook', $params, 'certificate')->getResult(); } return $this->post('setWebhook', $params)->getResult(); } /** * Remove webhook integration if you decide to switch back to getUpdates. * * @link https://core.telegram.org/bots/api#deletewebhook * * @throws TelegramSDKException */ public function deleteWebhook(): bool { return $this->get('deleteWebhook')->getResult(); } /** * Get current webhook status. * * @link https://core.telegram.org/bots/api#getwebhookinfo * * @throws TelegramSDKException */ public function getWebhookInfo(): WebhookInfo { $response = $this->get('getWebhookInfo'); return new WebhookInfo($response->getDecodedBody()); } /** * Alias for getWebhookUpdate. * * @deprecated Call method getWebhookUpdate (note lack of letter s at end) * To be removed in next major version. */ public function getWebhookUpdates(bool $shouldDispatchEvents = true): UpdateObject { return $this->getWebhookUpdate($shouldDispatchEvents); } /** * Returns a webhook update sent by Telegram. * Works only if you set a webhook. * * @see setWebhook */ public function getWebhookUpdate(bool $shouldDispatchEvents = true, ?RequestInterface $request = null): UpdateObject { $body = $this->getRequestBody($request); $update = new UpdateObject($body); if ($shouldDispatchEvents) { $this->dispatchUpdateEvent($update); } return $update; } /** * Alias for deleteWebhook. * * * @throws TelegramSDKException */ public function removeWebhook(): bool { return $this->deleteWebhook(); } /** * @throws TelegramSDKException */ private function validateHookUrl(string $url): void { if (filter_var($url, FILTER_VALIDATE_URL) === false) { throw new TelegramSDKException('Invalid URL Provided'); } if (parse_url($url, PHP_URL_SCHEME) !== 'https') { throw new TelegramSDKException('Invalid URL, should be a HTTPS url.'); } } private function formatCertificate($certificate): InputFile { if ($certificate instanceof InputFile) { return $certificate; } return InputFile::create($certificate, 'certificate.pem'); } private function getRequestBody(?RequestInterface $request): mixed { $rawBody = $request instanceof RequestInterface ? (string) $request->getBody() : file_get_contents('php://input'); return json_decode($rawBody, true); } /** Dispatch Update Event. */ protected function dispatchUpdateEvent(UpdateObject $update): void { if (! $this->hasEventDispatcher()) { return; } $dispatcher = $this->eventDispatcher(); $dispatcher->dispatch(new UpdateWasReceived($this, $update)); $dispatcher->dispatch(new UpdateEvent($this, $update)); $updateType = $update->objectType(); if (is_string($updateType)) { $dispatcher->dispatch(new UpdateEvent($this, $update, $updateType)); if (method_exists($update->getMessage(), 'objectType')) { $messageType = $update->getMessage()->objectType(); if ($messageType !== null) { $dispatcher->dispatch(new UpdateEvent($this, $update, sprintf('%s.%s', $updateType, $messageType))); } } } } } telegram-bot-sdk/src/Methods/Payments.php000064400000017721152665541660014440 0ustar00 * $params = [ * 'chat_id' => '', // int - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'title' => '', // string - Required. Product name, 1-32 characters * 'description' => '', // string - Required. Product description, 1-255 characters * 'payload' => '', // string - Required. Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes. * 'provider_token' => '', // string - Required. Payments provider token, obtained via Botfather * 'currency' => '', // string - Required. Three-letter ISO 4217 currency code * 'prices' => '', // LabeledPrice[] - Required. Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.) * 'max_tip_amount' => '', // int - (Optional). The maximum accepted amount for tips in the smallest units of the currency (integer, not float/double). For example, for a maximum tip of US$ 1.45 pass max_tip_amount = 145. See the exp parameter in currencies.json, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). Defaults to 0 * 'suggested_tip_amounts' => '', // int[] - (Optional). A JSON-serialized array of suggested amounts of tips in the smallest units of the currency (integer, not float/double). At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount. * 'start_parameter' => '', // string - (Optional). Unique deep-linking parameter. If left empty, forwarded copies of the sent message will have a Pay button, allowing multiple users to pay directly from the forwarded message, using the same invoice. If non-empty, forwarded copies of the sent message will have a URL button with a deep link to the bot (instead of a Pay button), with the value used as the start parameter * 'provider_data' => '', // string - (Optional). JSON-encoded data about the invoice, which will be shared with the payment provider. A detailed description of required fields should be provided by the payment provider. * 'photo_url' => '', // string - (Optional). URL of the product photo for the invoice. Can be a photo of the goods or a marketing image for a service. People like it better when they see what they are paying for. * 'photo_size' => '', // int - (Optional). Photo size * 'photo_width' => '', // int - (Optional). Photo width * 'photo_height' => '', // int - (Optional). Photo height * 'need_name' => '', // bool - (Optional). Pass True, if you require the user's full name to complete the order * 'need_phone_number' => '', // bool - (Optional). Pass True, if you require the user's phone number to complete the order * 'need_email' => '', // bool - (Optional). Pass True, if you require the user's email to complete the order * 'need_shipping_address' => '', // bool - (Optional). Pass True, if you require the user's shipping address to complete the order * 'send_phone_number_to_provider' => '', // bool - (Optional). Pass True, if user's phone number should be sent to provider * 'send_email_to_provider' => '', // bool - (Optional). Pass True, if user's email address should be sent to provider * 'is_flexible' => '', // bool - (Optional). Pass True, if the final price depends on the shipping method * 'disable_notification' => '', // bool - (Optional). Sends the message silently. Users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply => '', // boo - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button. * ] * * * @link https://core.telegram.org/bots/api#sendinvoice * * @throws TelegramSDKException */ public function sendInvoice(array $params): Message { $params['prices'] = json_encode(Arr::wrap($params['prices']), JSON_THROW_ON_ERROR); $response = $this->post('sendInvoice', $params); return new Message($response->getDecodedBody()); } /** * Reply to shipping queries. * * * $params = [ * 'shippingQueryId' => '', // string - Required. Unique identifier for the query to be answered * 'ok' => '', // bool - Required. Specify True if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible) * 'shippingOptions' => '', // ShippingOption[] - (Optional|Required). Required if ok is True. A JSON-serialized array of available shipping options. * 'errorMessage' => '', // string - (Optional|Required). Required if ok is False. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user. * ] * * * @link https://core.telegram.org/bots/api#answershippingquery * * @throws TelegramSDKException */ public function answerShippingQuery(array $params): bool { return $this->post('answerShippingQuery', $params)->getResult(); } /** * Reply to pre-checkout queries. * * * $params = [ * 'preCheckoutQueryId' => '', // string - Required. Unique identifier for the query to be answered * 'ok' => '', // bool - Required. Specify True if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order. Use False if there are any problems. * 'errorMessage' => '', // string - (Optional|Required). Required if ok is False. Error message in human readable form that explains the reason for failure to proceed with the checkout (e.g. "Sorry, somebody just bought the last of our amazing black T-shirts while you were busy filling out your payment details. Please choose a different color or garment!"). Telegram will display this message to the user. * ] * * * @link https://core.telegram.org/bots/api#answerprecheckoutquery * * @throws TelegramSDKException */ public function answerPreCheckoutQuery(array $params): bool { return $this->post('answerPreCheckoutQuery', $params)->getResult(); } } telegram-bot-sdk/src/Methods/Forum.php000064400000010554152665541660013725 0ustar00 * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target supergroup (in the format "@supergroupusername") * 'name' => '', // string - Required. Topic name, 1-128 characters * 'icon_color' => '', // int - (Optional). Color of the topic icon in RGB format. Currently, must be one of 7322096 (0x6FB9F0), 16766590 (0xFFD67E), 13338331 (0xCB86DB), 9367192 (0x8EEE98), 16749490 (0xFF93B2), or 16478047 (0xFB6F5F) * 'icon_custom_emoji_id' => '', // string - (Optional). Unique identifier of the custom emoji shown as the topic icon. Use getForumTopicIconStickers to get all allowed custom emoji identifiers. * ] * * * @link https://core.telegram.org/bots/api#createforumtopic * * @throws TelegramSDKException */ public function createForumTopic(array $params): ForumTopicObject { $response = $this->post('createForumTopic', $params); return new ForumTopicObject($response->getDecodedBody()); } /** * Edit forum topics. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target supergroup (in the format "@supergroupusername") * 'message_thread_id' => '', // int - Required. Unique identifier for the target message thread of the forum topic * 'name' => '', // string - (Optional). Topic name, 1-128 characters * 'icon_custom_emoji_id' => '', // string - (Optional). Unique identifier of the custom emoji shown as the topic icon. Use getForumTopicIconStickers to get all allowed custom emoji identifiers. * ] * * * @link https://core.telegram.org/bots/api#editforumtopic * * @throws TelegramSDKException */ public function editForumTopic(array $params): bool { return $this->post('editForumTopic', $params)->getResult(); } /** * Close forum topics. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target supergroup (in the format "@supergroupusername") * 'message_thread_id' => '', // int - Required. Unique identifier for the target message thread of the forum topic * ] * * * @link https://core.telegram.org/bots/api#closeforumtopic * * @throws TelegramSDKException */ public function closeForumTopic(array $params): bool { return $this->post('closeForumTopic', $params)->getResult(); } /** * Reopen forum topics. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target supergroup (in the format "@supergroupusername") * 'message_thread_id' => '', // int - Required. Unique identifier for the target message thread of the forum topic * ] * * * @link https://core.telegram.org/bots/api#reopenforumtopic * * @throws TelegramSDKException */ public function reopenForumTopic(array $params): bool { return $this->post('reopenForumTopic', $params)->getResult(); } /** * Delete forum topics. * * * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target supergroup (in the format "@supergroupusername") * 'message_thread_id' => '', // int - Required. Unique identifier for the target message thread of the forum topic * ] * * * @link https://core.telegram.org/bots/api#deleteforumtopic * * @throws TelegramSDKException */ public function deleteForumTopic(array $params): bool { return $this->post('deleteForumTopic', $params)->getResult(); } } telegram-bot-sdk/src/Methods/Location.php000064400000013422152665541660014402 0ustar00 * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'latitude' => '', // float - Required. Latitude of location * 'longitude' => '', // float - Required. Longitude of location * 'horizontal_accuracy => '', // float - (Optional). The radius of uncertainty for the location, measured in meters; 0-1500 * 'live_period' => '', // int - (Optional). Period in seconds for which the location will be updated (see Live Locations, should be between 60 and 86400. * 'heading' => '', // int - (Optional). For live locations, a direction in which the user is moving, in degrees. Must be between 1 and 360 if specified. * 'proximity_alert_radius' => '', // int - (Optional). For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified. * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply' => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendlocation * * @throws TelegramSDKException */ public function sendLocation(array $params): MessageObject { $response = $this->post('sendLocation', $params); return new MessageObject($response->getDecodedBody()); } /** * Edit live location messages sent by the bot or via the bot. * * * $params = [ * 'chat_id' => '', // int|string - (Optional|Required). Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - (Optional|Required). Required if inline_message_id is not specified. Identifier of the sent message * 'inline_message_id' => '', // string - (Optional|Required). Required if chat_id and message_id are not specified. Identifier of the inline message * 'latitude' => '', // float - Required. Latitude of location * 'longitude' => '', // float - Required. Longitude of location * 'horizontal_accuracy => '', // float - (Optional). The radius of uncertainty for the location, measured in meters; 0-1500 * 'heading' => '', // int - (Optional). For live locations, a direction in which the user is moving, in degrees. Must be between 1 and 360 if specified. * 'proximity_alert_radius' => '', // int - (Optional). For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified. * 'reply_markup' => '', // string - (Optional). A JSON-serialized object for a new inline keyboard. * ] * * * @link https://core.telegram.org/bots/api#editmessagelivelocation * * @return MessageObject|bool * * @throws TelegramSDKException */ public function editMessageLiveLocation(array $params): MessageObject { $response = $this->post('editMessageLiveLocation', $params); return new MessageObject($response->getDecodedBody()); } /** * Stop updating a live location message sent by the bot or via the bot. * * * $params = [ * 'chat_id' => '', // int|string - (Optional|Required). Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'message_id' => '', // int - (Optional|Required). Required if inline_message_id is not specified. Identifier of the sent message * 'inline_message_id' => '', // string - (Optional|Required). Required if chat_id and message_id are not specified. Identifier of the inline message * 'reply_markup' => '', // string - (Optional). A JSON-serialized object for a new inline keyboard. * ] * * * @link https://core.telegram.org/bots/api#stopmessagelivelocation * * @return MessageObject|bool * * @throws TelegramSDKException */ public function stopMessageLiveLocation(array $params): MessageObject { $response = $this->post('stopMessageLiveLocation', $params); return new MessageObject($response->getDecodedBody()); } } telegram-bot-sdk/src/Methods/Stickers.php000064400000024001152665541660014414 0ustar00 * $params = [ * 'chat_id' => '', // int|string - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'sticker' => InputFile::file($file), // InputFile|string - Required. Sticker to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a .webp file from the Internet, or upload a new one using multipart/form-data. * 'disable_notification' => '', // bool - (Optional). Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound. * 'protect_content' => '', // bool - (Optional). Protects the contents of the sent message from forwarding and saving * 'reply_to_message_id' => '', // int - (Optional). If the message is a reply, ID of the original message * 'allow_sending_without_reply => '', // bool - (Optional). Pass True, if the message should be sent even if the specified replied-to message is not found * 'reply_markup' => '', // string - (Optional). Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. * ] * * * @link https://core.telegram.org/bots/api#sendsticker * * @throws TelegramSDKException */ public function sendSticker(array $params): MessageObject { $response = $this->uploadFile('sendSticker', $params, 'sticker'); return new MessageObject($response->getDecodedBody()); } /** * Get a sticker set. On success, a StickerSet object is returned. * * * $params = [ * 'name' => '', // string - Required. Name of the sticker set * ] * * * @link https://core.telegram.org/bots/api#getstickerset * * @throws TelegramSDKException */ public function getStickerSet(array $params): StickerSet { $response = $this->post('getStickerSet', $params); return new StickerSet($response->getDecodedBody()); } /** * Upload a .png file with a sticker for later use in createNewStickerSet and addStickerToSet * methods (can be used multiple times). * * * $params = [ * 'user_id' => '', // int - Required. Unique identifier for the target chat or username of the target channel (in the format "@channelusername") * 'png_sticker' => InputFile::file($file), // InputFile - Required. Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. * ] * * * @link https://core.telegram.org/bots/api#uploadstickerfile * * @throws TelegramSDKException */ public function uploadStickerFile(array $params): File { $response = $this->uploadFile('uploadStickerFile', $params, 'png_sticker'); return new File($response->getDecodedBody()); } /** * Create new sticker set owned by a user. * * * $params = [ * 'user_id' => '', // int - Required. User identifier of created sticker set owner * 'name' => '', // string - Required. Short name of sticker set, to be used in t.me/addstickers/ URLs (e.g., animals). Can contain only english letters, digits and underscores. Must begin with a letter, can't contain consecutive underscores and must end in “_by_”. is case insensitive. 1-64 characters. * 'title' => '', // string - Required. Sticker set title, 1-64 characters * 'png_sticker' => InputFile::file($file), // InputFile|string - (Optional). Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. * 'tgs_sticker' => InputFile::file($file), // InputFile - (Optional). TGS animation with the sticker, uploaded using multipart/form-data. See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements * 'emojis' => '', // string - Required. One or more emoji corresponding to the sticker * 'contains_masks' => '', // bool - (Optional). Pass True, if a set of mask stickers should be created * 'mask_position' => MaskPosition::make($fields), // MaskPosition - (Optional). A JSON-serialized object for position where the mask should be placed on faces * ] * * * @link https://core.telegram.org/bots/api#createnewstickerset * * @throws TelegramSDKException */ public function createNewStickerSet(array $params): bool { return $this->uploadFile('createNewStickerSet', $params, 'png_sticker')->getResult(); } /** * Add a new sticker to a set created by the bot. * * * $params = [ * 'user_id' => '', // int - Required. User identifier of sticker set owner * 'name' => '', // string - Required. Sticker set name * 'png_sticker' => InputFile::file($file), // InputFile|string - Required. Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. * 'tgs_sticker' => InputFile::file($file), // InputFile - (Optional). TGS animation with the sticker, uploaded using multipart/form-data. See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements * 'emojis' => '', // string - Required. One or more emoji corresponding to the sticker * 'mask_position' => MaskPosition::make($fields), // MaskPosition - (Optional). A JSON-serialized object for position where the mask should be placed on faces * ] * * * @link https://core.telegram.org/bots/api#addstickertoset * * @throws TelegramSDKException */ public function addStickerToSet(array $params): bool { return $this->uploadFile('addStickerToSet', $params, 'png_sticker')->getResult(); } /** * Move a sticker in a set created by the bot to a specific position. * * * $params = [ * 'sticker' => '', // string - Required. File identifier of the sticker * 'position' => '', // string - Required. New sticker position in the set, zero-based. * ] * * * @link https://core.telegram.org/bots/api#setstickerpositioninset * * @throws TelegramSDKException */ public function setStickerPositionInSet(array $params): bool { return $this->post('setStickerPositionInSet', $params)->getResult(); } /** * Delete a sticker from a set created by the bot. * * * $params = [ * 'sticker' => '', // string - Required. File identifier of the sticker * ] * * * @link https://core.telegram.org/bots/api#deletestickerfromset * * @throws TelegramSDKException */ public function deleteStickerFromSet(array $params): bool { return $this->post('deleteStickerFromSet', $params)->getResult(); } /** * Set the thumbnail of a sticker set * * * $params = [ * 'name' => '', // string - Required. Sticker set name * 'user_id' => '', // int - Required. User identifier of sticker set owner * 'thumb' => InputFile::file($file), // InputFile|string - (Optional). A PNG image with the thumbnail, must be up to 128 kilobytes in size and have width and height exactly 100px, or a TGS animation with the thumbnail up to 32 kilobytes in size; see https://core.telegram.org/animated_stickers#technical-requirements for animated sticker technical requirements. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. More info on Sending Files ». Animated sticker set thumbnail can't be uploaded via HTTP URL * ] * * @link https://core.telegram.org/bots/api#setstickersetthumb * * * @throws TelegramSDKException */ public function setStickerSetThumb(array $params): bool { return $this->uploadFile('setStickerSetThumb', $params, 'thumb')->getResult(); } } telegram-bot-sdk/src/BotsManager.php000064400000013756152665541660013443 0ustar00 The active bot instances. */ private array $bots = []; /** * TelegramManager constructor. */ public function __construct(private array $config) {} /** * Set the IoC Container. * * @param ContainerInterface $container Container instance */ public function setContainer(ContainerInterface $container): self { $this->container = $container; return $this; } /** * Get the configuration for a bot. * * * @throws TelegramBotNotFoundException */ public function getBotConfig(?string $name = null): array { $name ??= $this->getDefaultBotName(); $bots = collect($this->getConfig('bots')); $config = $bots->get($name); if (! $config) { throw TelegramBotNotFoundException::create($name); } return $config + ['bot' => $name]; } /** * Get a bot instance. * * * @throws TelegramSDKException */ public function bot(?string $name = null): Api { $name ??= $this->getDefaultBotName(); if (! isset($this->bots[$name])) { $this->bots[$name] = $this->makeBot($name); } return $this->bots[$name]; } /** * Reconnect to the given bot. * * * @throws TelegramSDKException */ public function reconnect(?string $name = null): Api { $name ??= $this->getDefaultBotName(); $this->disconnect($name); return $this->bot($name); } /** * Disconnect from the given bot. */ public function disconnect(?string $name = null): self { $name ??= $this->getDefaultBotName(); unset($this->bots[$name]); return $this; } /** * Determine if given bot name exists. */ public function hasBot(string $name): bool { return isset($this->bots[$name]); } /** * Get the specified configuration value for Telegram. */ public function getConfig(string $key, mixed $default = null): mixed { return data_get($this->config, $key, $default); } /** * Get the default bot name. */ public function getDefaultBotName(): ?string { return $this->getConfig('default'); } /** * Set the default bot name. */ public function setDefaultBot(string $name): self { Arr::set($this->config, 'default', $name); return $this; } /** * Return all the created bots. * * @return array */ public function getBots(): array { return $this->bots; } /** * Make the bot instance. * * * @throws TelegramSDKException */ protected function makeBot(string $name): Api { $config = $this->getBotConfig($name); $token = data_get($config, 'token'); $telegram = new Api( $token, $this->getConfig('async_requests', false), $this->getConfig('http_client_handler', null), $this->getConfig('base_bot_url', null) ); // Check if DI needs to be enabled for Commands if ($this->container instanceof ContainerInterface && $this->getConfig('resolve_command_dependencies', false)) { $telegram::setContainer($this->container); } $commands = data_get($config, 'commands', []); $commands = $this->parseBotCommands($commands); // Register Commands $telegram->addCommands($commands); return $telegram; } /** * @param list<(string | class-string)> $commands A list of command names or FQCNs of CommandInterface instances. * @return array An array of commands which includes global and bot specific commands. * * @deprecated Will be removed in SDK v4 * * @internal * Builds the list of commands for the given commands array. */ public function parseBotCommands(array $commands): array { $globalCommands = $this->getConfig('commands', []); $parsedCommands = $this->parseCommands($commands); return collect($globalCommands) ->merge($parsedCommands) ->unique() ->values() ->all(); } /** * Parse an array of commands and build a list. * * @param list<(string | class-string)> $commands */ private function parseCommands(array $commands): array { $commandGroups = collect($this->getConfig('command_groups')); $sharedCommands = collect($this->getConfig('shared_commands')); return collect($commands)->map(function ($command) use ($commandGroups, $sharedCommands): mixed { // If the command is a group, we'll parse through the group of commands // and resolve the full class name. if ($commandGroups->has($command)) { return $this->parseCommands($commandGroups->get($command)); } // If this command is actually a shared command, we'll extract the full // class name out of the command list now. if ($sharedCommands->has($command)) { return $sharedCommands->get($command); } return $command; }) ->flatten() ->unique() ->values() ->all(); } /** * Magically pass methods to the default bot. * * @return mixed * * @throws TelegramSDKException */ public function __call(string $method, array $parameters) { return $this->bot()->$method(...$parameters); } } telegram-bot-sdk/src/Traits/Http.php000064400000023454152665541660013422 0ustar00isAsyncRequest = $isAsyncRequest; return $this; } public function setHttpClientHandler(HttpClientInterface $httpClientHandler): self { $this->httpClientHandler = $httpClientHandler; return $this; } public function setBaseBotUrl(string $baseBotUrl): self { $baseBotUrl = str_replace('/bot', '', $baseBotUrl); $this->baseBotUrl = rtrim($baseBotUrl, '/'); return $this; } /** * Returns the last response returned from API request. */ public function getLastResponse(): ?TelegramResponse { return $this->lastResponse; } /** * Download a file from Telegram server by file ID. * * @param File|BaseObject|string $file Telegram File Instance / File Response Object or File ID. * @param string $filename Absolute path to dir or filename to save as. * * @throws TelegramSDKException */ public function downloadFile(File|BaseObject|string $file, string $filename): string { $originalFilename = null; if (! $file instanceof File) { if ($file instanceof BaseObject) { $originalFilename = $file->get('file_name'); // Try to get file_id from the object or default to the original param. $file = $file->get('file_id', $file); } if (! is_string($file)) { throw new InvalidArgumentException( 'Invalid $file param provided. Please provide one of file_id, File or Response object containing file_id' ); } $file = $this->getFile(['file_id' => $file]); } // No filename provided. if (pathinfo($filename, PATHINFO_EXTENSION) === '') { // Attempt to use the original file name if there is one or fallback to the file_path filename. $filename .= DIRECTORY_SEPARATOR.($originalFilename ?: basename($file->file_path)); } $telegramRequest = $this->resolveTelegramRequest('GET', ''); return $this->getClient()->download($file->file_path, $filename, $telegramRequest); } /** * Sends a GET request to Telegram Bot API and returns the result. * * @throws TelegramSDKException */ protected function get(string $endpoint, array $params = []): TelegramResponse { $params = $this->replyMarkupToString($params); return $this->sendRequest('GET', $endpoint, $params); } /** * Converts a reply_markup field in the $params to a string. */ protected function replyMarkupToString(array $params): array { if (isset($params['reply_markup'])) { $params['reply_markup'] = (string) $params['reply_markup']; } return $params; } /** * Sends a request to Telegram Bot API and returns the result. * * @throws TelegramSDKException */ protected function sendRequest(string $method, string $endpoint, array $params = []): TelegramResponse { $telegramRequest = $this->resolveTelegramRequest($method, $endpoint, $params); return $this->lastResponse = $this->getClient()->sendRequest($telegramRequest); } /** * Instantiates a new TelegramRequest entity. */ protected function resolveTelegramRequest(string $method, string $endpoint, array $params = []): TelegramRequest { return (new TelegramRequest( $this->getAccessToken(), $method, $endpoint, $params, $this->isAsyncRequest() )) ->setTimeOut($this->getTimeOut()) ->setConnectTimeOut($this->getConnectTimeOut()); } /** * Returns Telegram Bot API Access Token. */ public function getAccessToken(): string { return $this->accessToken; } /** * Sets the bot access token to use with API requests. * * @param string $accessToken The bot access token to save. */ public function setAccessToken(string $accessToken): self { $this->accessToken = $accessToken; return $this; } /** * Check if this is an asynchronous request (non-blocking). */ public function isAsyncRequest(): bool { return $this->isAsyncRequest; } public function getTimeOut(): int { return $this->timeOut; } public function setTimeOut(int $timeOut): self { $this->timeOut = $timeOut; return $this; } public function getConnectTimeOut(): int { return $this->connectTimeOut; } public function setConnectTimeOut(int $connectTimeOut): self { $this->connectTimeOut = $connectTimeOut; return $this; } /** * Returns the TelegramClient service. */ public function getClient(): TelegramClient { if ($this->client === null) { $this->client = new TelegramClient($this->httpClientHandler, $this->baseBotUrl); } return $this->client; } /** * Sends a multipart/form-data request to Telegram Bot API and returns the result. * Used primarily for file uploads. * * * @throws CouldNotUploadInputFile * @throws TelegramSDKException */ protected function uploadFile(string $endpoint, array $params, string $inputFileField): TelegramResponse { // Check if the field in the $params array (that is being used to send the relative file), is a file id. if (! isset($params[$inputFileField])) { throw CouldNotUploadInputFile::missingParam($inputFileField); } if ($this->hasFileId($inputFileField, $params)) { return $this->post($endpoint, $params); } // Sending an actual file requires it to be sent using multipart/form-data return $this->post($endpoint, $this->prepareMultipartParams($params, $inputFileField), true); } /** * Sends a POST request to Telegram Bot API and returns the result. * * @param bool $fileUpload Set true if a file is being uploaded. * * @throws TelegramSDKException */ public function post(string $endpoint, array $params = [], bool $fileUpload = false): TelegramResponse { $params = $this->normalizeParams($params, $fileUpload); return $this->sendRequest('POST', $endpoint, $params); } private function normalizeParams(array $params, $fileUpload): array { if ($fileUpload) { return ['multipart' => $params]; } return ['form_params' => $this->replyMarkupToString($params)]; } /** * Prepare Multipart Params for File Upload. * * * @throws CouldNotUploadInputFile */ protected function prepareMultipartParams(array $params, string $inputFileField): array { $this->validateInputFileField($params, $inputFileField); // Iterate through all param options and convert to multipart/form-data. return collect($params) ->reject(static fn ($value): bool => $value === null) ->map(fn ($contents, $name) => $this->generateMultipartData($contents, $name)) ->values() ->all(); } /** * @throws CouldNotUploadInputFile */ protected function validateInputFileField(array $params, $inputFileField): void { if (! isset($params[$inputFileField])) { throw CouldNotUploadInputFile::missingParam($inputFileField); } // All file-paths, urls, or file resources should be provided by using the InputFile object if ($params[$inputFileField] instanceof InputFile) { return; } if (! (is_string($params[$inputFileField]) && ! $this->is_json($params[$inputFileField]))) { return; } throw CouldNotUploadInputFile::inputFileParameterShouldBeInputFileEntity($inputFileField); } /** * Generates the multipart data required when sending files to telegram. */ protected function generateMultipartData(mixed $contents, string $name): array { if (! $this->isInputFile($contents)) { return ['name' => $name, 'contents' => $contents]; } $filename = $contents->getFilename(); $contents = $contents->getContents(); return ['name' => $name, 'contents' => $contents, 'filename' => $filename]; } } telegram-bot-sdk/src/Traits/Validator.php000064400000002615152665541660014424 0ustar00isFileId($params[$inputFileField]); } /** * Determine if given contents are an instance of InputFile. */ protected function isInputFile($contents): bool { return $contents instanceof InputFile; } /** * Determine the given string is a file id. * * @param string|InputFile|resource $value */ protected function isFileId(mixed $value): bool { if (! is_string($value)) { return false; } return preg_match('#^[\w\-]{20,}+$#u', trim($value)) > 0; } /** * Determine given string is a URL. * * @param string $value A filename or URL to a sticker */ protected function isUrl(string $value): bool { return (bool) filter_var($value, FILTER_VALIDATE_URL); } /** * Determine given string is a json object. * * @param string $string A json string */ protected function is_json(string $string): bool { json_decode($string, false); return json_last_error() === JSON_ERROR_NONE; } } telegram-bot-sdk/src/Traits/Telegram.php000064400000001003152665541660014225 0ustar00telegram; } /** * Set Telegram Api Instance. */ public function setTelegram(Api $telegram): self { $this->telegram = $telegram; return $this; } } telegram-bot-sdk/src/Traits/Singleton.php000064400000002413152665541660014435 0ustar00commandBus; } public function setCommandBus(CommandBus $commandBus): static { $this->commandBus = $commandBus; return $this; } /** * Processes Inbound Commands. * * @return Update|Update[] */ public function commandsHandler(bool $webhook = false, ?RequestInterface $request = null): Update|array { return $webhook ? $this->useWebHook($request) : $this->useGetUpdates(); } /** * Process the update object for a command from your webhook. */ protected function useWebHook(?RequestInterface $request = null): Update { $update = $this->getWebhookUpdate(true, $request); $this->processCommand($update); return $update; } /** * Process the update object for a command using the getUpdates method. * * @return Update[] * * @throws TelegramSDKException */ protected function useGetUpdates(): array { $updates = $this->getUpdates(); $highestId = -1; foreach ($updates as $update) { $highestId = $update->updateId; $this->processCommand($update); } // An update is considered confirmed as soon as getUpdates is called with an offset higher than it's update_id. if ($highestId !== -1) { $this->markUpdateAsRead($highestId); } return $updates; } /** * Mark updates as read. * * @return Update[] */ protected function markUpdateAsRead($highestId): array { $params = []; $params['offset'] = $highestId + 1; $params['limit'] = 1; return $this->getUpdates($params, false); } /** * Check update object for a command and process. */ public function processCommand(Update $update): void { $this->commandBus->handler($update); } /** * @param string $name Command Name * @param Update $update Update Object * * @deprecated This method will be protected and signature will be changed in SDK v4. * Helper to Trigger Commands. */ public function triggerCommand(string $name, Update $update, ?array $entity = null): mixed { $entity ??= ['offset' => 0, 'length' => strlen($name) + 1, 'type' => 'bot_command']; return $this->commandBus->execute( $name, $update, $entity ); } } telegram-bot-sdk/src/Api.php000064400000007260152665541660011743 0ustar00setAccessToken($token ?? getenv(self::BOT_TOKEN_ENV_NAME)); $this->validateAccessToken(); if ($async) { $this->setAsyncRequest($async); } $this->httpClientHandler = $httpClientHandler; $this->baseBotUrl = $baseBotUrl; $this->commandBus = new CommandBus($this); } /** * @throws TelegramSDKException */ private function validateAccessToken(): void { if ($this->getAccessToken() === '' || $this->getAccessToken() === '0') { throw TelegramSDKException::tokenNotProvided(self::BOT_TOKEN_ENV_NAME); } } /** * @deprecated This method will be removed in SDK v4. * Invoke Bots Manager. */ public static function manager(array $config): BotsManager { return new BotsManager($config); } /** * Magic method to process any dynamic method calls. * * @return mixed */ public function __call($method, $parameters) { if (self::hasMacro($method)) { return $this->macroCall($method, $parameters); } if (method_exists($this, $method)) { return $this->$method(...$parameters); } // If the method does not exist on the API, try the commandBus. if (preg_match('#^\w+Commands?#', $method, $matches)) { return $this->getCommandBus()->{$matches[0]}(...$parameters); } throw new BadMethodCallException(sprintf('Method [%s] does not exist.', $method)); } } telegram-bot-sdk/src/Commands/HelpCommand.php000064400000001442152665541660015156 0ustar00telegram->getCommandBus()->getCommands(); $text = ''; foreach ($commands as $name => $handler) { $text .= sprintf('/%s - %s'.PHP_EOL, $name, $handler->getDescription()); } $this->replyWithMessage(['text' => $text]); } } telegram-bot-sdk/src/Commands/CommandBus.php000064400000015531152665541660015023 0ustar00 Holds all commands. Keys are command names (without leading slashes). */ private array $commands = []; /** * @var array Holds all commands' aliases. Keys are command names (without leading slashes). */ private array $commandAliases = []; /** * Instantiate Command Bus. */ public function __construct(?Api $telegram = null) { $this->telegram = $telegram; } /** * Returns the list of commands. * * @return array */ public function getCommands(): array { return $this->commands; } /** * Add a list of commands. * * @param iterable> $commands * * @throws TelegramSDKException */ public function addCommands(iterable $commands): self { foreach ($commands as $command) { $this->addCommand($command); } return $this; } /** * Add a command to the commands list. * * @param CommandInterface|class-string $command Either an object or fully qualified class name (FQCN) of the command class. * * @throws TelegramSDKException */ public function addCommand(CommandInterface|string $command): self { $command = $this->resolveCommand($command); /* * At this stage we definitely have a proper command to use. * * @var Command $command */ $this->commands[$command->getName()] = $command; foreach ($command->getAliases() as $alias) { $this->checkForConflicts($command, $alias); $this->commandAliases[$alias] = $command; } return $this; } /** * Remove a command from the list. * * @param string $name Command's name without leading slash */ public function removeCommand(string $name): self { unset($this->commands[$name]); return $this; } /** * Removes a list of commands. * * @param list $names Command names */ public function removeCommands(array $names): self { foreach ($names as $name) { $this->removeCommand($name); } return $this; } /** * Parse a Command for a Match. * * @param string $text Command name with a leading slash * @return string Telegram command name (without leading slash) */ protected function parseCommand(string $text, int $offset, int $length): string { if (trim($text) === '') { throw new InvalidArgumentException('Message is empty, Cannot parse for command'); } // remove leading slash $command = substr( $text, $offset + 1, $length - 1 ); // When in group - Ex: /command@MyBot. Just get the command name. return Str::of($command)->explode('@')->first(); } /** * Handles Inbound Messages and Executes Appropriate Command. */ protected function handler(Update $update): Update { $message = $update->getMessage(); if ($message->has('entities')) { $this->parseCommandsIn($message)->each(fn ($entity) => $this->process( $entity instanceof MessageEntity ? $entity->all() : $entity, $update )); } return $update; } /** * Returns all bot_commands detected in the update. */ private function parseCommandsIn(Collection $message): Collection { return Collection::wrap($message->get('entities')) ->filter(static fn (MessageEntity $entity): bool => $entity->type === 'bot_command'); } /** * Execute a bot command from the update text. * * @param array $entity {@see MessageEntity} object attributes. */ private function process(array $entity, Update $update): void { $command = $this->parseCommand( $update->getMessage()->text, $entity['offset'], $entity['length'] ); $this->execute($command, $update, $entity); } /** * Execute the command. * * @param string $name Telegram command name without leading slash * @param array $entity */ protected function execute(string $name, Update $update, array $entity): mixed { $command = $this->commands[$name] ?? $this->commandAliases[$name] ?? $this->commands['help'] ?? collect($this->commands)->first(fn ($command): bool => $command instanceof $name); return $command?->make($this->telegram, $update, $entity) ?? false; } /** * @param CommandInterface|class-string $command * * @throws TelegramSDKException */ private function resolveCommand(CommandInterface|string $command): CommandInterface { if (! is_a($command, CommandInterface::class, true)) { throw new TelegramSDKException( sprintf( 'Command class "%s" should be an instance of "%s"', is_object($command) ? $command::class : $command, CommandInterface::class ) ); } $commandInstance = $this->buildDependencyInjectedClass($command); if ($commandInstance instanceof Command && $this->telegram) { $commandInstance->setTelegram($this->getTelegram()); } return $commandInstance; } /** * @throws TelegramSDKException */ private function checkForConflicts(CommandInterface $command, string $alias): void { if (isset($this->commands[$alias])) { throw new TelegramSDKException( sprintf( '[Error] Alias [%s] conflicts with command name of "%s" try with another name or remove this alias from the list.', $alias, $command::class ) ); } if (isset($this->commandAliases[$alias])) { throw new TelegramSDKException( sprintf( '[Error] Alias [%s] conflicts with another command\'s alias list: "%s", try with another name or remove this alias from the list.', $alias, $command::class ) ); } } } telegram-bot-sdk/src/Commands/CommandInterface.php000064400000000634152665541660016170 0ustar00name; } /** * Set Command Name. */ public function setName(string $name): self { $this->name = $name; return $this; } /** * Get Command Aliases. * * Helpful when you want to trigger command with more than one name. */ public function getAliases(): array { return $this->aliases; } /** * Set Command Aliases. */ public function setAliases(array|string $aliases): self { $this->aliases = (array) $aliases; return $this; } /** * Get Command Description. * * The Telegram command description. */ public function getDescription(): string { return $this->description; } /** * Set Command Description. */ public function setDescription(string $description): self { $this->description = $description; return $this; } public function argument(string $name, mixed $default = null): mixed { return $this->arguments[$name] ?? $default; } /** * Get Command Arguments. */ public function getArguments(): array { return $this->arguments; } /** * Set Command Arguments. */ public function setArguments(array $arguments): self { $this->arguments = $arguments; return $this; } /** * Get Command Arguments Pattern. */ public function getPattern(): string { return $this->pattern; } /** * Get Command Arguments Pattern. */ public function setPattern(string $pattern): self { $this->pattern = $pattern; return $this; } /** * Process Inbound Command. */ public function make(Api $telegram, Update $update, array $entity): mixed { $this->telegram = $telegram; $this->update = $update; $this->entity = $entity; $this->arguments = $this->parseCommandArguments(); return $this->handle(); } /** * Parse Command Arguments. */ protected function parseCommandArguments(): array { if ($this->pattern === '') { return []; } // Generate the regex needed to search for this pattern [$pattern, $arguments] = $this->makeRegexPattern(); preg_match("%{$pattern}%ixmu", $this->relevantMessageSubString(), $matches, PREG_UNMATCHED_AS_NULL); return $this->formatMatches($matches, $arguments); } private function makeRegexPattern(): array { preg_match_all( pattern: '#\{\s*(?\w+)\s*(?::\s*(?\S+)\s*)?}#ixmu', subject: $this->pattern, matches: $matches, flags: PREG_SET_ORDER ); $patterns = collect($matches) ->mapWithKeys(function ($match): array { $pattern = $match['pattern'] ?? '[^ ]++'; return [ $match['name'] => "(?<{$match['name']}>{$pattern})?", ]; }) ->filter(); $commandName = ($this->aliases === []) ? $this->name : implode('|', [$this->name, ...$this->aliases]); return [ sprintf('(?:\/)%s%s%s', "(?:{$commandName})", self::OPTIONAL_BOT_NAME, $patterns->implode('\s*')), $patterns->keys()->all(), ]; } private function relevantMessageSubString(): string { // Get all the bot_command offsets in the Update object $commandOffsets = $this->allCommandOffsets(); if ($commandOffsets->isEmpty()) { return $this->getUpdate()->getMessage()->text ?? ''; } // Extract the current offset for this command and, if it exists, the offset of the NEXT bot_command entity $splice = $commandOffsets->splice( $commandOffsets->search($this->entity['offset']), 2 ); return $splice->count() === 2 ? $this->cutTextBetween($splice) : $this->cutTextFrom($splice); } private function allCommandOffsets(): Collection { return $this->getUpdate()->getMessage()->get('entities', collect()) ->filter(static fn (MessageEntity $entity): bool => $entity->type === 'bot_command') ->pluck('offset') ?? collect(); } private function cutTextBetween(Collection $splice): string { return mb_substr( $this->getUpdate()->getMessage()->text ?? '', $splice->first(), $splice->last() - $splice->first() ); } private function cutTextFrom(Collection $splice): string { return mb_substr( $this->getUpdate()->getMessage()->text ?? '', $splice->first() ); } private function formatMatches(array $matches, array $arguments): array { $matches = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY); return array_merge(array_fill_keys($arguments, null), $matches); } /** * {@inheritdoc} */ abstract public function handle(); /** * Helper to Trigger other Commands. */ protected function triggerCommand(string $command): mixed { return $this->getCommandBus()->execute($command, $this->update, $this->entity); } /** * Returns an instance of Command Bus. */ public function getCommandBus(): CommandBus { return $this->telegram->getCommandBus(); } } telegram-bot-sdk/src/Answers/AnswerBus.php000064400000002262152665541660014562 0ustar00$method(...$parameters); } throw new BadMethodCallException(sprintf('Method [%s] does not exist.', $method)); } /** * Use PHP Reflection and Laravel Container to instantiate the answer with type hinted dependencies. */ protected function buildDependencyInjectedClass(object|string $class): object { if (is_object($class)) { return $class; } if (! $this->telegram->hasContainer()) { return new $class; } $container = $this->telegram->getContainer(); if ($container instanceof Container) { return $container->make($class); } return $container->get($class); } } telegram-bot-sdk/src/Answers/Answerable.php000064400000005370152665541660014737 0ustar00telegram, $methodName)) { throw new BadMethodCallException(sprintf('Method [%s] does not exist.', $method)); } $chatId = $this->update->getChat()->id ?? null; if (! $chatId) { throw new BadMethodCallException(sprintf('No chat available for reply with [%s].', $method)); } $params = array_merge(['chat_id' => $chatId], $parameters[0]); return $this->telegram->{$methodName}($params); } /** * Returns Update object. */ public function getUpdate(): Update { return $this->update; } } telegram-bot-sdk/src/Storage/emoji.json000064400000073226152665541660014130 0ustar00{ "100": "💯", "1234": "🔢", "grinning": "😀", "grimacing": "😬", "grin": "😁", "joy": "😂", "smiley": "😃", "smile": "😄", "sweat_smile": "😅", "laughing": "😆", "innocent": "😇", "wink": "😉", "blush": "😊", "slightly_smiling": "🙂", "upside_down": "🙃", "relaxed": "☺️", "yum": "😋", "relieved": "😌", "heart_eyes": "😍", "kissing_heart": "😘", "kissing": "😗", "kissing_smiling_eyes": "😙", "kissing_closed_eyes": "😚", "stuck_out_tongue_winking_eye": "😜", "stuck_out_tongue_closed_eyes": "😝", "stuck_out_tongue": "😛", "money_mouth": "🤑", "nerd": "🤓", "sunglasses": "😎", "hugging": "🤗", "smirk": "😏", "no_mouth": "😶", "neutral_face": "😐", "expressionless": "😑", "unamused": "😒", "rolling_eyes": "🙄", "thinking": "🤔", "flushed": "😳", "disappointed": "😞", "worried": "😟", "angry": "😠", "rage": "😡", "pensive": "😔", "confused": "😕", "slightly_sad": "🙁", "white_frowning": "☹", "persevere": "😣", "confounded": "😖", "tired_face": "😫", "weary": "😩", "triumph": "😤", "open_mouth": "😮", "scream": "😱", "fearful": "😨", "cold_sweat": "😰", "hushed": "😯", "frowning": "😦", "anguished": "😧", "cry": "😢", "disappointed_relieved": "😥", "sleepy": "😪", "sweat": "😓", "sob": "😭", "dizzy_face": "😵", "astonished": "😲", "zipper_mouth": "🤐", "mask": "😷", "thermometer_face": "🤒", "bandage_face": "🤕", "sleeping": "😴", "zzz": "💤", "hankey": "💩", "smiling_imp": "😈", "imp": "👿", "japanese_ogre": "👹", "japanese_goblin": "👺", "skull": "💀", "ghost": "👻", "alien": "👽", "robot": "🤖", "smiley_cat": "😺", "smile_cat": "😸", "joy_cat": "😹", "heart_eyes_cat": "😻", "smirk_cat": "😼", "kissing_cat": "😽", "scream_cat": "🙀", "crying_cat_face": "😿", "pouting_cat": "😾", "raised_hands": "🙌", "clap": "👏", "wave": "👋", "+1": "👍", "-1": "👎", "facepunch": "👊", "fist": "✊", "v": "✌️", "ok_hand": "👌", "hand": "✋", "open_hands": "👐", "muscle": "💪", "pray": "🙏", "point_up": "☝️", "point_up_2": "👆", "point_down": "👇", "point_left": "👈", "point_right": "👉", "middle_finger": "🖕", "splayed_fingers": "🖐", "sign_of_horns": "🤘", "vulcan_salute": "🖖", "writing_hand": "✍", "nail_care": "💅", "lips": "👄", "tongue": "👅", "ear": "👂", "nose": "👃", "eye": "👁", "eyes": "👀", "bust_in_silhouette": "👤", "busts_in_silhouette": "👥", "speaking_head": "🗣", "baby": "👶", "boy": "👦", "girl": "👧", "man": "👨", "woman": "👩", "person_with_blond_hair": "👱", "older_man": "👴", "older_woman": "👵", "man_with_gua_pi_mao": "👲", "man_with_turban": "👳", "cop": "👮", "construction_worker": "👷", "guardsman": "💂", "sleuth": "🕵", "santa": "🎅", "angel": "👼", "princess": "👸", "bride_with_veil": "👰", "runner": "🏃", "walking": "🚶", "dancer": "💃", "dancers": "👯", "couple": "👫", "two_men_holding_hands": "👬", "two_women_holding_hands": "👭", "bow": "🙇", "information_desk_person": "💁", "no_good": "🙅", "ok_woman": "🙆", "raising_hand": "🙋", "person_with_pouting_face": "🙎", "person_frowning": "🙍", "haircut": "💇", "massage": "💆", "couple_with_heart": "💑", "female_couple_with_heart": "👩‍❤️‍👩", "male_couple_with_heart": "👨‍❤️‍👨", "couplekiss": "💏", "female_couplekiss": "👩‍❤️‍💋‍👩", "male_couplekiss": "👨‍❤️‍💋‍👨", "family": "👪", "family_man_woman_girl": "👨‍👩‍👧", "family_man_woman_girl_boy": "👨‍👩‍👧‍👦", "family_man_woman_boys": "👨‍👩‍👦‍👦", "family_man_woman_girls": "👨‍👩‍👧‍👧", "family_women_boy": "👩‍👩‍👦", "family_women_girl": "👩‍👩‍👧", "family_women_girl_boy": "👩‍👩‍👧‍👦", "family_women_boys": "👩‍👩‍👦‍👦", "family_women_girls": "👩‍👩‍👧‍👧", "family_men_boy": "👨‍👨‍👦", "family_men_girl": "👨‍👨‍👧", "family_men_girl_boy": "👨‍👨‍👧‍👦", "family_men_boys": "👨‍👨‍👦‍👦", "family_men_girls": "👨‍👨‍👧‍👧", "womans_clothes": "👚", "shirt": "👕", "jeans": "👖", "necktie": "👔", "dress": "👗", "bikini": "👙", "kimono": "👘", "lipstick": "💄", "kiss": "💋", "footprints": "👣", "high_heel": "👠", "sandal": "👡", "boot": "👢", "mans_shoe": "👞", "athletic_shoe": "👟", "womans_hat": "👒", "tophat": "🎩", "helmet": "⛑", "mortar_board": "🎓", "crown": "👑", "school_satchel": "🎒", "pouch": "👝", "purse": "👛", "handbag": "👜", "briefcase": "💼", "eyeglasses": "👓", "dark_sunglasses": "🕶", "ring": "💍", "closed_umbrella": "🌂", "dog": "🐶", "cat": "🐱", "mouse": "🐭", "hamster": "🐹", "rabbit": "🐰", "bear": "🐻", "panda_face": "🐼", "koala": "🐨", "tiger": "🐯", "lion_face": "🦁", "cow": "🐮", "pig": "🐷", "pig_nose": "🐽", "frog": "🐸", "octopus": "🐙", "monkey_face": "🐵", "see_no_evil": "🙈", "hear_no_evil": "🙉", "speak_no_evil": "🙊", "monkey": "🐒", "chicken": "🐔", "penguin": "🐧", "bird": "🐦", "baby_chick": "🐤", "hatching_chick": "🐣", "hatched_chick": "🐥", "wolf": "🐺", "boar": "🐗", "horse": "🐴", "unicorn_face": "🦄", "bee": "🐝", "bug": "🐛", "snail": "🐌", "beetle": "🐞", "ant": "🐜", "spider": "🕷", "scorpion": "🦂", "crab": "🦀", "snake": "🐍", "turtle": "🐢", "tropical_fish": "🐠", "fish": "🐟", "blowfish": "🐡", "dolphin": "🐬", "whale": "🐳", "whale2": "🐋", "crocodile": "🐊", "leopard": "🐆", "tiger2": "🐅", "water_buffalo": "🐃", "ox": "🐂", "cow2": "🐄", "dromedary_camel": "🐪", "camel": "🐫", "elephant": "🐘", "goat": "🐐", "ram": "🐏", "sheep": "🐑", "racehorse": "🐎", "pig2": "🐖", "rat": "🐀", "mouse2": "🐁", "rooster": "🐓", "turkey": "🦃", "dove_of_peace": "🕊", "dog2": "🐕", "poodle": "🐩", "cat2": "🐈", "rabbit2": "🐇", "chipmunk": "🐿", "feet": "🐾", "dragon": "🐉", "dragon_face": "🐲", "cactus": "🌵", "christmas_tree": "🎄", "evergreen_tree": "🌲", "deciduous_tree": "🌳", "palm_tree": "🌴", "seedling": "🌱", "herb": "🌿", "shamrock": "☘", "four_leaf_clover": "🍀", "bamboo": "🎍", "tanabata_tree": "🎋", "leaves": "🍃", "fallen_leaf": "🍂", "maple_leaf": "🍁", "ear_of_rice": "🌾", "hibiscus": "🌺", "sunflower": "🌻", "rose": "🌹", "tulip": "🌷", "blossom": "🌼", "cherry_blossom": "🌸", "bouquet": "💐", "mushroom": "🍄", "chestnut": "🌰", "jack_o_lantern": "🎃", "shell": "🐚", "spider_web": "🕸", "earth_americas": "🌎", "earth_africa": "🌍", "earth_asia": "🌏", "full_moon": "🌕", "waning_gibbous_moon": "🌖", "last_quarter_moon": "🌗", "waning_crescent_moon": "🌘", "new_moon": "🌑", "waxing_crescent_moon": "🌒", "first_quarter_moon": "🌓", "moon": "🌔", "new_moon_with_face": "🌚", "full_moon_with_face": "🌝", "first_quarter_moon_with_face": "🌛", "last_quarter_moon_with_face": "🌜", "sun_with_face": "🌞", "crescent_moon": "🌙", "star": "⭐", "star2": "🌟", "dizzy": "💫", "sparkles": "✨", "comet": "☄", "sunny": "☀️", "white_sun_with_small_cloud": "🌤", "partly_sunny": "⛅", "white_sun_behind_cloud": "🌥", "white_sun_behind_cloud_with_rain": "🌦", "cloud": "☁️", "cloud_with_rain": "🌧", "thunder_cloud_and_rain": "⛈", "cloud_with_lightning": "🌩", "zap": "⚡", "fire": "🔥", "boom": "💥", "snowflake": "❄️", "cloud_with_snow": "🌨", "snowman": "⛄", "snowman_with_snow": "☃", "wind_blowing_face": "🌬", "dash": "💨", "cloud_with_tornado": "🌪", "fog": "🌫", "umbrella_without_rain": "☂", "umbrella": "☔", "droplet": "💧", "sweat_drops": "💦", "ocean": "🌊", "green_apple": "🍏", "apple": "🍎", "pear": "🍐", "tangerine": "🍊", "lemon": "🍋", "banana": "🍌", "watermelon": "🍉", "grapes": "🍇", "strawberry": "🍓", "melon": "🍈", "cherries": "🍒", "peach": "🍑", "pineapple": "🍍", "tomato": "🍅", "eggplant": "🍆", "hot_pepper": "🌶", "corn": "🌽", "sweet_potato": "🍠", "honey_pot": "🍯", "bread": "🍞", "cheese_wedge": "🧀", "poultry_leg": "🍗", "meat_on_bone": "🍖", "fried_shrimp": "🍤", "egg": "🍳", "hamburger": "🍔", "fries": "🍟", "hot_dog": "🌭", "pizza": "🍕", "spaghetti": "🍝", "taco": "🌮", "burrito": "🌯", "ramen": "🍜", "stew": "🍲", "fish_cake": "🍥", "sushi": "🍣", "bento": "🍱", "curry": "🍛", "rice_ball": "🍙", "rice": "🍚", "rice_cracker": "🍘", "oden": "🍢", "dango": "🍡", "shaved_ice": "🍧", "ice_cream": "🍨", "icecream": "🍦", "cake": "🍰", "birthday": "🎂", "custard": "🍮", "candy": "🍬", "lollipop": "🍭", "chocolate_bar": "🍫", "popcorn": "🍿", "doughnut": "🍩", "cookie": "🍪", "beer": "🍺", "beers": "🍻", "wine_glass": "🍷", "cocktail": "🍸", "tropical_drink": "🍹", "bottle": "🍾", "sake": "🍶", "tea": "🍵", "coffee": "☕", "baby_bottle": "🍼", "fork_and_knife": "🍴", "fork_and_knife_with_plate": "🍽", "soccer": "⚽", "basketball": "🏀", "football": "🏈", "baseball": "⚾", "tennis": "🎾", "volleyball": "🏐", "rugby_football": "🏉", "8ball": "🎱", "golf": "⛳", "golfer": "🏌", "table_tennis": "🏓", "badminton": "🏸", "ice_hockey": "🏒", "field_hockey": "🏑", "cricket": "🏏", "ski": "🎿", "skier": "⛷", "snowboarder": "🏂", "ice_skate": "⛸", "bow_and_arrow": "🏹", "fishing_pole_and_fish": "🎣", "rowboat": "🚣", "swimmer": "🏊", "surfer": "🏄", "bath": "🛀", "person_with_ball": "⛹", "weight_lifter": "🏋", "bicyclist": "🚴", "mountain_bicyclist": "🚵", "horse_racing": "🏇", "man_levitating": "🕴", "trophy": "🏆", "running_shirt_with_sash": "🎽", "sports_medal": "🏅", "military_medal": "🎖", "reminder_ribbon": "🎗", "rosette": "🏵", "ticket": "🎫", "admission_ticket": "🎟", "performing_arts": "🎭", "art": "🎨", "circus_tent": "🎪", "microphone": "🎤", "headphones": "🎧", "musical_score": "🎼", "musical_keyboard": "🎹", "saxophone": "🎷", "trumpet": "🎺", "guitar": "🎸", "violin": "🎻", "clapper": "🎬", "video_game": "🎮", "space_invader": "👾", "dart": "🎯", "game_die": "🎲", "slot_machine": "🎰", "bowling": "🎳", "car": "🚗", "taxi": "🚕", "blue_car": "🚙", "bus": "🚌", "trolleybus": "🚎", "racing_car": "🏎", "police_car": "🚓", "ambulance": "🚑", "fire_engine": "🚒", "minibus": "🚐", "truck": "🚚", "articulated_lorry": "🚛", "tractor": "🚜", "racing_motorcycle": "🏍", "bike": "🚲", "rotating_light": "🚨", "oncoming_police_car": "🚔", "oncoming_bus": "🚍", "oncoming_automobile": "🚘", "oncoming_taxi": "🚖", "aerial_tramway": "🚡", "mountain_cableway": "🚠", "suspension_railway": "🚟", "railway_car": "🚃", "train": "🚋", "monorail": "🚝", "bullettrain_side": "🚄", "bullettrain_front": "🚅", "light_rail": "🚈", "mountain_railway": "🚞", "steam_locomotive": "🚂", "train2": "🚆", "metro": "🚇", "tram": "🚊", "station": "🚉", "helicopter": "🚁", "small_airplane": "🛩", "airplane": "✈️", "airplane_departure": "🛫", "airplane_arrival": "🛬", "boat": "⛵", "motor_boat": "🛥", "speedboat": "🚤", "ferry": "⛴", "passenger_ship": "🛳", "rocket": "🚀", "artificial_satellite": "🛰", "seat": "💺", "anchor": "⚓", "construction": "🚧", "fuelpump": "⛽", "busstop": "🚏", "vertical_traffic_light": "🚦", "traffic_light": "🚥", "checkered_flag": "🏁", "ship": "🚢", "ferris_wheel": "🎡", "roller_coaster": "🎢", "carousel_horse": "🎠", "building_construction": "🏗", "foggy": "🌁", "tokyo_tower": "🗼", "factory": "🏭", "fountain": "⛲", "rice_scene": "🎑", "mountain": "⛰", "snow_capped_mountain": "🏔", "mount_fuji": "🗻", "volcano": "🌋", "japan": "🗾", "camping": "🏕", "tent": "⛺", "national_park": "🏞", "motorway": "🛣", "railway_track": "🛤", "sunrise": "🌅", "sunrise_over_mountains": "🌄", "desert": "🏜", "beach_with_umbrella": "🏖", "desert_island": "🏝", "city_sunrise": "🌇", "city_sunset": "🌆", "cityscape": "🏙", "night_with_stars": "🌃", "bridge_at_night": "🌉", "milky_way": "🌌", "stars": "🌠", "sparkler": "🎇", "fireworks": "🎆", "rainbow": "🌈", "buildings": "🏘", "european_castle": "🏰", "japanese_castle": "🏯", "stadium": "🏟", "statue_of_liberty": "🗽", "house": "🏠", "house_with_garden": "🏡", "derelict_house": "🏚", "office": "🏢", "department_store": "🏬", "post_office": "🏣", "european_post_office": "🏤", "hospital": "🏥", "bank": "🏦", "hotel": "🏨", "convenience_store": "🏪", "school": "🏫", "love_hotel": "🏩", "wedding": "💒", "museum": "🏛", "church": "⛪", "mosque": "🕌", "synagogue": "🕍", "kaaba": "🕋", "shinto_shrine": "⛩", "watch": "⌚", "iphone": "📱", "calling": "📲", "computer": "💻", "keyboard": "⌨", "desktop_computer": "🖥", "printer": "🖨", "three_button_mouse": "🖱", "trackball": "🖲", "joystick": "🕹", "compression": "🗜", "minidisc": "💽", "floppy_disk": "💾", "cd": "💿", "dvd": "📀", "vhs": "📼", "camera": "📷", "camera_with_flash": "📸", "video_camera": "📹", "movie_camera": "🎥", "film_projector": "📽", "film_frames": "🎞", "telephone_receiver": "📞", "phone": "☎️", "pager": "📟", "fax": "📠", "tv": "📺", "radio": "📻", "studio_microphone": "🎙", "level_slider": "🎚", "control_knobs": "🎛", "stopwatch": "⏱", "timer_clock": "⏲", "alarm_clock": "⏰", "mantelpiece_clock": "🕰", "hourglass_flowing_sand": "⏳", "hourglass": "⌛", "satellite": "📡", "battery": "🔋", "electric_plug": "🔌", "bulb": "💡", "flashlight": "🔦", "candle": "🕯", "wastebasket": "🗑", "oil_drum": "🛢", "money_with_wings": "💸", "dollar": "💵", "yen": "💴", "euro": "💶", "pound": "💷", "moneybag": "💰", "credit_card": "💳", "gem": "💎", "scales": "⚖", "wrench": "🔧", "hammer": "🔨", "hammer_and_pick": "⚒", "hammer_and_wrench": "🛠", "pick": "⛏", "nut_and_bolt": "🔩", "gear": "⚙", "chains": "⛓", "gun": "🔫", "bomb": "💣", "hocho": "🔪", "dagger_knife": "🗡", "crossed_swords": "⚔", "shield": "🛡", "smoking": "🚬", "skull_and_crossbones": "☠", "coffin": "⚰", "funeral_urn": "⚱", "amphora": "🏺", "crystal_ball": "🔮", "prayer_beads": "📿", "barber": "💈", "alembic": "⚗", "telescope": "🔭", "microscope": "🔬", "hole": "🕳", "pill": "💊", "syringe": "💉", "thermometer": "🌡", "label": "🏷", "bookmark": "🔖", "toilet": "🚽", "shower": "🚿", "bathtub": "🛁", "key": "🔑", "old_key": "🗝", "couch_and_lamp": "🛋", "sleeping_accommodation": "🛌", "bed": "🛏", "door": "🚪", "bellhop_bell": "🛎", "frame_with_picture": "🖼", "world_map": "🗺", "umbrella_on_ground": "⛱", "moyai": "🗿", "shopping_bags": "🛍", "balloon": "🎈", "flags": "🎏", "ribbon": "🎀", "gift": "🎁", "confetti_ball": "🎊", "tada": "🎉", "dolls": "🎎", "wind_chime": "🎐", "crossed_flags": "🎌", "izakaya_lantern": "🏮", "envelope": "✉️", "envelope_with_arrow": "📩", "incoming_envelope": "📨", "email": "📧", "love_letter": "💌", "postbox": "📮", "mailbox_closed": "📪", "mailbox": "📫", "mailbox_with_mail": "📬", "mailbox_with_no_mail": "📭", "package": "📦", "postal_horn": "📯", "inbox_tray": "📥", "outbox_tray": "📤", "scroll": "📜", "page_with_curl": "📃", "bookmark_tabs": "📑", "bar_chart": "📊", "chart_with_upwards_trend": "📈", "chart_with_downwards_trend": "📉", "page_facing_up": "📄", "date": "📅", "calendar": "📆", "spiral_calendar_pad": "🗓", "card_index": "📇", "card_file_box": "🗃", "ballot_box_with_ballot": "🗳", "file_cabinet": "🗄", "clipboard": "📋", "spiral_note_pad": "🗒", "file_folder": "📁", "open_file_folder": "📂", "card_index_dividers": "🗂", "rolled_up_newspaper": "🗞", "newspaper": "📰", "notebook": "📓", "closed_book": "📕", "green_book": "📗", "blue_book": "📘", "orange_book": "📙", "notebook_with_decorative_cover": "📔", "ledger": "📒", "books": "📚", "book": "📖", "link": "🔗", "paperclip": "📎", "linked_paperclips": "🖇", "scissors": "✂️", "triangular_ruler": "📐", "straight_ruler": "📏", "pushpin": "📌", "round_pushpin": "📍", "triangular_flag_on_post": "🚩", "waving_white_flag": "🏳", "waving_black_flag": "🏴", "closed_lock_with_key": "🔐", "lock": "🔒", "unlock": "🔓", "lock_with_ink_pen": "🔏", "lower_left_ballpoint_pen": "🖊", "lower_left_fountain_pen": "🖋", "black_nib": "✒️", "memo": "📝", "pencil2": "✏️", "lower_left_crayon": "🖍", "lower_left_paintbrush": "🖌", "mag": "🔍", "mag_right": "🔎", "heart": "❤️", "yellow_heart": "💛", "green_heart": "💚", "blue_heart": "💙", "purple_heart": "💜", "broken_heart": "💔", "heavy_heart_exclamation_mark_ornament": "❣", "two_hearts": "💕", "revolving_hearts": "💞", "heartbeat": "💓", "heartpulse": "💗", "sparkling_heart": "💖", "cupid": "💘", "gift_heart": "💝", "heart_decoration": "💟", "peace_symbol": "☮", "latin_cross": "✝", "star_and_crescent": "☪", "om_symbol": "🕉", "wheel_of_dharma": "☸", "star_of_david": "✡", "six_pointed_star": "🔯", "menorah_with_nine_branches": "🕎", "yin_yang": "☯", "orthodox_cross": "☦", "place_of_worship": "🛐", "ophiuchus": "⛎", "aries": "♈", "taurus": "♉", "gemini": "♊", "cancer": "♋", "leo": "♌", "virgo": "♍", "libra": "♎", "scorpius": "♏", "sagittarius": "♐", "capricorn": "♑", "aquarius": "♒", "pisces": "♓", "id": "🆔", "atom_symbol": "⚛", "u7a7a": "🈳", "u5272": "🈹", "radioactive_sign": "☢", "biohazard_sign": "☣", "mobile_phone_off": "📴", "vibration_mode": "📳", "u6709": "🈶", "u7121": "🈚", "u7533": "🈸", "u55b6": "🈺", "u6708": "🈷️", "eight_pointed_black_star": "✴️", "vs": "🆚", "accept": "🉑", "white_flower": "💮", "ideograph_advantage": "🉐", "secret": "㊙️", "congratulations": "㊗️", "u5408": "🈴", "u6e80": "🈵", "u7981": "🈲", "a": "🅰️", "b": "🅱️", "ab": "🆎", "cl": "🆑", "o2": "🅾️", "sos": "🆘", "no_entry": "⛔", "name_badge": "📛", "no_entry_sign": "🚫", "x": "❌", "o": "⭕", "anger": "💢", "hotsprings": "♨️", "no_pedestrians": "🚷", "do_not_litter": "🚯", "no_bicycles": "🚳", "non-potable_water": "🚱", "underage": "🔞", "no_mobile_phones": "📵", "exclamation": "❗", "grey_exclamation": "❕", "question": "❓", "grey_question": "❔", "bangbang": "‼️", "interrobang": "⁉️", "low_brightness": "🔅", "high_brightness": "🔆", "trident": "🔱", "fleur_de_lis": "⚜", "part_alternation_mark": "〽️", "warning": "⚠️", "children_crossing": "🚸", "beginner": "🔰", "recycle": "♻️", "u6307": "🈯", "chart": "💹", "sparkle": "❇️", "eight_spoked_asterisk": "✳️", "negative_squared_cross_mark": "❎", "white_check_mark": "✅", "diamond_shape_with_a_dot_inside": "💠", "cyclone": "🌀", "loop": "➿", "globe_with_meridians": "🌐", "m": "Ⓜ️", "atm": "🏧", "sa": "🈂️", "passport_control": "🛂", "customs": "🛃", "baggage_claim": "🛄", "left_luggage": "🛅", "wheelchair": "♿", "no_smoking": "🚭", "wc": "🚾", "parking": "🅿️", "potable_water": "🚰", "mens": "🚹", "womens": "🚺", "baby_symbol": "🚼", "restroom": "🚻", "put_litter_in_its_place": "🚮", "cinema": "🎦", "signal_strength": "📶", "koko": "🈁", "ng": "🆖", "ok": "🆗", "up": "🆙", "cool": "🆒", "new": "🆕", "free": "🆓", "zero": "0️⃣", "one": "1️⃣", "two": "2️⃣", "three": "3️⃣", "four": "4️⃣", "five": "5️⃣", "six": "6️⃣", "seven": "7️⃣", "eight": "8️⃣", "nine": "9️⃣", "keycap_ten": "🔟", "keycap_star": "*⃣", "arrow_forward": "▶️", "double_vertical_bar": "⏸", "black_right_pointing_triangle_with_double_vertical_bar": "⏭", "black_square_for_stop": "⏹", "black_circle_for_record": "⏺", "black_right_pointing_double_triangle_with_vertical_bar": "⏯", "black_left_pointing_double_triangle_with_vertical_bar": "⏮", "fast_forward": "⏩", "rewind": "⏪", "twisted_rightwards_arrows": "🔀", "repeat": "🔁", "repeat_one": "🔂", "arrow_backward": "◀️", "arrow_up_small": "🔼", "arrow_down_small": "🔽", "arrow_double_up": "⏫", "arrow_double_down": "⏬", "arrow_right": "➡️", "arrow_left": "⬅️", "arrow_up": "⬆️", "arrow_down": "⬇️", "arrow_upper_right": "↗️", "arrow_lower_right": "↘️", "arrow_lower_left": "↙️", "arrow_upper_left": "↖️", "arrow_up_down": "↕️", "left_right_arrow": "↔️", "arrows_counterclockwise": "🔄", "arrow_right_hook": "↪️", "leftwards_arrow_with_hook": "↩️", "arrow_heading_up": "⤴️", "arrow_heading_down": "⤵️", "hash": "#️⃣", "information_source": "ℹ️", "abc": "🔤", "abcd": "🔡", "capital_abcd": "🔠", "symbols": "🔣", "musical_note": "🎵", "notes": "🎶", "wavy_dash": "〰️", "curly_loop": "➰", "heavy_check_mark": "✔️", "arrows_clockwise": "🔃", "heavy_plus_sign": "➕", "heavy_minus_sign": "➖", "heavy_division_sign": "➗", "heavy_multiplication_x": "✖️", "heavy_dollar_sign": "💲", "currency_exchange": "💱", "copyright": "©️", "registered": "®️", "tm": "™️", "end": "🔚", "back": "🔙", "on": "🔛", "top": "🔝", "soon": "🔜", "ballot_box_with_check": "☑️", "radio_button": "🔘", "white_circle": "⚪", "black_circle": "⚫", "red_circle": "🔴", "large_blue_circle": "🔵", "small_orange_diamond": "🔸", "small_blue_diamond": "🔹", "large_orange_diamond": "🔶", "large_blue_diamond": "🔷", "small_red_triangle": "🔺", "black_small_square": "▪️", "white_small_square": "▫️", "black_large_square": "⬛", "white_large_square": "⬜", "small_red_triangle_down": "🔻", "black_medium_square": "◼️", "white_medium_square": "◻️", "black_medium_small_square": "◾", "white_medium_small_square": "◽", "black_square_button": "🔲", "white_square_button": "🔳", "speaker": "🔈", "sound": "🔉", "loud_sound": "🔊", "mute": "🔇", "mega": "📣", "loudspeaker": "📢", "bell": "🔔", "no_bell": "🔕", "black_joker": "🃏", "mahjong": "🀄", "spades": "♠️", "clubs": "♣️", "hearts": "♥️", "diamonds": "♦️", "flower_playing_cards": "🎴", "thought_balloon": "💭", "right_anger_bubble": "🗯", "speech_balloon": "💬", "left_speech_bubble": "🗨", "clock1": "🕐", "clock2": "🕑", "clock3": "🕒", "clock4": "🕓", "clock5": "🕔", "clock6": "🕕", "clock7": "🕖", "clock8": "🕗", "clock9": "🕘", "clock10": "🕙", "clock11": "🕚", "clock12": "🕛", "clock130": "🕜", "clock230": "🕝", "clock330": "🕞", "clock430": "🕟", "clock530": "🕠", "clock630": "🕡", "clock730": "🕢", "clock830": "🕣", "clock930": "🕤", "clock1030": "🕥", "clock1130": "🕦", "clock1230": "🕧", "af": "🇦🇫", "ax": "🇦🇽", "al": "🇦🇱", "dz": "🇩🇿", "as": "🇦🇸", "ad": "🇦🇩", "ao": "🇦🇴", "ai": "🇦🇮", "aq": "🇦🇶", "ag": "🇦🇬", "ar": "🇦🇷", "am": "🇦🇲", "aw": "🇦🇼", "au": "🇦🇺", "at": "🇦🇹", "az": "🇦🇿", "bs": "🇧🇸", "bh": "🇧🇭", "bd": "🇧🇩", "bb": "🇧🇧", "by": "🇧🇾", "be": "🇧🇪", "bz": "🇧🇿", "bj": "🇧🇯", "bm": "🇧🇲", "bt": "🇧🇹", "bo": "🇧🇴", "bq": "🇧🇶", "ba": "🇧🇦", "bw": "🇧🇼", "br": "🇧🇷", "io": "🇮🇴", "vg": "🇻🇬", "bn": "🇧🇳", "bg": "🇧🇬", "bf": "🇧🇫", "bi": "🇧🇮", "cv": "🇨🇻", "kh": "🇰🇭", "cm": "🇨🇲", "ca": "🇨🇦", "ic": "🇮🇨", "ky": "🇰🇾", "cf": "🇨🇫", "td": "🇹🇩", "chile": "🇨🇱", "cn": "🇨🇳", "cx": "🇨🇽", "cc": "🇨🇨", "co": "🇨🇴", "km": "🇰🇲", "cg": "🇨🇬", "drc": "🇨🇩", "ck": "🇨🇰", "cr": "🇨🇷", "hr": "🇭🇷", "cu": "🇨🇺", "cw": "🇨🇼", "cy": "🇨🇾", "cz": "🇨🇿", "dk": "🇩🇰", "dj": "🇩🇯", "dm": "🇩🇲", "do": "🇩🇴", "ec": "🇪🇨", "eg": "🇪🇬", "sv": "🇸🇻", "gq": "🇬🇶", "er": "🇪🇷", "ee": "🇪🇪", "et": "🇪🇹", "eu": "🇪🇺", "fk": "🇫🇰", "fo": "🇫🇴", "fj": "🇫🇯", "fi": "🇫🇮", "fr": "🇫🇷", "gf": "🇬🇫", "pf": "🇵🇫", "tf": "🇹🇫", "ga": "🇬🇦", "gm": "🇬🇲", "ge": "🇬🇪", "de": "🇩🇪", "gh": "🇬🇭", "gi": "🇬🇮", "gr": "🇬🇷", "gl": "🇬🇱", "gd": "🇬🇩", "gp": "🇬🇵", "gu": "🇬🇺", "gt": "🇬🇹", "gg": "🇬🇬", "gn": "🇬🇳", "gw": "🇬🇼", "gy": "🇬🇾", "ht": "🇭🇹", "hn": "🇭🇳", "hk": "🇭🇰", "hu": "🇭🇺", "is": "🇮🇸", "in": "🇮🇳", "indonesia": "🇮🇩", "ir": "🇮🇷", "iq": "🇮🇶", "ie": "🇮🇪", "im": "🇮🇲", "il": "🇮🇱", "it": "🇮🇹", "ci": "🇨🇮", "jm": "🇯🇲", "jp": "🇯🇵", "je": "🇯🇪", "jo": "🇯🇴", "kz": "🇰🇿", "ke": "🇰🇪", "ki": "🇰🇮", "xk": "🇽🇰", "kw": "🇰🇼", "kg": "🇰🇬", "la": "🇱🇦", "lv": "🇱🇻", "lb": "🇱🇧", "ls": "🇱🇸", "lr": "🇱🇷", "ly": "🇱🇾", "li": "🇱🇮", "lt": "🇱🇹", "lu": "🇱🇺", "mo": "🇲🇴", "mk": "🇲🇰", "mg": "🇲🇬", "mw": "🇲🇼", "my": "🇲🇾", "mv": "🇲🇻", "ml": "🇲🇱", "mt": "🇲🇹", "mh": "🇲🇭", "mq": "🇲🇶", "mr": "🇲🇷", "mu": "🇲🇺", "yt": "🇾🇹", "mx": "🇲🇽", "fm": "🇫🇲", "md": "🇲🇩", "mc": "🇲🇨", "mn": "🇲🇳", "me": "🇲🇪", "ms": "🇲🇸", "ma": "🇲🇦", "mz": "🇲🇿", "mm": "🇲🇲", "na": "🇳🇦", "nr": "🇳🇷", "np": "🇳🇵", "nl": "🇳🇱", "nc": "🇳🇨", "nz": "🇳🇿", "ni": "🇳🇮", "ne": "🇳🇪", "nigeria": "🇳🇬", "nu": "🇳🇺", "nf": "🇳🇫", "mp": "🇲🇵", "kp": "🇰🇵", "no": "🇳🇴", "om": "🇴🇲", "pk": "🇵🇰", "pw": "🇵🇼", "ps": "🇵🇸", "pa": "🇵🇦", "pg": "🇵🇬", "py": "🇵🇾", "pe": "🇵🇪", "ph": "🇵🇭", "pn": "🇵🇳", "pl": "🇵🇱", "pt": "🇵🇹", "pr": "🇵🇷", "qa": "🇶🇦", "re": "🇷🇪", "ro": "🇷🇴", "ru": "🇷🇺", "rw": "🇷🇼", "bl": "🇧🇱", "sh": "🇸🇭", "kn": "🇰🇳", "lc": "🇱🇨", "pm": "🇵🇲", "vc": "🇻🇨", "ws": "🇼🇸", "sm": "🇸🇲", "st": "🇸🇹", "saudi_arabia": "🇸🇦", "sn": "🇸🇳", "rs": "🇷🇸", "sc": "🇸🇨", "sl": "🇸🇱", "sg": "🇸🇬", "sx": "🇸🇽", "sk": "🇸🇰", "si": "🇸🇮", "sb": "🇸🇧", "so": "🇸🇴", "za": "🇿🇦", "gs": "🇬🇸", "kr": "🇰🇷", "ss": "🇸🇸", "es": "🇪🇸", "lk": "🇱🇰", "sd": "🇸🇩", "sr": "🇸🇷", "sz": "🇸🇿", "se": "🇸🇪", "ch": "🇨🇭", "sy": "🇸🇾", "tw": "🇹🇼", "tj": "🇹🇯", "tz": "🇹🇿", "th": "🇹🇭", "tl": "🇹🇱", "tg": "🇹🇬", "tk": "🇹🇰", "to": "🇹🇴", "tt": "🇹🇹", "tn": "🇹🇳", "tr": "🇹🇷", "turkmenistan": "🇹🇲", "tc": "🇹🇨", "tuvalu": "🇹🇻", "ug": "🇺🇬", "ua": "🇺🇦", "ae": "🇦🇪", "gb": "🇬🇧", "us": "🇺🇸", "vi": "🇻🇮", "uy": "🇺🇾", "uz": "🇺🇿", "vu": "🇻🇺", "va": "🇻🇦", "ve": "🇻🇪", "vn": "🇻🇳", "wf": "🇼🇫", "eh": "🇪🇭", "ye": "🇾🇪", "zm": "🇿🇲", "zw": "🇿🇼" }telegram-bot-sdk/src/TelegramResponse.php000064400000011207152665541660014505 0ustar00httpStatusCode = $response->getStatusCode(); $this->body = $response->getBody(); $this->headers = $response->getHeaders(); $this->decodeBody(); } elseif ($response instanceof PromiseInterface) { $this->httpStatusCode = null; } else { throw new InvalidArgumentException( 'Second constructor argument "response" must be instance of ResponseInterface or PromiseInterface' ); } $this->endPoint = $request->getEndpoint(); } /** * Converts raw API response to proper decoded response. */ public function decodeBody(): void { if ($this->body !== '' && $this->body !== '0') { $this->decodedBody = json_decode($this->body, true, 512, JSON_THROW_ON_ERROR); } if ($this->decodedBody === null) { $this->decodedBody = []; parse_str($this->body, $this->decodedBody); } if (! is_array($this->decodedBody)) { $this->decodedBody = []; } if ($this->isError()) { $this->makeException(); } } /** * Checks if response is an error. */ public function isError(): bool { return isset($this->decodedBody['ok']) && ($this->decodedBody['ok'] === false); } /** * Instantiates an exception to be thrown later. */ public function makeException(): void { $this->thrownException = TelegramResponseException::create($this); } /** * Return the original request that returned this response. */ public function getRequest(): TelegramRequest { return $this->request; } /** * Gets the HTTP status code. * Returns NULL if the request was asynchronous since we are not waiting for the response. */ public function getHttpStatusCode(): ?int { return $this->httpStatusCode; } /** * Gets the Request Endpoint used to get the response. */ public function getEndpoint(): string { return $this->endPoint; } /** * Return the bot access token that was used for this request. */ public function getAccessToken(): ?string { return $this->request->getAccessToken(); } /** * Return the HTTP headers for this response. */ public function getHeaders(): array { return $this->headers; } /** * Return the raw body response. */ public function getBody(): string { return $this->body; } /** * Return the decoded body response. */ public function getDecodedBody(): ?array { return $this->decodedBody; } /** * Helper function to return the payload of a successful response. * * @return mixed */ public function getResult() { return $this->decodedBody['result'] ?? false; } /** * Throws the exception. * * @return never * * @throws TelegramSDKException */ public function throwException(): TelegramSDKException { throw $this->thrownException; } /** * Returns the exception that was thrown for this request. */ public function getThrownException(): TelegramSDKException { return $this->thrownException; } } telegram-bot-sdk/src/Events/LeagueEventDispatcher.php000064400000000254152665541660016705 0ustar00dispatcher = $emitter; } public function eventDispatcher(): EventDispatcherListenerContract { if ($this->dispatcher === null) { $this->dispatcher = EventDispatcherFactory::create(); } return $this->dispatcher; } public function hasEventDispatcher(): bool { return $this->eventDispatcher() !== null; } public function on(string $event, callable $listener, int $priority = 0): void { $this->eventDispatcher()->subscribeTo($event, $listener, $priority); } } telegram-bot-sdk/src/Events/Emitter.php000064400000000611152665541660014100 0ustar00addListener($event, $listener, $priority); } public function dispatch(object $event): object { return $this->emit($event); } } telegram-bot-sdk/src/Events/EventDispatcherListenerContract.php000064400000000406152665541660020765 0ustar00name; } public function getName(): string { return $this->name; } } telegram-bot-sdk/src/Events/AbstractEvent.php000064400000000534152665541660015240 0ustar00getName(); } } } else { abstract class AbstractEvent {} } telegram-bot-sdk/src/Actions.php000064400000004652152665541660012634 0ustar00getConstants(); } public static function isActionValid(string $action): bool { $actions = self::all(); if (in_array($action, $actions, true)) { return true; } throw new TelegramSDKException('Invalid Action! Accepted value: '.implode(', ', $actions)); } } telegram-bot-sdk/src/EntityType.php000064400000003400152665541660013340 0ustar00client = $client ?? new Client; } /** * Unwrap Promises. * * @throws Throwable */ public function __destruct() { Utils::unwrap(self::$promises); } /** * Sets HTTP client. */ public function setClient(ClientInterface $client): self { $this->client = $client; return $this; } /** * {@inheritdoc} * * @throws TelegramSDKException */ public function send( string $url, string $method, array $headers = [], array $options = [], bool $isAsyncRequest = false ): ResponseInterface|PromiseInterface|null { $body = $options['body'] ?? null; $options = $this->getOptions($headers, $body, $options, $isAsyncRequest); try { $response = $this->client->requestAsync($method, $url, $options); if ($isAsyncRequest) { self::$promises[] = $response; } else { $response = $response->wait(); } } catch (GuzzleException $guzzleException) { $response = null; if ($guzzleException instanceof RequestExceptionInterface) { $response = $guzzleException->getResponse(); } if (! $response instanceof ResponseInterface) { throw new TelegramSDKException($guzzleException->getMessage(), $guzzleException->getCode(), $guzzleException); } } return $response; } /** * Prepares and returns request options. */ private function getOptions( array $headers, mixed $body, array $options, bool $isAsyncRequest = false ): array { $default_options = [ RequestOptions::HEADERS => $headers, RequestOptions::BODY => $body, RequestOptions::TIMEOUT => $this->timeOut, RequestOptions::CONNECT_TIMEOUT => $this->connectTimeOut, RequestOptions::SYNCHRONOUS => ! $isAsyncRequest, ]; return array_merge($default_options, $options); } /** * {@inheritdoc} */ public function getTimeOut(): int { return $this->timeOut; } /** * {@inheritdoc} */ public function setTimeOut(int $timeOut): static { $this->timeOut = $timeOut; return $this; } /** * {@inheritdoc} */ public function getConnectTimeOut(): int { return $this->connectTimeOut; } /** * {@inheritdoc} */ public function setConnectTimeOut(int $connectTimeOut): static { $this->connectTimeOut = $connectTimeOut; return $this; } } telegram-bot-sdk/src/HttpClients/HttpClientInterface.php000064400000001573152665541660017373 0ustar00botsManager = $botsManager; $bot = $this->argument('bot'); $this->resolveTelegramBot($bot); $this->config = $this->botsManager->getBotConfig($bot); if ($this->option('setup')) { $this->setupWebhook(); } if ($this->option('remove')) { $this->removeWebhook(); } if ($this->option('info')) { $this->getInfo(); } } /** * Setup Webhook. * * @throws TelegramSDKException */ private function setupWebhook(): void { $this->info('Setting up webhook...'); $this->newLine(); $webhookUrl = data_get($this->config, 'webhook_url'); if (! Str::startsWith($webhookUrl, 'https://')) { $this->error('Your webhook url must start with https://'); return; } $params = ['url' => $webhookUrl]; $certificatePath = data_get($this->config, 'certificate_path', false); if ($certificatePath && $certificatePath !== 'YOUR-CERTIFICATE-PATH') { $params['certificate'] = $certificatePath; } $allowedUpdates = data_get($this->config, 'allowed_updates'); if ($allowedUpdates) { $params['allowed_updates'] = $allowedUpdates; } $response = $this->telegram->setWebhook($params); if ($response) { $this->info('Success: Your webhook has been set!'); return; } $this->error('Your webhook could not be set!'); } /** * Remove Webhook. * * @throws TelegramSDKException */ private function removeWebhook(): void { if ($this->confirm(sprintf('Are you sure you want to remove the webhook for %s?', $this->config['bot']))) { $this->info('Removing webhook...'); if ($this->telegram->removeWebhook()) { $this->info('Webhook removed successfully!'); return; } $this->error('Webhook removal failed'); } } /** * Get Webhook Info. * * @throws TelegramSDKException */ private function getInfo(): void { $this->alert('Webhook Info'); $bots = collect($this->botsManager->getConfig('bots')); if (! $this->option('all')) { $bots = $bots->only($this->config['bot']); } $bots->each(function ($bot, $botName): void { $response = $this->botsManager->bot($botName)->getWebhookInfo(); $this->makeWebhookInfoResponse($response, $botName); }); } /** * Make WebhookInfo Response for console. */ private function makeWebhookInfoResponse(WebhookInfo $response, string $bot): void { $rows = $response->map(function ($value, $key): array { $key = Str::title(str_replace('_', ' ', $key)); $value = is_bool($value) ? $this->mapBool($value) : (is_array($value) ? implode("\n", $value) : $value); return ['key' => $key, 'value' => $value]; })->toArray(); $this->table([ [new TableCell('Bot: '.$bot, ['colspan' => 2])], ['Key', 'Info'], ], $rows); } /** * Map Boolean Value to Yes/No. */ private function mapBool(bool $value): string { return $value ? 'Yes' : 'No'; } private function resolveTelegramBot(?string $bot): void { try { $this->telegram = $this->botsManager->bot($bot); } catch (TelegramBotNotFoundException $e) { $this->warn($e->getMessage()); $this->warn('You must specify a proper bot name or configure one.'); $this->newLine(); $this->info('💡Omitting the bot name will fallback to the default bot.'); exit(1); } } } telegram-bot-sdk/src/Laravel/TelegramServiceProvider.php000064400000004375152665541660017420 0ustar00configure(); $this->offerPublishing(); $this->registerBindings(); $this->registerCommands(); } /** * Setup the configuration. */ private function configure(): void { $this->mergeConfigFrom(__DIR__.'/config/telegram.php', 'telegram'); } /** * Setup the resource publishing groups. */ private function offerPublishing(): void { if ($this->app instanceof LaravelApplication && $this->app->runningInConsole()) { $this->publishes([ __DIR__.'/config/telegram.php' => config_path('telegram.php'), ], 'telegram-config'); } elseif ($this->app instanceof LumenApplication) { $this->app->configure('telegram'); } } /** * Register bindings in the container. */ private function registerBindings(): void { $this->app->singleton(BotsManager::class, static fn ($app): BotsManager => (new BotsManager(config('telegram')))->setContainer($app)); $this->app->alias(BotsManager::class, 'telegram'); $this->app->bind(Api::class, static fn ($app) => $app[BotsManager::class]->bot()); $this->app->alias(Api::class, 'telegram.bot'); } /** * Register the Artisan commands. */ private function registerCommands(): void { if ($this->app->runningInConsole()) { $this->commands([ WebhookCommand::class, ]); } } /** * Get the services provided by the provider. * * @return array */ public function provides() { return [BotsManager::class, Api::class, 'telegram', 'telegram.bot']; } } telegram-bot-sdk/src/Laravel/config/telegram.php000064400000017663152665541660015675 0ustar00 [ 'mybot' => [ 'token' => env('TELEGRAM_BOT_TOKEN', 'YOUR-BOT-TOKEN'), 'certificate_path' => env('TELEGRAM_CERTIFICATE_PATH', 'YOUR-CERTIFICATE-PATH'), 'webhook_url' => env('TELEGRAM_WEBHOOK_URL', 'YOUR-BOT-WEBHOOK-URL'), /* * @see https://core.telegram.org/bots/api#update */ 'allowed_updates' => null, 'commands' => [ // Acme\Project\Commands\MyTelegramBot\BotCommand::class ], ], // 'mySecondBot' => [ // 'token' => '123456:abc', // ], ], /* |-------------------------------------------------------------------------- | Default Bot Name |-------------------------------------------------------------------------- | | Here you may specify which of the bots you wish to use as | your default bot for regular use. | */ 'default' => 'mybot', /* |-------------------------------------------------------------------------- | Asynchronous Requests [Optional] |-------------------------------------------------------------------------- | | When set to True, All the requests would be made non-blocking (Async). | | Default: false | Possible Values: (Boolean) "true" OR "false" | */ 'async_requests' => env('TELEGRAM_ASYNC_REQUESTS', false), /* |-------------------------------------------------------------------------- | HTTP Client Handler [Optional] |-------------------------------------------------------------------------- | | If you'd like to use a custom HTTP Client Handler. | Should be an instance of \Telegram\Bot\HttpClients\HttpClientInterface | | Default: GuzzlePHP | */ 'http_client_handler' => null, /* |-------------------------------------------------------------------------- | Base Bot Url [Optional] |-------------------------------------------------------------------------- | | If you'd like to use a custom Base Bot Url. | Should be a local bot api endpoint or a proxy to the telegram api endpoint | | Default: https://api.telegram.org/bot | */ 'base_bot_url' => null, /* |-------------------------------------------------------------------------- | Resolve Injected Dependencies in commands [Optional] |-------------------------------------------------------------------------- | | Using Laravel's IoC container, we can easily type hint dependencies in | our command's constructor and have them automatically resolved for us. | | Default: true | Possible Values: (Boolean) "true" OR "false" | */ 'resolve_command_dependencies' => true, /* |-------------------------------------------------------------------------- | Register Telegram Global Commands [Optional] |-------------------------------------------------------------------------- | | If you'd like to use the SDK's built in command handler system, | You can register all the global commands here. | | Global commands will apply to all the bots in system and are always active. | | The command class should extend the \Telegram\Bot\Commands\Command class. | | Default: The SDK registers, a help command which when a user sends /help | will respond with a list of available commands and description. | */ 'commands' => [ HelpCommand::class, ], /* |-------------------------------------------------------------------------- | Command Groups [Optional] |-------------------------------------------------------------------------- | | You can organize a set of commands into groups which can later, | be re-used across all your bots. | | You can create 4 types of groups: | 1. Group using full path to command classes. | 2. Group using shared commands: Provide the key name of the shared command | and the system will automatically resolve to the appropriate command. | 3. Group using other groups of commands: You can create a group which uses other | groups of commands to bundle them into one group. | 4. You can create a group with a combination of 1, 2 and 3 all together in one group. | | Examples shown below are by the group type for you to understand each of them. */ 'command_groups' => [ /* // Group Type: 1 'commmon' => [ Acme\Project\Commands\TodoCommand::class, Acme\Project\Commands\TaskCommand::class, ], */ /* // Group Type: 2 'subscription' => [ 'start', // Shared Command Name. 'stop', // Shared Command Name. ], */ /* // Group Type: 3 'auth' => [ Acme\Project\Commands\LoginCommand::class, Acme\Project\Commands\SomeCommand::class, ], 'stats' => [ Acme\Project\Commands\UserStatsCommand::class, Acme\Project\Commands\SubscriberStatsCommand::class, Acme\Project\Commands\ReportsCommand::class, ], 'admin' => [ 'auth', // Command Group Name. 'stats' // Command Group Name. ], */ /* // Group Type: 4 'myBot' => [ 'admin', // Command Group Name. 'subscription', // Command Group Name. 'status', // Shared Command Name. 'Acme\Project\Commands\BotCommand' // Full Path to Command Class. ], */ ], /* |-------------------------------------------------------------------------- | Shared Commands [Optional] |-------------------------------------------------------------------------- | | Shared commands let you register commands that can be shared between, | one or more bots across the project. | | This will help you prevent from having to register same set of commands, | for each bot over and over again and make it easier to maintain them. | | Shared commands are not active by default, You need to use the key name to register them, | individually in a group of commands or in bot commands. | Think of this as a central storage, to register, reuse and maintain them across all bots. | */ 'shared_commands' => [ // 'start' => Acme\Project\Commands\StartCommand::class, // 'stop' => Acme\Project\Commands\StopCommand::class, // 'status' => Acme\Project\Commands\StatusCommand::class, ], ]; telegram-bot-sdk/composer.json000064400000005253152665541660012454 0ustar00{ "name": "irazasyed/telegram-bot-sdk", "description": "The Unofficial Telegram Bot API PHP SDK", "license": "BSD-3-Clause", "type": "library", "keywords": [ "telegram", "telegram bot", "telegram bot api", "telegram sdk", "telegram php", "laravel telegram", "laravel" ], "authors": [ { "name": "Irfaq Syed", "email": "github@lukonet.net", "homepage": "https://github.com/irazasyed" } ], "homepage": "https://github.com/irazasyed/telegram-bot-sdk", "require": { "php": ">=8.0", "ext-json": "*", "guzzlehttp/guzzle": "^7.5.1", "guzzlehttp/psr7": "^2.5", "illuminate/support": "9 - 12", "league/event": "^2.2 || ^3.0", "psr/container": "^1.1 || ^2.0", "psr/event-dispatcher": "^1.0" }, "require-dev": { "irazasyed/docgen": "^0.2", "pestphp/pest": "^1.22 || ^2.0 || ^3.0", "php-parallel-lint/php-parallel-lint": "^1.3", "phpspec/prophecy": "^1.17", "phpspec/prophecy-phpunit": "^2.0", "rector/rector": "^0.16.0 || ^0.17.0 || ^0.18.0 || ^0.19.0 || ^1.0.0 || ^2.0.0" }, "suggest": { "illuminate/container": "Hold dependencies to be injected in commands constructors", "irazasyed/larasupport": "Allows you to use any Laravel Package in Lumen by adding support!" }, "minimum-stability": "dev", "prefer-stable": true, "autoload": { "psr-4": { "Telegram\\Bot\\": "src/" } }, "autoload-dev": { "psr-4": { "Telegram\\Bot\\Tests\\": "tests/" } }, "config": { "allow-plugins": { "kylekatarnls/update-helper": true, "pestphp/pest-plugin": true }, "preferred-install": "dist", "sort-packages": true }, "extra": { "branch-alias": { "dev-master": "3.0-dev" }, "laravel": { "aliases": { "Telegram": "Telegram\\Bot\\Laravel\\Facades\\Telegram" }, "providers": [ "Telegram\\Bot\\Laravel\\TelegramServiceProvider" ] } }, "scripts": { "docgen": "docgen", "refactor": "rector --debug", "test": [ "@test:lint", "@test:refactor", "@test:unit" ], "test:coverage": "pest --coverage --colors=always", "test:docgen": "docgen -d", "test:lint": "parallel-lint . --blame --colors --exclude vendor", "test:refactor": "rector --dry-run", "test:unit": "pest --colors=always" } } telegram-bot-sdk/LICENSE.md000064400000002756152665541660011343 0ustar00# The BSD 3-Clause License Copyright (c) Irfaq Syed All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.