Messengers (Telegram, Discord)
Stealth provides built-in integration with messenger bots, allowing scripts to send and receive messages through Telegram and Discord.
Viber support is deprecated. The Ngrok dependency required for Viber webhooks has been removed. Viber-related API calls may still be present but are non-functional. New scripts should use Telegram or Discord only.
Internal scripts (DWScript and PascalScript) expose messenger functionality through the TMessenger class:
TMessenger = class
public
procedure SendMessage(Msg, UserID: String); virtual;
property MessengerName: string read GetMessengerName;
property Connected: Boolean read fConnected write SetConnected default False;
property Token: String read GetToken write SetToken;
end;
Two global variables are available:
TelegramMessenger : TMessenger;
DiscordMessenger : TMessenger;
You can inspect these objects at runtime using the debugger in the Editor window.
The Token property must be set before setting Connected := True. See Bot Registration for instructions on obtaining bot tokens.
For Discord, the UserID parameter in SendMessage accepts either a channel ID or a user ID for direct messages, depending on the bot’s permissions.
Messenger events are delivered through evMessengerEvent. The callback signature for internal scripts:
procedure Handler(
Sender: TMessenger;
SenderNickName: String;
SenderId, ChatId: String;
EventMsg: String;
EventCode: Byte
);
EventCode values:
| EventCode | Meaning |
|---|---|
| 0 | Connected |
| 1 | Disconnected |
| 2 | Incoming message |
| 3 | Error (details in EventMsg) |
External scripts (Python): The first callback parameter is not a
TMessengerobject but a numeric Messenger ID (see table below).
External scripts identify messengers by numeric ID:
| ID | Messenger |
|---|---|
| 1 | Telegram |
| 2 | Viber (deprecated) |
| 3 | Discord |
The Python wrapper py_astealth also accepts 0 as an alias for Telegram (fallback in the Python layer only, not in Stealth itself).
Python scripts use standalone functions instead of object properties. All functions accept the messenger parameter as a Messenger enum value, an int ID, or a str name (case-insensitive).
from py_astealth.stealth_enums import Messenger, EventType
MessengerSetToken(messenger, token: str) → None
Sets the bot authentication token. Must be called before connecting.
MessengerGetToken(messenger) → str
Returns the current token for the specified messenger.
MessengerSetConnected(messenger, value: bool) → None
Connects (True) or disconnects (False) the messenger bot.
MessengerGetConnected(messenger) → bool
Returns True if the messenger bot is currently connected.
MessengerGetName(messenger) → str
Returns the messenger name string (e.g. "Telegram", "Discord").
MessengerSendMessage(messenger, msg: str, user_id: str) → None
Sends a message. For Discord, user_id is a channel ID or user ID depending on bot permissions.
class Messenger(IntEnum):
Telegram = 1
Viber = 2 # deprecated
Discord = 3
The messenger parameter in all functions accepts:
Messenger.Telegram,Messenger.Discord— enum values1,3— integer IDs directly"Telegram","Discord"— string names (case-insensitive)0— alias for Telegram (Python wrapper only)
from py_astealth.stealth_enums import EventType
def messenger_handler(mes_id, sender_nickname, sender_id, chat_id, event_msg, event_code):
if event_code == 0:
AddToSystemJournal(f'Connected (ID={mes_id})')
elif event_code == 1:
AddToSystemJournal(f'Disconnected (ID={mes_id})')
elif event_code == 2:
AddToSystemJournal(f'Message from "{sender_nickname}" '
f'(SenderID: {sender_id}, ChatID: {chat_id}): {event_msg}')
elif event_code == 3:
AddToSystemJournal(f'Error: {event_msg}')
SetEventProc(EventType.EvMessengerEvent, messenger_handler)
Program MessengerDemo;
procedure MessengerEventHandler(Sender: TMessenger; SenderNickName: String;
SenderId, ChatId: String; EventMsg: String; EventCode: Byte);
begin
case EventCode of
0: AddToSystemJournal(Sender.MessengerName + ' Connected');
1: AddToSystemJournal(Sender.MessengerName + ' Disconnected');
2: AddToSystemJournal(Sender.MessengerName + ' Message from "' +
SenderNickName + '" (SenderId: ' + SenderId +
', ChatId: ' + ChatId + '): ' + EventMsg);
3: AddToSystemJournal(Sender.MessengerName + ' Error: ' + EventMsg);
end;
end;
begin
SetEventProc(evMessengerEvent, 'MessengerEventHandler');
if not TelegramMessenger.Connected then
begin
TelegramMessenger.Token := 'your_token_here';
TelegramMessenger.Connected := True;
end;
TelegramMessenger.SendMessage('Hello from Stealth!', 'receiver_id_here');
if not DiscordMessenger.Connected then
begin
DiscordMessenger.Token := 'your_token_here';
DiscordMessenger.Connected := True;
end;
DiscordMessenger.SendMessage('Hello from Stealth!', 'channel_id_here');
while True do
Wait(200);
end.
from py_astealth.stealth_enums import Messenger, EventType
def on_messenger_event(mes_id, sender_nickname, sender_id, chat_id, event_msg, event_code):
names = {1: 'Telegram', 3: 'Discord'}
name = names.get(mes_id, f'Unknown({mes_id})')
if event_code == 0:
AddToSystemJournal(f'{name} Connected')
elif event_code == 1:
AddToSystemJournal(f'{name} Disconnected')
elif event_code == 2:
AddToSystemJournal(f'{name} Message from "{sender_nickname}" '
f'(SenderID: {sender_id}, ChatID: {chat_id}): {event_msg}')
# Echo back
MessengerSendMessage(mes_id, f'Echo: {event_msg}', sender_id)
elif event_code == 3:
AddToSystemJournal(f'{name} Error: {event_msg}')
def main():
SetEventProc(EventType.EvMessengerEvent, on_messenger_event)
# Telegram
MessengerSetToken(Messenger.Telegram, 'your_token_here')
MessengerSetConnected(Messenger.Telegram, True)
# Discord
MessengerSetToken(Messenger.Discord, 'your_token_here')
MessengerSetConnected(Messenger.Discord, True)
MessengerSendMessage(Messenger.Telegram, 'Hello from Stealth!', 'receiver_id_here')
MessengerSendMessage(Messenger.Discord, 'Hello from Stealth!', 'channel_id_here')
while True:
Wait(200)
if __name__ == '__main__':
main()
To get a user’s sender ID: send any message from that user to your bot while a script with the event handler is running. The system journal will log the SenderId value. For example:
17:27:37:759 [Test]: Telegram Message from "Vizit0r" (SenderId: 435486649): testtest
For Discord, incoming messages also include the ChatId (channel ID). Both SenderId and ChatId can be used as the recipient in SendMessage, depending on whether you want to reply to the channel or send a direct message.
Tokenmust be set before connecting. SettingConnected := Truewithout a token will result in an error event (EventCode 3).- Messenger connections persist for the lifetime of the script. If the script stops, the bot disconnects.
- Rate limits are enforced by the messenger platforms themselves (Telegram, Discord). Stealth does not add additional throttling.
- If the bot loses connection, an EventCode 1 (Disconnected) event is fired. Reconnection must be handled manually in the script.
- Discord bots require the Message Content intent enabled in the Discord Developer Portal for receiving message text.