tva
← Insights

การขยาย Telegram AI Assistant จากผู้ใช้คนเดียวสู่ทีม

คุณสร้าง Telegram AI assistant เฉพาะโปรเจกต์ไว้ใช้เอง ไม่ว่าจะเป็น Claude, GPT หรือ LLM อื่น ที่ wrap ไว้หลัง Telegram bot รันบนเซิร์ฟเวอร์ของตัวเอง ทุกอย่างทำงานดีเมื่อใช้คนเดียว ตอนนี้คุณต้องการแชร์กับทีม ไม่ว่าจะเป็น developer, ที่ปรึกษา หรือผู้เชี่ยวชาญที่จะได้ประโยชน์จากการเข้าถึง assistant เดิมได้ตามต้องการ เส้นทางจากผู้ใช้คนเดียวไปสู่ทีมขนาดเล็กมีรายละเอียดมากกว่าที่เอกสารส่วนใหญ่กล่าวถึง

คู่มือนี้ครอบคลุมทุกขั้นตอน ตั้งแต่การเก็บ Telegram ID ของสมาชิกทีม การขยาย allow-list ให้รับมือกับความแตกต่างระหว่าง restart กับ recreate ของ Docker การเปิดกลุ่มแบบที่ถูกต้อง การตั้งค่า trigger detection เพื่อไม่ให้ bot สแปม และการจัดการ privacy trade-off ที่ทีมส่วนใหญ่มักเจอปัญหา

สิ่งที่คุณต้องมี

  • Telegram bot ที่ทำงานได้แล้วสำหรับผู้ใช้อย่างน้อยหนึ่งคน (ตัวคุณเอง)
  • SSH หรือ shell access ไปยังเซิร์ฟเวอร์ที่รัน bot container
  • Telegram username ของสมาชิกทีมที่ต้องการเพิ่ม
  • การเข้าถึง BotFather (บัญชี Telegram เดิมที่สร้าง bot)
  • เวลาประมาณ 20 นาทีสำหรับงานเทคนิค บวกเวลาประสานงานกับสมาชิกทีม

ปัญหาที่คู่มือนี้แก้ไข

  • สมาชิกทีมไม่สามารถใช้ bot ได้ — "ใช้ได้ของตัวเอง แต่ไม่ได้ของคนอื่น"
  • การแก้ไข allow-list ดูเหมือนใช้งานได้แต่ bot ยังคง ignore ผู้ใช้ใหม่หลัง restart
  • Bot สแปมใน group chat โดยตอบทุกข้อความแทนที่จะตอบเฉพาะที่เกี่ยวข้อง
  • พฤติกรรม trigger ที่สับสน — bot ควรตอบเมื่อไร? เมื่อถูก mention? keyword? หรือ reply?
  • ความกังวลเรื่อง privacy จากการรั่วไหลของ memory ระหว่างผู้ใช้ที่ไม่ได้คาดไว้

ขั้นตอนที่ 1: เก็บ Telegram User ID แบบตัวเลขของสมาชิกแต่ละคน

allow-list ของ Telegram AI assistant ใช้ numeric user ID เป็น key ไม่ใช่ username หรือชื่อที่แสดง username สามารถเปลี่ยนได้ แต่ numeric ID คงที่ตลอดอายุบัญชี คุณต้องการ ID นี้จากสมาชิกทีมทุกคนที่ต้องการเพิ่ม

วิธีที่ง่ายที่สุด: ขอให้สมาชิกแต่ละคนเริ่มแชทกับ @userinfobot (utility bot สาธารณะ) ข้อความแรกที่ได้รับจะมี numeric ID เช่น 100000001 ให้พวกเขาคัดลอก ID แล้วส่งให้คุณทาง DM

ทางเลือกอื่นหาก @userinfobot ถูกบล็อกหรือไม่พร้อมใช้งานในพื้นที่:

  • ใช้ log ของ bot ตัวเอง เพิ่มบรรทัด "log all attempts" ชั่วคราวใน middleware ของ allow-list ขอให้สมาชิกส่งข้อความมาที่ bot แล้วอ่าน user ID จาก container log หลังจากได้ ID แล้วให้ลบบรรทัด logging ออก
  • อ่านจากข้อความในกลุ่ม หากผู้ใช้ส่งข้อความในกลุ่มที่ bot อยู่แล้ว field from.id ในข้อความนั้นมี numeric ID ซึ่งอ่านได้จาก endpoint getUpdates ของ bot

เก็บ ID ที่รวบรวมไว้ในที่ปลอดภัย ไม่ว่าจะเป็น note, password manager หรือตรงใน .env ของคุณ ให้ปฏิบัติกับข้อมูลเหล่านี้เหมือนที่อยู่อีเมล เพราะมันระบุตัวบุคคลและสามารถ cross-reference กับ Telegram profile สาธารณะได้

ขั้นตอนที่ 2: ขยาย allow-list ของ bot

Telegram bot framework ส่วนใหญ่ ไม่ว่าจะเป็น aiogram, python-telegram-bot, Telegraf หรือ grammY ใช้ middleware ในการตรวจสอบ allow-list ทุก update ที่เข้ามาจะถูกกรองด้วย sender ID ก่อนที่ handler จะทำงาน ผู้ส่งที่ไม่ได้รับอนุญาตจะถูก discard อย่างเงียบๆ bot จะรับข้อความภายในแต่ไม่ตอบกลับ

allow-list เองมักเก็บในตัวแปรสภาพแวดล้อม โหลดเข้า container ผ่าน env_file: ใน docker-compose.yml:

BOT_ALLOWED_USERS=100000001,100000002,100000003
BOT_OPERATOR_ID=100000001

มีสองรูปแบบที่นิยมใช้:

  • CSV list: BOT_ALLOWED_USERS=111,222,333 parse โดย settings code ของ bot เป็น list[int]
  • JSON array: BOT_ALLOWED_USERS=[111,222,333] ใช้เมื่อ settings parser คาดหวัง JSON สำหรับ complex types

หาก bot ใช้ Python กับ pydantic-settings สำหรับ configuration รูปแบบ JSON array เป็นตัวเลือกที่ปลอดภัยกว่า แม้แต่ผู้ใช้คนเดียว ควรใช้ BOT_ALLOWED_USERS=[100000001] แทน BOT_ALLOWED_USERS=100000001 เหตุผลอธิบายละเอียดในส่วน pydantic ด้านล่าง แต่โดยสรุปคือรูปแบบ JSON หลีกเลี่ยง parser ambiguity ที่ทำให้ container crash ตอน startup

ขั้นตอนที่ 3: Restart Container ให้ถูกวิธี

นี่คือจุดที่การอัปเดต allow-list ส่วนใหญ่ผิดพลาดอย่างเงียบๆ คุณแก้ไข .env, รัน docker compose restart your-bot, ดู container กลับขึ้นมา แต่ผู้ใช้ใหม่ยังใช้ bot ไม่ได้ การเปลี่ยนแปลง "ไม่มีผล"

สาเหตุ: docker compose restart แค่หยุดและเริ่ม container เดิม มันไม่สร้าง container ใหม่ Environment variable รวมถึงทุกอย่างจาก env_file: จะถูก inject เข้า container ตอนสร้าง ไม่ใช่ตอนเริ่ม การ restart จะ preserve snapshot env-var เดิม ไฟล์ .env ที่แก้ไขแล้วไม่มีผลต่อ container ที่ restart

คำสั่งที่ถูกต้อง:

docker compose up -d --force-recreate --no-deps your-bot-service-name

แต่ละ flag ทำอะไร:

  • --force-recreate หยุด container เก่า ลบออก และสร้างใหม่ด้วย Compose spec ปัจจุบัน รวมถึงเนื้อหา env_file: ที่แก้ไขใหม่
  • --no-deps ป้องกันไม่ให้ Compose recreate service อื่นที่ bot พึ่งพา เช่น database หรือ message queue หาก bot ไม่มี depends_on flag นี้ไม่มีผลแต่ก็ไม่เป็นปัญหา
  • -d รัน container ที่ recreate แบบ detached ให้ terminal กลับมาทันที

ตรวจสอบว่า recreate สำเร็จโดยดู uptime ของ container:

docker ps --filter name=your-bot --format "{{.Status}}"
# Expected: "Up 10 seconds" (not "Up 4 hours")

หาก status แสดง uptime เดิมที่ยาวนาน แสดงว่า recreate ไม่เกิดขึ้น ตรวจสอบ typo ในชื่อ service หรือว่าคุณรันคำสั่งจากไดเรกทอรีที่ถูกต้องหรือไม่

pattern นี้ใช้กับ Docker Compose service ทุกตัวที่มี configuration อยู่ใน env-file ไม่ว่าจะเป็น API gateway, worker, scraper หรือ monitoring agent กับดักเดียวกันนี้จะเจออีกทุกครั้ง เราได้บันทึก pattern ที่กว้างขึ้นสำหรับการจัดการ container จำนวนมากไว้ในคู่มือ routine health-check สำหรับ Dockerized infrastructure

pydantic-settings: Parser Trap ที่ควรรู้

หาก settings layer ของ bot ใช้ pydantic-settings ซึ่งเป็น library มาตรฐานสำหรับ Pydantic v2 settings และคุณประกาศ allow-list เป็น list[int] คุณจะเจอปัญหา parser ที่ควรเข้าใจก่อนจะเจอจริง

pydantic-settings จัดการ complex types เช่น list, dict, tuple เป็น JSON-encoded ตามค่าเริ่มต้น เมื่ออ่าน BOT_ALLOWED_USERS=111,222 จาก env-file มันจะ attempt json.loads("111,222") ก่อน ซึ่ง fail ด้วย JSONDecodeError: Extra data เพราะ CSV ธรรมดาไม่ใช่ JSON ที่ถูกต้อง container ของคุณจะ crash ตอน startup ด้วย SettingsError: error parsing value for field

หากคุณมี custom BeforeValidator ติดกับ field ที่รู้จัก parse CSV คุณอาจคิดว่ามันรันก่อนและดัก raw string ก่อนที่ JSON-decode จะ attempt แต่ไม่ใช่ pydantic-settings apply ขั้นตอน JSON-decode ก่อน field-level validator สำหรับ complex types

มีสองทางแก้:

Quick fix — ใช้ JSON-array syntax ใน env-file:

BOT_ALLOWED_USERS=[100000001,100000002,100000003]

นี่คือ JSON ที่ถูกต้อง pydantic-settings decode เป็น list of int ได้ตรงๆ ไม่ต้องมี validator trade-off เป็นแค่เรื่อง cosmetic คือมีวงเล็บครอบรายการ

Permanent fix — annotate field ด้วย NoDecode:

from pydantic_settings import NoDecode
from pydantic import BeforeValidator
from typing import Annotated

def parse_csv(v):
    if isinstance(v, str):
        return [int(x.strip()) for x in v.split(",")]
    return v

class Settings(BaseSettings):
    bot_allowed_users: Annotated[list[int], NoDecode, BeforeValidator(parse_csv)]

NoDecode ยับยั้งขั้นตอน JSON-decode อย่างสมบูรณ์ BeforeValidator ของคุณรับ raw string และ parse เป็น CSV นี่คือวิธีแก้ที่สะอาดกว่าหากคุณควบคุม settings code ได้

ปัญหาพื้นฐานนี้ติดตามใน pydantic-settings issue #157 พร้อม discussion เพิ่มเติมใน #184 และ #570 พฤติกรรมนี้สม่ำเสมอใน pydantic-settings ทุก version ที่ release แล้ว (v2.x) หากคุณไม่ได้ควบคุม settings code เช่น ใช้ third-party bot framework ให้ใช้ JSON-array syntax workaround

ขั้นตอนที่ 4: เปิด Telegram Group กับ bot และทีม

Telegram มีกลุ่มสองแบบสำหรับกรณีนี้:

  • Regular group: สมาชิกสูงสุด 200 คน โมเดล admin แบบง่าย ไม่มีฟีเจอร์ขั้นสูง เหมาะกับทีมเล็ก
  • Supergroup: สมาชิกสูงสุด 200,000 คน สิทธิ์ admin แบบละเอียด การสนทนาแบบ thread ประวัติข้อความถาวร สามารถ convert จาก regular group ได้ภายหลังเมื่อทีมขยายใหญ่ขึ้น

สำหรับงาน workflow ของทีมไม่เกินหนึ่งโหล regular group ก็เพียงพอ ขั้นตอน:

  • ใน Telegram app ของคุณ แตะ "New Group" และเลือกสมาชิกทีมจาก contact
  • ตั้งชื่อกลุ่มให้สื่อความหมาย เช่น "Project X — AI Assistant" หรือ "Engineering Bot Workspace"
  • เมื่อสร้างแล้ว เปิด settings ของกลุ่ม แตะ "Add Member" ค้นหา username ของ bot (@your_bot_name) แล้วเพิ่ม
  • Promote bot เป็น admin เฉพาะเมื่อต้องการ admin action เช่น การลบหรือ pin ข้อความ สำหรับการถามตอบธรรมดา สถานะ regular member ก็เพียงพอ

หากคุณจัดการ bot เฉพาะโปรเจกต์หลายตัวสำหรับหลายทีมบน infrastructure ร่วมกัน pattern multi-tenant ที่เราใช้บันทึกไว้ในคู่มือ multi-tenant Docker development stack

ขั้นตอนที่ 5: ตั้งค่า Trigger Detection

ตามค่าเริ่มต้น Telegram bot ในกลุ่มจะรับเฉพาะข้อความที่ mention มันโดยตรง (@your_bot_name), reply ต่อข้อความของมัน หรือใช้ slash-command Telegram เรียกสิ่งนี้ว่า "Privacy Mode" และเปิดใช้งานเป็นค่าเริ่มต้น ซึ่งเป็นค่าเริ่มต้นที่สมเหตุสมผลที่ป้องกัน bot สแปมโดยไม่ตั้งใจ

แต่สำหรับ Telegram AI assistant ที่ควรตอบคำถามปกติ เช่น "เฮ้ bot สถานะ deployment เป็นยังไง?" โดยไม่ต้อง mention ชัดเจน Privacy Mode จะจำกัดเกินไป คุณมีสองทาง:

ทาง A: คง Privacy Mode ไว้ สอนทีมให้ @mention ง่าย ไม่ต้องเปลี่ยน config bot เห็นเฉพาะสิ่งที่ควรตอบ ข้อเสีย: friction สมาชิกทีมลืม @ แล้ว bot ไม่ตอบ

ทาง B: ปิด Privacy Mode และ implement trigger logic เอง เปิด BotFather ส่ง /setprivacy เลือก bot แล้ว set เป็น Disable bot จะรับทุกข้อความในกลุ่ม คุณ implement การตรวจสอบ "ควรตอบไหม?" เอง

trigger set ที่ใช้งานจริงในระบบ production ของเรา:

  • Direct message: ตอบเสมอ คุณคุยกับ bot แบบ one-on-one
  • @mention ในกลุ่ม: ตอบเสมอ เป็นการเรียกใช้โดยตรง
  • Reply ต่อข้อความของ bot: ตอบเสมอ เป็นการสนทนาต่อเนื่องจากที่ bot เริ่มไว้
  • ข้อความในกลุ่มที่มี trigger word ของ bot: ตอบ โดย trigger word มักเป็นชื่อเล่นของ bot หรือชื่อโปรเจกต์ จับคู่ด้วย word-boundary regex เพื่อไม่ให้ "advisor" ถูก trigger โดยไม่ตั้งใจจาก "advisory"
  • ทุกอย่างอื่น: log อย่างเงียบๆ ลงในไฟล์ conversation ไม่มีการตอบกลับ

ส่วน silent-log มีความสำคัญ แม้ bot ไม่ตอบ มันยังเห็น conversation flow ของกลุ่ม การ log ทุกข้อความลงในไฟล์ per-chat ให้ bot มี context ในอนาคต เมื่อมีคน @mention มันพร้อมคำถาม เช่น "เราตัดสินใจอะไรไปบ้าง?" bot จะมีการสนทนาล่าสุดเป็น context สำหรับการใช้เหตุผล

การ implement ขึ้นอยู่กับ framework ของคุณ ใน aiogram handler ข้อความเดียวจะตรวจสอบทั้ง 5 เงื่อนไขก่อนตัดสินใจว่าจะเรียก LLM และตอบกลับ ใน Telegraf หรือ grammY pattern เหมือนกัน คือ bot.on('message') handler ที่ filter อย่างชัดเจนก่อน react

ขั้นตอนที่ 6: จัดการ Privacy Trade-Off

นี่คือคำถามที่ทีมส่วนใหญ่ไม่คิดถึงจนกว่าจะกลายเป็นปัญหา: bot รักษา memory แยกต่อผู้ใช้ ต่อกลุ่ม หรือ global ข้ามทุก conversation?

มีสาม pattern ที่พบบ่อย:

  • Per-chat memory: bot เริ่ม session ใหม่สำหรับทุก chat DM กับผู้ใช้ A แยกจาก DM กับผู้ใช้ B และทั้งคู่แยกจากกลุ่ม X privacy สูงสุด ข้อเสีย: bot ไม่จำ context ข้าม session ซึ่งจำกัดความมีประโยชน์ในฐานะ "assistant ที่รู้จักโปรเจกต์ของเรา"
  • Per-user memory: bot รักษา thread memory แยกต่อผู้ใช้ แต่แชร์ข้าม DM และการ mention ในกลุ่มจากผู้ใช้คนเดียวกัน เป็น middle ground ที่สมเหตุสมผล
  • Global memory: bot มี session เดียวที่ทุก conversation มีส่วนร่วม การแชร์ context สูงสุด DM และ conversation ในกลุ่มสร้าง long-term memory เดียวกัน ข้อเสีย: privacy รั่วไหล สิ่งที่สมาชิกคนหนึ่งบอก bot ใน DM แบบลับๆ อาจปรากฏในคำตอบสำหรับคำถามของสมาชิกคนอื่นในกลุ่ม

แต่ละ pattern สามารถป้องกันได้ แต่ละอย่างมี trade-off ที่ทีมต้องตกลงกันก่อนเปิดให้ผู้ใช้หลายคน

หากคุณเลือก global memory ซึ่งเราใช้สำหรับทีมที่ tight-knit ซึ่งการแชร์ context เป็นส่วนหนึ่งของ value proposition ให้สื่อสารอย่างชัดเจนกับทีมก่อนที่พวกเขาจะเริ่มใช้ bot: "สิ่งที่คุณบอก bot นี้อาจปรากฏในคำตอบที่ทั้งกลุ่มเห็นได้ ให้ถือว่าเป็น shared workspace ไม่ใช่ที่ปรึกษาส่วนตัว"

หากคุณเลือก per-chat memory คุณจะสูญเสีย cross-context reasoning เช่น "เราตัดสินใจอะไรเรื่อง X เมื่อสัปดาห์ที่แล้ว?" แต่หลีกเลี่ยง leak risk ได้อย่างสมบูรณ์

นี่คือการตัดสินใจด้าน design ที่มีผลทางสังคมจริงๆ ไม่ใช่แค่ปุ่มทางเทคนิคที่เปลี่ยนได้ภายหลังโดยไม่ต้องให้ทีมรับรู้ เราพูดถึง trade-off ที่คล้ายกันในบทความที่กว้างขึ้นเกี่ยวกับAI agent skills สำหรับ domain-specific workflows ซึ่ง shared-context configuration ปรากฏในทุก customer engagement ที่เราดำเนินการ

การขยาย Telegram AI Assistant ให้เกินทีมขนาดเล็ก

pattern allow-list ใน env-file ทำงานได้ดีสำหรับทีมขนาดประมาณ 20 ถึง 30 คน เกินจากนั้น hardcoded entry จะยุ่งยาก การ onboard ผู้ใช้ใหม่แต่ละครั้งต้องมี git commit (หาก env ถูก check in ผ่าน SOPS หรือ secrets-management layer ที่คล้ายกัน) deploy และ container recreate

Pattern ที่รองรับการขยายได้มากกว่า:

  • Database-backed allow-list: ผู้ใช้อยู่ใน SQL table bot อ่านและ cache รายการตอน startup จากนั้น refresh เป็นระยะ (หรือผ่าน webhook เมื่อมีการเปลี่ยนแปลงผู้ใช้) การ onboard ผู้ใช้ใหม่เป็นแค่ INSERT statement ไม่ต้อง deploy
  • Group-membership-based access: แทนที่จะ allow ผู้ใช้แต่ละคน ให้ allow ผู้ใช้ทุกคนที่เป็นสมาชิกของ Telegram group เฉพาะ (หรือกลุ่มเล็กๆ) การเป็นสมาชิกกลุ่มเป็น access boundary Telegram API getChatMember ยืนยันการเป็นสมาชิกก่อนทุก invocation
  • Channel-based: สำหรับ assistant แบบ read-only เช่น daily summary, alert หรือ monitoring digest ใช้ Telegram channel แทน group Channel มีโมเดลสิทธิ์ที่แตกต่างกัน มีเฉพาะ admin ที่ post ได้ คนอื่น read อย่างเดียว มีประโยชน์เมื่อเป็น one-to-many fan-out ไม่ใช่การสนทนาสองทาง

สำหรับ workflow ของทีมขนาดเล็ก ไม่ว่าจะเป็น developer, ที่ปรึกษา หรือผู้เชี่ยวชาญที่เข้ามาเป็นครั้งคราว pattern allow-list ใน env-file ก็เพียงพอ เราใช้มันกับ infrastructure ภายในของเราเป็นส่วนใหญ่ และถือว่า database-backed variant เป็น refactor ที่ทำเมื่อโปรเจกต์โตเกินกว่ารูปแบบที่ง่ายกว่าอย่างชัดเจน

Checklist ก่อนใช้งานจริง

ก่อนที่ทีมจะเริ่มใช้ bot ตรวจสอบ:

  • เก็บ numeric Telegram ID ของสมาชิกทีมทุกคนและเพิ่มใน allow-list แล้ว
  • รูปแบบ allow-list ตรงกับสิ่งที่ settings parser คาดหวัง — JSON-array หาก pydantic-settings อยู่ใน stack
  • Container ถูก recreate (ไม่ใช่แค่ restart) เพื่อให้ env-var ใหม่โหลดเข้า container ใหม่
  • สร้าง Telegram group พร้อมเพิ่ม bot เป็น member แล้ว (และ promote เป็น admin หากต้องการ admin action)
  • ตั้งค่า BotFather privacy mode ให้ตรงกับ trigger strategy — ปิดเฉพาะเมื่อ implement filter logic เองแล้ว
  • Trigger logic ใน bot code สอดคล้องกับ privacy mode (อย่าปิด privacy โดยไม่ filter มิฉะนั้น bot จะสแปมทุกข้อความในกลุ่ม)
  • เลือก memory model (per-chat / per-user / global) และสื่อสารกับทีมแล้ว
  • กำหนด privacy expectation กับสมาชิกทีมอย่างชัดเจนก่อนที่พวกเขาจะเริ่มใช้ bot

หากคุณกำลังสร้าง assistant เฉพาะโปรเจกต์ตั้งแต่ต้นและต้องการเข้าใจว่า bot infrastructure พื้นฐานเชื่อมต่อกันอย่างไร บทความเพื่อนคู่กันของเราเกี่ยวกับการสร้าง project-specific AI assistant ผ่าน Telegram ครอบคลุมรากฐาน สำหรับ email infrastructure ที่มักมาพร้อมกับ setup เหล่านี้ เช่น notification, escalation path และ audit trail ดูบทความของเราเกี่ยวกับการตั้งค่า mailbox เฉพาะโปรเจกต์พร้อม DKIM และ DMARC

หากคุณดำเนินการ multi-user Telegram AI assistant infrastructure สำหรับลูกค้าหรือทีมของตัวเองและต้องการความช่วยเหลือในการ rollout ติดต่อเรา เราสร้างและดูแล setup แบบนี้เป็นส่วนหนึ่งของงานโปรเจกต์ของเรา


บทความที่เกี่ยวข้อง

บทความที่เกี่ยวข้อง