telegramR is an R client for Telegram's MTProto API. It is intended as an R alternative to Python's Telethon and focuses on full-client functionality (not the Bot API).
Install
From CRAN:
install.packages("telegramR")
From GitHub (development version):
# install.packages("remotes")
# remotes::install_github("RomanKyrychenko/telegramR")
install.packages("telegramR", repos = c('https://romankyrychenko.r-universe.dev', 'https://cloud.r-project.org'))
Prerequisites
You need Telegram API credentials from my.telegram.org:
api_idapi_hashQuick Start (Login)
library(telegramR)
api_id <- 123456
api_hash <- "0123456789abcdef0123456789abcdef"
# Create a client. The session file stores your auth key so you
# don't need to re-login every time.
client <- TelegramClient$new(
session = "my_session",
api_id = api_id,
api_hash = api_hash
)
# Connect and log in interactively.
# You will be prompted for your phone number, the login code Telegram
# sends you, and (if enabled) your 2FA password.
client$start()
You can also supply the phone number and a code callback explicitly:
client$start(
phone = "+15551234567",
code_callback = function() readline("Enter the code: ")
)
If your account has 2FA enabled, pass password:
client$start(
phone = "+15551234567",
password = "my2FApassword"
)
Step-by-step login (non-interactive)
If you prefer full control over each step:
client <- TelegramClient$new("my_session", api_id = api_id, api_hash = api_hash)
client$connect()
# Request a login code
client$send_code_request("+15551234567")
# Sign in with the code you received
client$sign_in("+15551234567", code = "12345")
Download messages from a channel
Use high‑level helpers to fetch channel data as tibbles:
library(telegramR)
msgs <- download_channel_messages(
client,
"telegram",
limit = 200
)
msgs
The result contains a compact schema:
message_id, date, text
views, forwards, replies
reactions_total, reactions_json
media_type, is_forward, forward_from_id, forward_from_message_id, forward_saved_from_message_id, forward_from_name
reply_to_msg_id, edit_date, post_author
channel_id, channel_username, channel_title
You can also fetch channel info:
info <- download_channel_info(client, "telegram")
info
Filter by date range:
msgs <- download_channel_messages(
client,
"telegram",
start_date = "2025-01-01",
end_date = "2025-02-01",
limit = Inf
)
And get an approximate post count (upper bound) without downloading everything:
estimate_channel_post_count(client, "telegram")
Reactions, replies, and members
reactions <- download_channel_reactions(client, "telegram", limit = 500)
replies <- download_channel_replies(client, "telegram", message_limit = 50)
members <- download_channel_members(client, "telegram", limit = 1000)
media <- download_channel_media(client, "telegram", limit = 200, out_dir = "downloads")
All helpers accept a numeric channel id when it is available in your session cache:
msgs_by_id <- download_channel_messages(client, 1234567890, limit = 100)
Download media
dir.create("downloads", showWarnings = FALSE)
media <- download_channel_media(
client,
"telegram",
limit = 200,
media_types = c("photo", "video"),
start_date = "2025-01-01",
end_date = "2025-02-01",
out_dir = "downloads"
)
head(media)
You can also download directly from raw messages:
for (m in messages) {
if (!is.null(m$media)) {
future::value(client$download_media(m, file = "downloads/"))
}
}
Notes
TelegramClient$new().
Remove that file to force a fresh login.Sys.sleep() between requests.get_entity, download_media) return
future objects. Unwrap
them with future::value().options(telegramR.verbose = TRUE) (default), FALSE (silent) or "debug"
(adds low-level connection details). It is emitted as R messages, so
suppressMessages() also works. show_progress = FALSE turns off the
progress bar and summary of a single download call.options(telegramR.debug_pump = FALSE, telegramR.debug_process = FALSE, telegramR.debug_parse = FALSE).options(telegramR.trace_hang = TRUE, telegramR.trace_parse = TRUE) to see step-by-step parsing and network waits.image/* MIME types. download_channel_media() treats image as a photo-type alias when photo is requested.download_channel_messages(), download_channel_reactions() and
download_channel_replies() decode messages as lightweight lists, which is
several times faster than full objects. Set
options(telegramR.lite_messages = FALSE) to get full objects everywhere.
These messages are decoded by compiled code; options(telegramR.fast_decode = FALSE)
switches back to the (identical, slower) R decoder.telegramR_parse_warning, and a
page of channel messages is marked incomplete. Silence these warnings with
options(telegramR.parse_warnings = FALSE).Citation
In R, use:
citation("telegramR")
GitHub and reference managers can also read the repository's CITATION.cff.