*! version 1.0.0 03apr2026

Title

telegram -- Send free push notifications (mobile alerts) and
exported figures from Stata to Telegram

Syntax

Initial configuration:

telegram setup

Send a message or figure:

telegram
["message text or caption"]
[, options]

Alias:

tg can be used interchangeably as a drop-in shortcut for telegram.

Main
token(string) Telegram Bot API token

chatid(string) Telegram Chat ID (numeric or @channel)

figure(filepath) Path to a local image file to send (e.g., .png, .jpg)

Advanced
notrimpipe Do not trim spaces around the || line-break operator

connecttimeout(#) curl connection timeout in seconds; default is 10

maxtime(#) curl total execution timeout in seconds; default is 60

retry(#) curl maximum retry attempts; default is 0

curlcmd(string) path to curl executable; default is "curl"

debug display redacted curl command and API responses

quiet suppress success output

Description

Let's be honest: staring at Stata while a massive script runs is nobody's idea
of a good time. telegram lets you walk away. It sends free push
notifications (mobile alerts) and exported graphs from Stata directly to your
smartphone (iPhone or Android) or desktop via the Telegram messenger.

Whether you are monitoring remote batch jobs or waiting for a bootstrap to
finish so you can finally pour a glass of wine (or grab another coffee), this
package is a hassle-free alternative to wrestling with SMTP email servers or
paying for premium third-party push notification apps.

Setup and Credentials: Nobody wants to paste their Bot Token and Chat ID
into every single command. Run telegram setup once. It walks you through
the setup and quietly saves your credentials in a telegram_config.txt
file inside your Stata PERSONAL directory. (Pro-tip: If you are on a
virtual desktop, ensure your PERSONAL sysdir points to a persistent
network drive).

Line Breaks: Because walls of text are terrible to read on a phone, use
the double-pipe operator || to drop in a line break. Spaces around the
pipes are automatically trimmed (unless you use the notrimpipe option).

Message Chunking: Telegram cuts off standard messages at 4,096 characters.
telegram is Unicode-aware and will automatically split longer output into
sequential chunks of 4,000 characters. This conservative limit ensures that
multi-byte characters (like complex emojis) don't cause API rejection errors
at the boundary.

Figure Captions: Use the figure() option to push charts right to
your screen so you can review results from the couch. The message text
automatically becomes the image caption (though Telegram limits captions to a
strict 1,024 characters).

Options

token(string) specifies the authentication token provided by the BotFather.
It must contain a colon. (Note: This is optional if you have completed the
telegram setup configuration).

chatid(string) specifies the recipient. This can be a personal chat ID
(e.g., 12345678), a negative group chat ID (e.g., -12345678), or a
public channel username (e.g., @my_stata_channel). (Note: This is optional
if you have completed the telegram setup configuration).

figure(filepath) specifies a local image file to upload. Supported
formats include .png, .jpg, .jpeg, .gif, .bmp, and .webp. Stata formats like
.gph or vector formats like .eps are not supported by Telegram.

notrimpipe instructs the program to preserve spaces immediately before
and after the || operator when converting it to a line break.

debug prints the exact (but redacted) curl command being sent to the OS
shell. Highly recommended for troubleshooting when firewalls or proxy servers
decide to ruin your day.

Examples

First-time configuration:

. telegram setup

Standard plain-text message:

. telegram "Data cleaning finished. I deserve a coffee."

Using the shorter alias:

. tg "Simulation completed."

Using line breaks to format a mobile alert:

. tg "Model 1 Converged || R-squared: 0.85 || Let's pretend that's causal..."

Using compound quotes to include double quotes and evaluate a macro:

. local pval = 0.042

. tg `"The "causal" effect has a p-value of `pval'"'

Sending an exported Stata graph to your phone (fully executable):

. sysuse auto, clear

. scatter price mpg

. graph export "results.png", as(png) replace

. tg "Scatter plot of Price vs. MPG", figure("results.png")

Overriding stored credentials for a specific alert:

. tg "Monte Carlo loop 1,000 complete. Pouring wine.", chatid("@lab_channel") token("987:XYZ")

Stored results

telegram stores the following in r():

Scalars

r(curl_rc) 0 if successful; standard Stata error code otherwise

r(chunks) number of message chunks or files sent

r(split_msg) 1 if a text message was split into chunks, 0 otherwise

r(orig_len) character length of the original message/caption

Macros

r(type) "text" or "figure"

r(chatid) the resolved Chat ID used for the transmission