DiscordPHP-BridgeBot Documentation

TelegramGateway
in package

FinalYes

Owns the Telegram side of the bridge: the update subscription, and a paced outbound queue.

There is nothing here corresponding to an IRC JOIN — Telegram pushes updates for every chat the bot is a member of, whether or not the bridge is interested — so membership is Telegram's business and filtering is TelegramConnector's. What this class owns is pacing: every outbound message passes a per-chat bucket and a global one, because Telegram's limits are per-chat and per-bot at the same time and a burst that respects only one of them still earns a 429.

TelegramPHP honours a 429's retry_after itself, so this is about not earning one: a bot that keeps hitting the limit is throttled harder.

Tags
author

Valithor Obsidion valithor@valgorithms.com

Table of Contents

Constants

GLOBAL  : mixed = 25
And across every chat: about 30 a second.
GLOBAL_SECONDS  : mixed = 1.0
MAX_QUEUE  : mixed = 200
How much may wait. A busy Discord channel can outrun a group's twenty a minute indefinitely, and a backlog that is still playing out an hour later is worse than a gap.
PER_CHAT  : mixed = 18
Telegram's limit in a group: 20 messages a minute. Kept a little under.
PER_CHAT_SECONDS  : mixed = 60.0

Properties

$clock  : callable(): float|null
$draining  : bool
$dropped  : int
How many messages were dropped since the backlog last cleared.
$global  : RateLimiter
$limiters  : array<string, RateLimiter>
$logger  : LoggerInterface
$loop  : LoopInterface
$onEdit  : callable(Message): void|null
$onMessage  : callable(Message): void|null
$queue  : array<int, Deferred}>
$telegram  : Telegram

Methods

__construct()  : mixed
edit()  : PromiseInterface<string|int, mixed>
Rewrites a message the bot sent. Paced like a send, because Telegram counts it like one.
listen()  : void
Starts listening.
onEdit()  : void
Registers the handler for edits to messages already seen.
onMessage()  : void
Registers the handler for inbound Telegram messages.
queued()  : int
How many messages are waiting, for logging and health checks.
send()  : PromiseInterface<string|int, Message>
Queues an HTML message for a Telegram chat.
sendAnimation()  : PromiseInterface<string|int, Message>
Queues a GIF, by URL, as an animation.
sendPhoto()  : PromiseInterface<string|int, Message>
Queues a photo, by URL — Telegram fetches it itself.
dispatch()  : void
Sends one item and settles its promise, however the send fails.
drain()  : void
Sends whatever the budgets allow, then re-arms a timer for the rest.
enqueue()  : PromiseInterface<string|int, mixed>

Constants

GLOBAL

And across every chat: about 30 a second.

public mixed GLOBAL = 25

MAX_QUEUE

How much may wait. A busy Discord channel can outrun a group's twenty a minute indefinitely, and a backlog that is still playing out an hour later is worse than a gap.

public mixed MAX_QUEUE = 200

Properties

$dropped

How many messages were dropped since the backlog last cleared.

private int $dropped = 0

Methods

__construct()

public __construct(Telegram $telegram, LoopInterface $loop, LoggerInterface $logger[, callable(): float|null $clock = null ]) : mixed
Parameters
$telegram : Telegram
$loop : LoopInterface
$logger : LoggerInterface
$clock : callable(): float|null = null

For tests; defaults to the wall clock.

edit()

Rewrites a message the bot sent. Paced like a send, because Telegram counts it like one.

public edit(int|string $chatId, int $messageId, string $html[, bool $caption = false ]) : PromiseInterface<string|int, mixed>
Parameters
$chatId : int|string
$messageId : int
$html : string
$caption : bool = false

Whether the message is a photo, whose text is its caption.

Return values
PromiseInterface<string|int, mixed>

listen()

Starts listening.

public listen() : void

Channel posts are relayed alongside group messages: to a reader in Discord the difference between someone talking in a group and a channel publishing a post is not interesting, and a bridge that silently ignored one of them would look broken.

A bot does not receive its own sends as updates, but the identity check is made anyway — two instances of this bridge pointed at one bot token would otherwise relay each other's output back and forth forever.

onEdit()

Registers the handler for edits to messages already seen.

public onEdit(callable $handler) : void
Parameters
$handler : callable

onMessage()

Registers the handler for inbound Telegram messages.

public onMessage(callable $handler) : void
Parameters
$handler : callable

queued()

How many messages are waiting, for logging and health checks.

public queued() : int
Return values
int

send()

Queues an HTML message for a Telegram chat.

public send(int|string $chatId, string $html[, array{reply_to?: int|string|null, silent?: bool} $options = [] ]) : PromiseInterface<string|int, Message>

Never sends around the budgets, even when they are full and the queue is empty: the ordering guarantee is what keeps a busy channel's messages arriving in the order they were typed.

Parameters
$chatId : int|string
$html : string
$options : array{reply_to?: int|string|null, silent?: bool} = []
Return values
PromiseInterface<string|int, Message> —

resolves when Telegram accepts it

sendAnimation()

Queues a GIF, by URL, as an animation.

public sendAnimation(int|string $chatId, string $url[, string|null $caption = null ]) : PromiseInterface<string|int, Message>

Not through sendPhoto(): Telegram turns a GIF sent as a photo into a still of its first frame. Paced and captioned the same way.

Parameters
$chatId : int|string
$url : string
$caption : string|null = null
Return values
PromiseInterface<string|int, Message>

sendPhoto()

Queues a photo, by URL — Telegram fetches it itself.

public sendPhoto(int|string $chatId, string $url[, string|null $caption = null ]) : PromiseInterface<string|int, Message>

Discord's CDN links are public for long enough for that, so handing Telegram the URL avoids pulling several megabytes through this process only to push them straight back out.

Parameters
$chatId : int|string
$url : string
$caption : string|null = null
Return values
PromiseInterface<string|int, Message>

dispatch()

Sends one item and settles its promise, however the send fails.

private dispatch(Deferred} $item) : void

A send that throws before it has a promise — a bad argument, say — must still settle, or the caller waits forever.

Parameters
$item : Deferred}

drain()

Sends whatever the budgets allow, then re-arms a timer for the rest.

private drain() : void

A chat that is out of tokens is skipped rather than blocking the queue behind it, so one busy bridge cannot stall every other one. The global bucket is the exception: when that is empty nothing can go anywhere, so the loop stops immediately and keeps the remaining order intact.

enqueue()

private enqueue(string $chatId, callable(): PromiseInterface $send) : PromiseInterface<string|int, mixed>
Parameters
$chatId : string
$send : callable(): PromiseInterface
Return values
PromiseInterface<string|int, mixed>
On this page

Search results