The crust of this fork is the advanced_get plugin, which gives you a unix shell in Telegram, with the ability to exchange files. I’ll update the README when I have the time to document it.
Needs Python 3.7.2+.
# Install dash, zsh, tmux, grealpath (GNU realpath, on Linux you could probably use `alias grealpath=realpath`)
# Run in Zsh:
##
borgdir=~/code/betterborg/
# set this the directory containing betterborg
##
function ec {
#: `ec` should almost always be used instead of `echo`.
print -r -- "$@"
}
function ecn {
print -rn -- "$@"
}
function ecerr {
ec "$@" >&2
}
function gquote {
ec "${(qq@)@}"
}
alias gq=gquote
tmuxnew () {
tmux kill-session -t "$1" &> /dev/null
tmux new -d -s "$@"
}
function realpath2 {
test -e "$1" && grealpath -e -- "$1" || {
(( ${+commands[$1]} )) && grealpath -e -- "${commands[$1]}"
}
##
# -e, --canonicalize-existing: all components of the path must exist
##
}
##
tmuxnew betterborg_llm_chat "dash -c 'cd $(gq $borgdir) && borg_session=session_llm_chat borg_plugin_path=llm_chat_plugins borg_brish_count=1 $(gq "$(realpath2 python3)") $(gq $borgdir/stdborg.py)'"borgdir=~/code/betterborg/
# set this the directory containing betterborg
##
# IMPORTANT: needs the same functions as `llm_chat` defined, copy those function definitions here before running!
##
tmuxnew betterborg_stt "dash -c 'cd $(gq $borgdir) && borg_session=session_stt borg_plugin_path=stt_plugins borg_brish_count=1 $(gq "$(realpath2 python3)") $(gq $borgdir/stdborg.py)'"borgdir=~/code/betterborg/
# set this the directory containing betterborg
##
# IMPORTANT: needs the same functions as `llm_chat` defined, copy those function definitions here before running!
##
tmuxnew betterborg_reply_chainer "dash -c 'cd $(gq $borgdir) && borg_session=session_reply_chainer borg_plugin_path=reply_chainer_plugins borg_brish_count=1 $(gq "$(realpath2 python3)") $(gq $borgdir/stdborg.py)'"Pluggable =asyncio= Telegram userbot based on Telethon.
Simply clone the repository and run the main file:
sudo apt-get install -y coreutils fzf zsh python3 mkdir -p ~/code cd ~/code git clone 'https://github.com/NightMachinary/betterborg.git' cd betterborg pip3 install -r requirements.txt # Optional: override Telethon API credentials. export borg_api_id='...' export borg_api_hash='...' # =TELEGRAM_API_ID= / =TELEGRAM_API_HASH= also work. python3 stdborg.py
The modular design of the project enhances your Telegram experience through plugins which you can enable or disable on demand.
Each plugin gets the borg, logger and storage magical variables to ease their use. Thus creating a plugin as easy as adding a new file under the plugin directory to do the job:
# stdplugins/myplugin.py
from telethon import events
@borg.on(events.NewMessage(pattern='hi'))
async def handler(event):
await event.reply('hey')The core features offered by the custom TelegramClient live under the =uniborg/= directory, with some utilities, enhancements and the core plugin.
stdplugins/all.py adds admin-only .all=/=@all, .allf=/=@allf, and
.allIDs=/=@allIDs commands for mentioning or listing chat participants. These
commands skip Telegram bots and the Borg/userbot account itself before batching.
See docs/all.md.
llm_chat adds Telegram reaction metadata to model history when available. Reaction
history is stored by history_util; bot sessions require bot admin status in the
group and Redis for restart persistence. Set
REACTION_HISTORY_CACHE_VERBOSITY_MODE=print_each_update to debug reaction
delivery. See docs/llm_chat_reactions.md.
llm_chat appends a short instruction telling models to use injected metadata as
context, not as reply wording. See docs/llm_chat_prompting.md.
llm_chat defaults Last N Messages context to 100 messages. The effective
limit is resolved as chat override, then personal default, then the global
default. Use /contextMode, /groupContextMode, or /contextModeHere for
inline quick picks (50, 100, 200, 400, 800), or use /setLastN and
/setLastNHere for arbitrary valid values. See
docs/llm_chat_last_n_context.md.
stdplugins/history_export.py adds an admin-only .export [number-of-messages=all]
command that silently writes a Telegram Desktop-style, text-only result.json
for the current chat.
By default exports are saved below ~/tmp/.borg/chat_exports/. Set
BORG_HISTORY_EXPORT_DIR to override the root directory. Reactions include
available reactor identities. Media files are not downloaded; placeholders and
available media metadata are written instead. Progress is printed in the server
terminal, and SIGINT during an active export writes a partial export instead of
interrupting the process. Collection is newest-first for useful partial exports,
while the saved JSON remains oldest-first. See
docs/history_export.md.
stdplugins/deleter.py adds the admin-only .del N, .del s N,
.delalltext N, .delallself, and .delallselfreactions commands. The self-only
form deletes the userbot account’s own messages and selectively clears that
account’s reactions from scanned messages. The bulk text command deletes
text-only posts and conservative text-file attachments from the scanned window
except hashtag-only marker posts. Message-deleting commands export deleted text
to ~/tmp/tlg-deleter/ with a durable WIP JSONL plus final result.json. The
bulk self-delete command clears all of the account’s reactions before deleting
all of its messages; the reaction-only bulk command is available separately. See
docs/deleter.md.
llm_chat can expose openai-codex/gpt-5.6-sol and openai-codex/gpt-6-astra
as access-controlled chat models using the published llm-openai-via-codex
package and local Codex OAuth credentials. Access is configured in
~/.borg/llm_chat_config.json5 (or LLM_CHAT_CONFIG_PATH) using numeric
Telegram user IDs and the optional MAGIC_ADMINS sentinel. See
docs/codex_models.md and
docs/codex_caching.md.
The codex_users roster stores names and separate Codex/image access flags.
Bot admins can use .codex-users to toggle those grants and manage personal
default models and per-model reasoning effort. Its compact overview omits
unknown Telegram profile/contact fields and shows configured personal API-key
provider names without exposing key values.
Known private contact appears as Started. Pages contain at most eight users
and split earlier when needed to stay within Telegram’s message limit.
The detail panel separates configured labels from Telegram identity and lists
personal API-key providers with their last-set UTC times. Historical keys show
an unknown date. For older contacts missing from local metadata, opening the
panel can recover positive Started evidence from the bot’s private-dialog list
without sending anything; an absent or unavailable dialog remains unknown.
Use Add user, then Choose user in a private chat to select someone in
Telegram and confirm their identity. Numeric ID and @username entry also work.
Phone-number lookup requires a Telegram user account and is not supported by
the bot. New users start with Codex and images off; their saved model is preserved.
In groups, reply to the add-user prompt. Roster controls require the caller to
be a bot admin, independently of trusted-chat model grants.
Disabled users remain listed; configured trusted-chat access
still applies. Use .codex-users <user-id> <model-id> to set a default
immediately. If Codex is unavailable, ordinary messages fall back to Gemini
Flash with a notice, preserving the saved default.
When the shared account’s allowance runs out, requests are retried
automatically on the Luna Reserve, reached through the gpt-reserve routing
slug rather than gpt-5.6-luna, and also selectable with .cr / .چر. If the
Reserve is spent too, /codexStatus reports the account’s live meters and can
park a user’s saved default on another provider until the window resets. See
docs/codex_luna_reserve.md and
docs/codex_quota_fallback.md.
Codex quick prefixes have matching Persian aliases: .چ* for GPT-5.6 Sol and
.اس* for GPT-6 Astra; see the complete mapping.
Use .i on the current message to enable Codex image generation, for example
.i .cl draw a fox. Both access policies must allow the sender. Previews and
final images are sent separately, alongside any text response; the switch does
not persist. See Codex image generation.
The Pioneer backend is still wired up but its models and prefixes are commented out, so they no longer appear in the chat model menus. See docs/pioneer.md.
Check out the already-mentioned plugins directory to learn how to write your own, and consider reading Telethon’s documentation.