Dành cho lập trình viên

Tạo bot cho Lumora

Bot là một tài khoản Lumora do đoạn mã của bạn điều khiển, giống bot trên Telegram. Không cần thuê máy chủ, không tốn phí: bot chạy ngay trên máy tính của bạn.

Bắt đầu trong 3 bước Tài liệu API

  1. 1

    Tạo bot với BotFather

    Mở Lumora, tìm và trò chuyện với @BotFather, gửi /newbot. Đặt tên và @tên cho bot (phải kết thúc bằng "bot", ví dụ @hoamai_bot). BotFather sẽ gửi cho bạn một token.

  2. 2

    Tải Bot Runner và SDK

    Lumora Bot Runner là chương trình nhỏ giúp đoạn mã bot kết nối vào Lumora. SDK là một tệp mã duy nhất cho Python hoặc JavaScript.

  3. 3

    Dán token và chạy

    Đặt token vào biến môi trường LUMORA_BOT_TOKEN (khuyên dùng) hoặc truyền thẳng vào Bot. Có token thì không cần đặt tên: tên và @tên lấy từ BotFather.

bot.py

from lumora_bot import Bot

# Khuyên dùng: đặt token vào biến môi trường LUMORA_BOT_TOKEN, mã nguồn không chứa bí mật
bot = Bot()

# Hoặc truyền trực tiếp (đừng đưa tệp này lên mạng):
# bot = Bot(token="lumora_bot_...")

@bot.command("start", "Bắt đầu")
def start(ctx):
    ctx.reply("Xin chào! Mình là bot của bạn.")

bot.run()

bot.mjs

import { Bot } from "./lumora-bot.mjs";

// token lấy từ biến môi trường LUMORA_BOT_TOKEN (khuyên dùng)
const bot = new Bot({ token: process.env.LUMORA_BOT_TOKEN });

bot.command("start", "Bắt đầu", (ctx) => ctx.reply("Xin chào! Mình là bot của bạn."));

await bot.run();

Linux / macOS

# Linux / macOS: cấp quyền chạy cho Bot Runner (một lần)
chmod +x lumora-bot-runner-linux-x86_64

export LUMORA_BOT_TOKEN="lumora_bot_..."      # token từ BotFather
export LUMORAD=./lumora-bot-runner-linux-x86_64            # nơi đặt Bot Runner
python3 bot.py                                # hoặc: node bot.mjs

Windows (Command Prompt)

REM Windows: đặt lumora-bot-runner-windows-x86_64.exe cùng thư mục với bot
set LUMORA_BOT_TOKEN=lumora_bot_...
set LUMORAD=lumora-bot-runner-windows-x86_64.exe
python bot.py

Giữ token bí mật

Ai có token là điều khiển được bot của bạn. Đừng đưa token vào mã nguồn công khai hay gửi cho người khác. Nếu lỡ lộ, hãy thu hồi và tạo token mới trong BotFather: @tên của bot vẫn giữ nguyên, người dùng không bị ảnh hưởng.

Lumora Bot Runner là gì?

Chương trình nhỏ chạy trên máy tính của bạn, giúp đoạn mã bot kết nối vào Lumora. Cài một lần; bot chạy khi máy bật.

Windows

  1. Tải tệp .exe của Bot Runner.
  2. Đặt tệp vào cùng thư mục với đoạn mã bot.
  3. Đặt LUMORAD trỏ tới tệp đó rồi chạy bot.

Linux

  1. Tải Bot Runner cho Linux.
  2. Cấp quyền chạy: chmod +x tên-tệp.
  3. Đặt LUMORAD trỏ tới tệp đó rồi chạy bot.

macOS

  1. Tải Bot Runner cho macOS.
  2. Cấp quyền chạy: chmod +x tên-tệp. Lần đầu, mở bằng chuột phải → Mở.
  3. Đặt LUMORAD trỏ tới tệp đó rồi chạy bot.

Tài nguyên

  1. ≈ 30 MB RAM cho mỗi bot
  2. Gần 0% CPU khi rảnh
  3. Không tạo thêm tải cho máy người dùng

Để bot chạy 24/7

Máy luôn bậtMột máy tính ở nhà hay ở cửa hàng luôn bật là đủ cho hầu hết bot.
Máy chủ thuê giá rẻMột máy chủ ảo cấu hình thấp nhất đã đủ chạy nhiều bot cùng lúc.
Raspberry PiMáy tính nhỏ, ít điện, chạy cả ngày lẫn đêm. Dùng bản Linux tương ứng.
Tôi có cần máy chủ không?

Không bắt buộc. Bot chạy trên bất kỳ máy tính nào có Bot Runner. Bạn chỉ cần một máy luôn bật nếu muốn bot trả lời cả ngày; đó có thể là máy ở nhà, một máy chủ thuê giá rẻ hoặc Raspberry Pi.

Tắt máy thì bot có chạy không?

Không. Khi máy tắt, bot tạm ngừng; bật lại là bot hoạt động tiếp với cùng @tên và danh sách người dùng.

Một máy chạy được bao nhiêu bot?

Mỗi bot dùng khoảng 30 MB RAM, nên một máy tính thông thường chạy được hàng chục bot cùng lúc.

Quy tắc cho bot

  • Bot chỉ nhắn được cho người đã bắt đầu trò chuyện với bot.
  • Trong nhóm, bot chỉ nhận lệnh, tin nhắc @tên của bot và tin trả lời bot, trừ khi quản trị viên nhóm cho phép "đọc mọi tin".
  • @tên của bot luôn kết thúc bằng "bot", ví dụ @hoamai_bot.
  • SDK tự giãn tốc độ gửi tin (kể cả khi gửi hàng loạt) để tin nhắn của bot không bị chặn như tin rác.

Bot cho từng mục đích

Các đoạn mã ngắn dưới đây chỉ dùng API có sẵn trong SDK. Ghép vào bot của bạn rồi chạy.

Bot bán hàng

Hiện thực đơn bằng nút bấm, nhận đơn và lưu lại bằng bot.storage.

@bot.command("menu", "Xem thực đơn")
def menu(ctx):
    ctx.reply("Hôm nay có gì?", buttons=[[("☕ Cà phê 25k", "cafe"), ("🧋 Trà sữa 30k", "trasua")]])

@bot.on_callback
def order(ctx):
    orders = bot.storage.get("orders", [])
    orders.append({"who": ctx.sender, "item": ctx.data})
    bot.storage["orders"] = orders          # tự lưu vào tệp
    ctx.reply("Đã nhận đơn! Cửa hàng sẽ liên hệ bạn sớm.")

Bot nhắc lịch & thông báo

Gửi thông báo cho mọi người đã dùng bot. Chỉ admin mới gọi được lệnh này; tốc độ gửi được tự điều chỉnh.

bot = Bot(admins=["@chu_shop·k7q2xz"])   # @tên·mã của chủ bot

@bot.command("thongbao", "Gửi thông báo cho mọi người", admin_only=True)
def announce(ctx):
    sent = bot.broadcast(ctx.args or "Hôm nay cửa hàng mở cửa muộn 30 phút.")
    ctx.reply(f"Đã gửi cho {sent} người.")

Bot quản lý nhóm

Lệnh chỉ dành cho admin, cấp vai trò mod và lệnh theo vai trò. Lệnh admin được ẩn khỏi menu lệnh.

@bot.command("addmod", "Cấp quyền mod", admin_only=True)
def addmod(ctx):
    bot.roles.grant(ctx.args.strip(), "mod")
    ctx.reply("Đã cấp quyền mod.")

@bot.command("stats", "Thống kê", role="mod")
def stats(ctx):
    ctx.reply(f"Người dùng: {len(bot.users())}")

Bot hỏi đáp

Trả lời câu hỏi thường gặp bằng on_message.

FAQ = {"giờ mở cửa": "7h–22h mỗi ngày", "địa chỉ": "12 Lý Thường Kiệt, Hà Nội"}

@bot.on_message
def answer(ctx):
    for key, reply in FAQ.items():
        if key in ctx.text.lower():
            return ctx.reply(reply)
    ctx.reply("Mình chưa hiểu, bạn gõ /help để xem các lệnh nhé.")

JavaScript

new Bot({ token, admins: ["@chu_shop·k7q2xz"] });
bot.command("thongbao", "Gửi thông báo", fn, { adminOnly: true });   // hoặc { role: "mod" }
bot.storage.get("orders", []);  bot.storage.set("orders", list);
await bot.broadcast("Tin mới!");   bot.roles.grant(peer, "mod");   ctx.isAdmin;  ctx.hasRole("mod")

Ví dụ đầy đủ

Các ví dụ trong SDK dùng tên bot để thử nhanh không cần token. Khi chạy thật, hãy dùng token từ BotFather như ở bước 3.

"""Ví dụ bot Lumora (Python): chào hỏi, nút bấm, trả lời lại tin nhắn."""
import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "python"))
from lumora_bot import Bot

bot = Bot("Thời tiết Bot", data_dir=os.environ.get("BOT_DIR", "./weather-bot"),
          about="Xem thời tiết nhanh các thành phố Việt Nam")

WEATHER = {"hn": "Hà Nội: 24°C, có mây ⛅", "hcm": "TP.HCM: 32°C, nắng ☀️", "dn": "Đà Nẵng: 28°C, mưa rào 🌦️"}

@bot.command("start", "Bắt đầu")
def start(ctx):
    ctx.reply("Xin chào! Bạn muốn xem thời tiết ở đâu?",
              buttons=[[("Hà Nội", "hn"), ("TP.HCM", "hcm"), ("Đà Nẵng", "dn")]])

@bot.on_callback
def on_city(ctx):
    ctx.reply(WEATHER.get(ctx.data, "Chưa có dữ liệu"))

@bot.on_message
def echo(ctx):
    ctx.reply(f"Gõ /start để bắt đầu. Bạn vừa nói: {ctx.text}")

if __name__ == "__main__":
    bot.run()
"""Ví dụ bot có phân quyền admin, vai trò, lưu trữ và gửi hàng loạt."""
import os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "python"))
from lumora_bot import Bot

ADMINS = [a for a in os.environ.get("BOT_ADMINS", "").split(",") if a]
bot = Bot("Cửa hàng Bot", data_dir=os.environ.get("BOT_DIR", "./shop-bot"), admins=ADMINS, about="Đặt hàng & khuyến mãi")

@bot.command("start", "Bắt đầu")
def start(ctx):
    n = bot.storage.get("visits", 0) + 1
    bot.storage["visits"] = n
    ctx.reply(f"Chào bạn! Bạn là khách thứ {n} 🎉", buttons=[[("🛒 Xem hàng", "menu")]])

@bot.command("promo", "Gửi khuyến mãi cho mọi người", admin_only=True)
def promo(ctx):
    sent = bot.broadcast(ctx.args or "Giảm 20% hôm nay!")
    ctx.reply(f"Đã gửi cho {sent} người.")

@bot.command("addmod", "Cấp quyền mod", admin_only=True)
def addmod(ctx):
    bot.roles.grant(ctx.args.strip(), "mod")
    ctx.reply("Đã cấp quyền mod.")

@bot.command("stats", "Thống kê", role="mod")
def stats(ctx):
    ctx.reply(f"Lượt truy cập: {bot.storage.get('visits', 0)} — người dùng: {len(bot.users())}")

@bot.on_callback
def on_btn(ctx):
    if ctx.data == "menu":
        ctx.reply("☕ Cà phê 25k\n🧋 Trà sữa 30k")

if __name__ == "__main__":
    bot.run()
// Ví dụ bot Lumora (JavaScript / Node.js ≥ 18)
import { Bot } from "../js/lumora-bot.mjs";

const bot = new Bot({ name: "Echo Bot", dataDir: process.env.BOT_DIR || "./echo-bot", about: "Nhắc lại mọi tin nhắn" });

bot.command("start", "Bắt đầu", (ctx) =>
  ctx.reply("Chào bạn 👋 Bấm thử nút nhé:", [[{ text: "👍 Thích", data: "like" }, { text: "Trang chủ", url: "https://lumora.app" }]])
);
bot.onCallback((ctx) => ctx.reply(`Cảm ơn! Bạn đã bấm: ${ctx.data}`));
bot.onMessage((ctx) => ctx.reply(`Bạn nói: ${ctx.text}`));

await bot.run();

Ngữ cảnh của hàm xử lý

PythonJavaScript
ctx.textctx.textnội dung tin nhắn
ctx.datactx.datadữ liệu nút bấm (callback)
ctx.command / ctx.argsctx.command / ctx.argstên lệnh và phần chữ sau lệnh
ctx.sender / ctx.convctx.sender / ctx.convngười gửi và cuộc trò chuyện
ctx.is_admin / ctx.has_role("mod")ctx.isAdmin / ctx.hasRole("mod")kiểm tra quyền
ctx.reply(text, buttons=None)ctx.reply(text, buttons)trả lời, có thể kèm nút
ctx.send_file(path)ctx.sendFile(path)gửi một tệp
bot.storagebot.storage.get/setlưu dữ liệu, tự ghi ra tệp
bot.broadcast(text) / bot.users()await bot.broadcast(text) / await bot.users()gửi cho mọi người dùng / danh sách người dùng
bot.roles.grant(peer, "mod")bot.roles.grant(peer, "mod")cấp hoặc thu hồi (revoke) vai trò
bot.call(cmd, **args)bot.call(cmd, args)gọi bất kỳ lệnh nào trong tài liệu API

Tải SDK

Các tệp mã nguồn thuần, xem trực tiếp trên trình duyệt hoặc lưu về máy. Giữ cấu trúc thư mục sdk/ nếu bạn dùng nguyên các ví dụ.

Cần nhiều hơn trả lời tin nhắn?

bot.call(cmd, …) cho phép dùng mọi lệnh trong tài liệu API: nhóm, cảm xúc, bình chọn, sticker, tệp và nhiều hơn nữa.

Mở tài liệu API