Home API Manuals About Forum
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

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.

TMessenger Class (Internal Scripts — DWScript / PascalScript)

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 Event

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 TMessenger object but a numeric Messenger ID (see table below).

Messenger ID (External Scripts)

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 API

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

Functions

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.

Messenger Enum

class Messenger(IntEnum):
    Telegram = 1
    Viber = 2      # deprecated
    Discord = 3

The messenger parameter in all functions accepts:

  • Messenger.Telegram, Messenger.Discord — enum values
  • 1, 3 — integer IDs directly
  • "Telegram", "Discord" — string names (case-insensitive)
  • 0 — alias for Telegram (Python wrapper only)

Event Handling

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)

Example: Internal Script (DWScript / PascalScript)

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.

Example: Python

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()

Obtaining Sender / Channel IDs

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.

Notes

  • Token must be set before connecting. Setting Connected := True without 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.