Quick start: from zero to running, no steps skipped
Just follow along โ about 15 minutes total. Every step tells you which screen to open and what to tap, plus the pitfalls people actually hit.
๐งพ Checklist
- Telegram Premium โ the Telegram Business features LingoDesk relies on (message relay to a bot) are Premium-only. Without Premium none of this works.
- Node.js 20 or newer โ run
node -v in a terminal to check; install the LTS from nodejs.org if missing.
- Anthropic API key โ the translation engine. Step 4 shows how to get one; an optional OpenAI key adds a fallback.
- The LingoDesk code โ free and open source on GitHub; Step 4b clones it.
- An always-on computer โ the bot process must keep running to receive and send (you can move it to a server later).
1Create your bot in BotFather
In Telegram, search for @BotFather (look for the blue verification badge) and have this conversation:
๐ค BotFather
/newbot
BotFatherAlright, a new bot. How are we going to call it? Please choose a name for your bot.
LingoDesk Assistant
BotFatherGood. Now let's choose a username for your bot. It must end in bot.
my_lingodesk_bot
BotFatherDone! Use this token to access the HTTP API:
8123456789:AAHfK3xxxxxxxxxxxxxxxxxxxxxxxxx
Keep your token secure and store it safelyโฆ
- The "name" is just a display name; the "username" must be globally unique and end in
bot โ if taken, try another.
- That
digits:letters string in the last reply is your BOT_TOKEN. Copy it somewhere safe. It is effectively the bot's password โ never share it.
1a. Turn on Business Mode (required)
Still inside BotFather:
/mybotsโ
@my_lingodesk_botโ
Bot Settingsโ
Business Modeโ
Turn on
Without Business Mode your bot won't even show up in the Telegram Business chatbot list in Step 2. This is the single most common blocker.
1b. Turn off Group Privacy (required)
/mybotsโ
@my_lingodesk_botโ
Bot Settingsโ
Group Privacyโ
Turn off
Privacy is on by default, and while it's on the bot cannot see the replies you type in your console group โ the symptom is "I type in the topic and nothing happens". Turn it off (BotFather must say Privacy mode is disabled).
2Link the bot in Telegram Business
On the mobile Telegram app (this setting currently exists only on mobile):
โ๏ธ Settingsโ
๐ผ Telegram Businessโ
๐ค Chatbots
- Type your bot's username (e.g.
my_lingodesk_bot) in the search box and select it.
- Permissions: enable "Reply to messages" โ without it the bot can read but can never send on your behalf.
- For "which chats", choose All 1:1 Chats; add any private contacts you want to keep out of the relay to the Excluded Chats list.
Once linked, every private message you receive is silently "cc'd" to the bot โ the other side notices nothing, and your own chat experience doesn't change at all.
3Create your console forum group
This group is your workbench: one topic per contact, with bilingual message cards popping up inside.
- Create a group: New โ New Group, add your bot as the only member (search its username). Name it anything, e.g. "LingoDesk Console".
- Enable Topics: open the group โ tap the name for its profile โ Edit โ toggle Topics on. The group upgrades to a supergroup and gets a topic list.
- Promote the bot to admin: profile โ Administrators โ Add Admin โ your bot โ check "Manage Topics" (leave the rest default) โ save.
The bot creates a topic automatically for each contact. Without admin rights + "Manage Topics" that fails โ the symptom is "a customer wrote to me but nothing appears in the group".
The group only needs you and the bot โ no other humans. If you add a partner, their replies in a topic trigger translation and sending just like yours.
4Get the three IDs & keys
4a. ANTHROPIC_API_KEY (the translation engine)
- Open
console.anthropic.com and sign up / sign in.
- Sidebar API Keys โ Create Key โ copy the
sk-ant-โฆ string (shown only once โ store it).
- Add a few dollars under Billing โ the default Haiku model costs roughly $0.001 per translated message, so a few dollars lasts a long time.
4b. First contact with the code: install deps + set BOT_TOKEN
In a terminal, inside the LingoDesk folder:
git clone https://github.com/sanxiaozi/lingodesk.git
cd lingodesk
npm install
cp .env.example .env
Open .env in any editor and fill in just one line for now: BOT_TOKEN=the token from Step 1. Save.
4c. FORUM_CHAT_ID and OWNER_USER_ID: one command
- Post anything (e.g. "test") in your console group.
- From your own account, open a private chat with the bot (search its username) and send
/start.
- Back in the terminal:
npm run ids
โโ Chats (the supergroup row starting with -100 = FORUM_CHAT_ID) โโ
-1002345678901 supergroup ยท LingoDesk Console
โโ Users (your own row = OWNER_USER_ID) โโ
712345678 Jason @your_username
The two highlighted numbers are the values you need. If the output says "(empty)", those two messages haven't been sent yet โ send them and rerun. If you get a 409, the bot is currently running โ stop it first.
5Fill in .env
Complete your .env (all other lines can stay at their defaults):
# The four required values
BOT_TOKEN=8123456789:AAHfK3xxxxxxxxxxxxxxxxxxxxxxxxx
FORUM_CHAT_ID=-1002345678901
OWNER_USER_ID=712345678
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxx
# Optional: OpenAI fallback (auto-switches if Claude has an outage โ recommended)
OPENAI_API_KEY=sk-xxxxxxxx
FORUM_CHAT_ID is negative โ copy the whole string including the -100 prefix.
OWNER_USER_ID is not optional in practice: it's how the bot tells "the customer wrote this" from "I replied manually myself". Leave it empty and your own manual replies get treated as customer messages.
6Launch
npm run db:push
๐ Your database is now in sync with your Prisma schema.
npm run dev
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ LingoDesk is up, bot = @my_lingodesk_bot
Receive โ translate โ reply โ translate relay:
ยท Customers DM your personal account โ auto-translated card in your console topic
ยท You type in a topic โ preview โ sent in their language, as you
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
That banner means it's alive. db:push initializes the local database on first run โ you won't need it again.
One bot token = one running instance, globally. A 409 Conflict means another process is still holding it (e.g. a previous run that never exited) โ stop everything, then start again.
7Test chat
From a different Telegram account (a second account or a friend), send a foreign-language DM to your personal account (not to the bot!) โ say, "Hola, ยฟcuรกnto cuesta?" in Spanish. Within seconds, a new topic named after the sender should appear in your console group:
๐ LingoDesk Console ยท topic: @amigo_es
my_lingodesk_bot๐ New contact @amigo_es (es)
Original: Hola, ยฟcuรกnto cuesta?
๐ Hi, how much does it cost?
โโโโโ
โณ Type here in your language โ it goes out in es, sent as you
Package A is $100 and includes all features.
my_lingodesk_bot๐ค Translation preview (โes), sent only after you confirm:
El paquete A cuesta 100 dรณlares e incluye todas las funciones.
(Your message: Package A is $100โฆ)
[ โ
Send to customer ] [ โ๏ธ Cancel ]
Tap "โ
Send to customer" โ the other side sees your personal account replying in fluent Spanish. The whole loop is now live ๐
- Photos, files and voice messages they send are forwarded into the topic and archived automatically.
- Wrong language detected? Send
/lang es in the topic to correct it; /help lists all commands.
- Replying manually from your phone is fine too โ the bot records it into the topic archive.
๐ง Troubleshooting
A customer wrote to me but nothing appears in the console group
Check in order: โ BotFather โ Business Mode is turned on (Step 1a); โก Telegram Business โ Chatbots has your bot linked and that chat is within scope (Step 2); โข the bot is a group admin with "Manage Topics" (Step 3); โฃ the bot process is still running in your terminal without errors.
I type in a topic and the bot does nothing
Nine times out of ten it's Group Privacy still on (Step 1b). BotFather โ Bot Settings โ Group Privacy โ Turn off, then remove the bot from the group and re-add it (the change only applies after rejoining), and promote it to admin again.
Startup fails with 409 Conflict
Two instances are running on the same token. Find and stop the old process (Ctrl+C or pkill -f "tsx.*main.ts"), wait ten seconds, start again.
"Send to customer" fails: contact inactive too long
A Telegram restriction: if a conversation has been idle too long, the bot can't initiate on your behalf (BUSINESS_PEER_USAGE_MISSING). Ask them to send anything to reactivate, or reply manually from your phone this once.
Send fails: business connection invalid
Go to Settings โ Telegram Business โ Chatbots, remove and re-add the bot โ or simply wait for the customer's next message, which lets the bot capture a fresh connection automatically.
Wrong language detected / want a different target language
The language locks on the contact's first message (to avoid flip-flopping on short texts). Send /lang code in that contact's topic to correct it, e.g. /lang pt (Portuguese) or /lang ar (Arabic).
After a restart, old "Send / Cancel" buttons stopped working
Pending previews live in memory and expire on restart (the button will tell you). Just type your reply again in the topic. Contacts and chat history live in the database โ nothing is lost.
๐ All working?
From now on, customers write in whatever language they like โ you just type in yours. If something breaks, run through the troubleshooting list above first; still stuck, email us with a screenshot of the terminal error.
โ๏ธ hello@lingodesk.org