บทความทั้งหมด
แพ็กเก็ตอัปเดตการแชทสไตล์โทรเลขเดินทางผ่านอุโมงค์ HTTPS ที่ปลอดภัยไปยังตัวจัดการบอทที่ทำงานบนแล็ปท็อปของนักพัฒนา
Telegram Bot APIwebhookslocalhostbot development

ทดสอบเว็บฮุกบอต Telegram บน localhost

หากต้องการทดสอบ Telegram bot webhook บน localhost ให้เปิดเผยเซิร์ฟเวอร์ภายในเครื่องของคุณด้วยอุโมงค์ HTTPS สาธารณะ โทร setWebhook ด้วย URL นั้น และตรวจสอบความถูกต้องของส่วนหัวโทเค็นลับของ Telegram ในทุกคำขอ สิ่งนี้จะให้ข้อความจริง แบบสอบถามการโทรกลับ และ อัปเดตความเป็นสมาชิกโดยไม่ต้องปรับใช้หลังจากเปลี่ยนรหัสทุกครั้ง การวนซ้ำที่สมบูรณ์คือ: เรียกใช้ตัวจัดการบอท เริ่ม npx portpreview 3000 ลงทะเบียน URL ผลลัพธ์ ส่งข้อความบอทของคุณ และตรวจสอบคำขอในเครื่อง

ทำไม Telegram ไม่สามารถส่งการอัปเดตโดยตรงไปยัง localhost

Bot API ของ Telegram ส่งการอัปเดต webhook จากโครงสร้างพื้นฐาน Telegram ไปยัง URL ที่เข้าถึงอินเทอร์เน็ตได้ localhost, 127.0.0.1 และที่อยู่ LAN ส่วนตัวไม่สามารถกำหนดเส้นทางจากโครงสร้างพื้นฐานนั้นได้ localhost tunnel ยุติ HTTPS ที่ที่อยู่สาธารณะและส่งต่อคำขอ HTTP ที่ไม่เปลี่ยนแปลงไปยังพอร์ตในเครื่องของคุณ

เทเลแกรมบอทสามารถรับการอัปเดตได้สองวิธีที่ไม่เกิดร่วมกัน: การโพลแบบยาวผ่าน getUpdates หรือเว็บฮุค อย่างเป็นทางการ setWebhook การอ้างอิง ระบุว่า getUpdates ไม่พร้อมใช้งานในขณะที่กำหนดค่า webhook ขาออก หากกระบวนการโพลยังคงทำงานอยู่ ให้หยุดก่อนที่จะตัดสินโฟลว์เว็บฮุค

สร้างจุดสิ้นสุด webhook ในเครื่อง

ตัวอย่าง Express นี้ทำให้ตัวจัดการมีขนาดเล็กโดยเจตนา จะตรวจสอบความลับที่แชร์ก่อนที่จะแตะการอัปเดต รับทราบอย่างรวดเร็ว และย้ายงานออกนอกเส้นทางการตอบสนอง

import express from 'express';
import crypto from 'node:crypto';

const app = express();
app.use(express.json({ limit: '1mb' }));

function sameSecret(received = '', expected = '') {
  const a = Buffer.from(received);
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post('/webhooks/telegram', (req, res) => {
  const received = req.get('x-telegram-bot-api-secret-token') || '';
  if (!sameSecret(received, process.env.TELEGRAM_WEBHOOK_SECRET)) {
    return res.sendStatus(401);
  }

  const update = req.body;
  res.sendStatus(200);
  queueMicrotask(() => handleUpdate(update));
});

app.listen(3000, () => console.log('Listening on http://localhost:3000'));

Telegram ส่ง JSON-ซีเรียลไลซ์ Update แตกต่างจากผู้ให้บริการที่ใช้ HMAC คุณลักษณะ secret_token ของ Telegram ไม่ได้ลงนามในส่วนเนื้อหา โดยจะวางค่าที่คุณเลือกไว้ใน X-Telegram-Bot-Api-Secret-Token โทเค็นพิสูจน์ให้เห็นว่าผู้ส่งทราบค่าที่ใช้เมื่อลงทะเบียน webhook แต่ไม่ได้ให้ข้อมูลสรุปของเพย์โหลด TLS ปกป้องคำขอระหว่างทาง

เปิดเผยปลายทางด้วย HTTPS

  1. เริ่มต้นแอปและยืนยัน curl -i http://localhost:3000/webhooks/telegram ถึงเซิร์ฟเวอร์ แม้ว่า GET จะส่งกลับ 404 ก็ตาม
  2. เปิดเทอร์มินัลที่สองแล้วรัน npx portpreview 3000.
  3. คัดลอกต้นกำเนิด HTTPS สาธารณะและผนวก /webhooks/telegram.
  4. ให้กระบวนการทันเนลทำงานต่อไปในขณะที่ Telegram ส่งการอัปเดต

Bot API ยอมรับ HTTPS webhook URL เอกสาร Telegram รองรับ webhook บนพอร์ต 443, 80, 88 และ 8443; โดยปกติแล้วจุดสิ้นสุดสาธารณะของทันเนลที่ได้รับการจัดการจะใช้ 443 แม้ว่ากระบวนการในเครื่องที่ส่งต่อจะฟังบน 3000

ลงทะเบียน Telegram webhook อย่างปลอดภัย

สร้างความลับแบบสุ่มที่มีเฉพาะตัวอักษร ตัวเลข ขีดล่าง หรือขีดกลางเท่านั้น โทรเลขอนุญาตให้มีอักขระได้ 1–256 ตัว อย่าใช้โทเค็นบอทซ้ำเป็นค่านี้

export TELEGRAM_WEBHOOK_SECRET="$(openssl rand -hex 32)"

curl -sS -X POST \
  "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/setWebhook" \
  -d "url=https://YOUR-TUNNEL.portpreview.dev/webhooks/telegram" \
  -d "secret_token=${TELEGRAM_WEBHOOK_SECRET}" \
  -d 'allowed_updates=["message","callback_query"]' \
  -d "drop_pending_updates=true"

allowed_updates ลดเสียงรบกวน และควรแสดงรายการเฉพาะประเภทการอัปเดตที่บอทจัดการเท่านั้น drop_pending_updates=true มีประโยชน์เมื่อเริ่มต้นเซสชันในเครื่องใหม่ แต่จะละทิ้งการอัปเดตที่อยู่ในคิวอย่างถาวร ดังนั้นให้ละเว้นเมื่อเหตุการณ์เหล่านั้นมีความสำคัญ เอกสารการอัปเดตของ Telegram อธิบายฟิลด์ต่างๆ เช่น message, callback_query และ my_chat_member.

ยืนยันการลงทะเบียนก่อนที่จะแก้ไขโค้ด

ใช้ getWebhookInfo เพื่อแยกความล้มเหลวในการกำหนดค่าออกจากความล้มเหลวของตัวจัดการ:

curl -sS "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getWebhookInfo"

ตรวจสอบ url, pending_update_count, last_error_message และ last_error_date URL ว่างเปล่าหมายความว่าการลงทะเบียนไม่ติด จำนวนรอดำเนินการที่เพิ่มขึ้นมักจะหมายความว่า Telegram ไม่สามารถเชื่อมต่อได้หรือปลายทางของคุณส่งกลับสถานะไม่ใช่ 2xx ส่งข้อความโดยตรงถึงบอทหลังการลงทะเบียน เพียงเปิดแชทไม่จำเป็นต้องสร้างการอัปเดต

จัดการการอัปเดตโดยไม่ต้องลองใหม่

รับทราบก่อนงานช้า

ส่งคืนการตอบกลับ 2xx ทันทีที่คำขอได้รับการตรวจสอบสิทธิ์และยอมรับอย่างคงทน การส่งออกฐานข้อมูล การเรียก AI และ API ของบริษัทอื่นควรทำงานแบบอะซิงโครนัส Telegram พยายามส่งคำขอที่ไม่สำเร็จอีกครั้งหลังจากการตอบกลับที่ไม่ใช่ 2xx ดังนั้นการทำงานแบบซิงโครนัสที่ช้าจึงสามารถสร้างรายการซ้ำได้

ทำซ้ำกับ update_id

ทุกการอัปเดตจะมี update_id จัดเก็บ ID ที่ประมวลผลโดยมีกรอบเวลาหมดอายุหรือบังคับใช้คีย์ฐานข้อมูลเฉพาะ การลองใหม่จะต้องไม่ส่งใบเสร็จรับเงินใบที่สอง สร้างตั๋วซ้ำ หรือดำเนินการโทรกลับเดิมสองครั้ง

สร้างโมเดลการอัปเดตทุกประเภทอย่างชัดเจน

ไม่ใช่ทุกการอัปเดตที่มี message.text ปุ่มโทรกลับอยู่ใต้ callback_query; โพสต์ของช่องและการเปลี่ยนแปลงการเป็นสมาชิกมีช่องอื่นๆ แยกสาขาบนฟิลด์ระดับบนสุดปัจจุบันและถือว่าประเภทที่ไม่รู้จักเป็นการไม่ดำเนินการที่ถูกต้องแทนที่จะโยนทิ้ง

กฎความปลอดภัยสำหรับการทดสอบบอท Telegram ในพื้นที่

  • ตรวจสอบส่วนหัวของข้อมูลลับก่อน ปฏิเสธค่าที่หายไปหรือไม่ถูกต้องก่อนที่จะบันทึกหรือแยกวิเคราะห์ฟิลด์ที่ละเอียดอ่อน
  • เก็บโทเค็นไม่ให้อยู่ใน URL และบันทึก โทเค็น Bot API ในคำสั่งการลงทะเบียนเป็นข้อมูลรับรอง หลีกเลี่ยงประวัติเชลล์บนระบบที่ใช้ร่วมกันและหมุนเวียนโทเค็นที่เปิดเผยผ่าน BotFather
  • ใช้เส้นทางและความลับที่คาดเดาไม่ได้ เส้นทางคือการป้องกันในเชิงลึก ส่วนหัวลับคือการตรวจสอบแอปพลิเคชันจริง
  • จำกัดข้อมูลที่บันทึกไว้ ข้อความสามารถประกอบด้วยชื่อ ชื่อผู้ใช้ หมายเลขโทรศัพท์ ไฟล์ และข้อความการสนทนาส่วนตัว ตรวจทานบันทึกและลบการบันทึกในเครื่องเมื่อเสร็จสิ้น
  • อย่าปิดใช้งานการรับรองความถูกต้องในการพัฒนา อุโมงค์สาธารณะเป็นแบบสาธารณะ รหัสท้องถิ่นควรใช้การตรวจสอบเดียวกันกับการผลิต

ดู คู่มือความปลอดภัย localhost tunnel ด้านความปลอดภัย ที่กว้างขึ้นสำหรับแนวทางปฏิบัติในการควบคุมการเข้าถึงและการเก็บรักษาข้อมูล

แก้ไขปัญหา Telegram webhook ทั่วไปล้มเหลว

Telegram รายงานใบรับรองหรือข้อผิดพลาดในการเชื่อมต่อ

ใช้ HTTPS URL ของทันเนล ไม่ใช่เป้าหมาย HTTP ในเครื่อง ยืนยันว่าช่องสัญญาณทำงานอยู่และ URL ไม่มีการเปลี่ยนแปลง หากคุณมอบใบรับรองที่ลงนามด้วยตนเองแทน Telegram กำหนดให้ต้องอัปโหลดใบรับรองสาธารณะเป็นไฟล์ ตำแหน่งข้อมูล TLS ที่มีการจัดการจะหลีกเลี่ยงการตั้งค่าดังกล่าว

จุดสิ้นสุดส่งคืน 401

เปรียบเทียบความลับที่ส่งไปยัง setWebhook กับตัวแปรสภาพแวดล้อมที่ใช้โดยกระบวนการ ชื่อส่วนหัวไม่ต้องคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ แต่พร็อกซีหรือมิดเดิลแวร์สามารถตัดส่วนหัวที่กำหนดเองได้ ตรวจสอบส่วนหัวขาเข้าโดยไม่ต้องพิมพ์ค่าลับ

ไม่มีการร้องขอมาถึง

เรียกใช้ getWebhookInfo ตรวจสอบเส้นทางที่ลงทะเบียนตรงกับเส้นทางของคุณทุกประการ และตรวจสอบให้แน่ใจว่าไม่มีไฟร์วอลล์บล็อกการเชื่อมต่อภายในของทันเนล หากคุณเพิ่งใช้การสำรวจความคิดเห็น ให้ยืนยันว่าขณะนี้มีการเติม URL ของเว็บฮุคแล้ว เรียกใช้การอัปเดตจริงโดยส่งข้อความถึงบอท

มีการอัปเดตซ้ำแล้วซ้ำอีก

บันทึกสถานะและเวลาตอบสนอง ข้อยกเว้นหลังจากได้รับคำขออาจเปลี่ยนความตั้งใจ 200 เป็น 500 คืน 200 ทันที ทำการประมวลผล idempotent และใช้ ควบคุมการเล่นซ้ำ webhook แทนที่จะรอให้ผู้ให้บริการลองใหม่ในระหว่างการดีบัก

ทดสอบคำสั่งโทรกลับและไฟล์ ไม่ใช่แค่ข้อความ

เมทริกซ์ทดสอบบอทที่มีประโยชน์ครอบคลุมมากกว่า message.text ส่งภาพถ่ายพร้อมคำบรรยาย แบ่งปันรายชื่อ แก้ไขข้อความ และกดปุ่มแป้นพิมพ์อินไลน์ สำหรับการสอบถามเกี่ยวกับการโทรกลับ ให้โทร answerCallbackQuery ทันทีเพื่อให้ไคลเอ็นต์หยุดแสดงตัวบ่งชี้ความคืบหน้า จากนั้นทำงานช้าลงแยกกัน การอัพเดตไฟล์มีตัวระบุ การดาวน์โหลดไบต์ถือเป็นการดำเนินการ Bot API ครั้งที่สอง และไม่ควรทำให้การตอบสนองของเว็บฮุคล่าช้า

เก็บอุปกรณ์จับยึดที่ผลิตจากการปรับปรุงสุขอนามัยสำหรับการทดสอบหน่วย แต่คงเส้นทางการขนส่งทั้งหมดไว้สำหรับการทดสอบแต่ละประเภทที่รองรับอย่างน้อยหนึ่งครั้ง อุปกรณ์ติดตั้งพิสูจน์ให้เห็นว่าผู้มอบหมายงานของคุณเข้าใจน้ำหนักบรรทุก การจัดส่งแบบทันเนลจริงยังพิสูจน์การลงทะเบียน TLS ส่วนหัว การแยกวิเคราะห์เนื้อหา และพฤติกรรมการตอบรับอีกด้วย เมื่อเพิ่มรายการ allowed_updates ใหม่ ให้โทร setWebhook อีกครั้ง และตรวจสอบว่า getWebhookInfo สะท้อนถึงการกำหนดค่าที่ต้องการ

ลบ webhook หลังจากเซสชันในเครื่อง

curl -sS -X POST \
  "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/deleteWebhook" \
  -d "drop_pending_updates=false"

การลบเว็บฮุคจะทำให้คุณกลับไปที่ getUpdates ได้ หาก URL ช่องสัญญาณเปลี่ยนแปลงในเซสชันถัดไป ให้โทร setWebhook อีกครั้ง สำหรับการวินิจฉัยเพิ่มเติม ให้ปฏิบัติตาม เวิร์กโฟลว์การแก้ไขจุดบกพร่อง webhook ทั่วไป.

คำถามที่พบบ่อย

Telegram สามารถส่ง bot webhook ไปยัง localhost โดยตรงได้หรือไม่?
ไม่ใช่ Telegram ไม่สามารถกำหนดเส้นทางคำขอไปยัง localhost หรือที่อยู่ LAN ส่วนตัวได้ ใช้อุโมงค์ HTTPS สาธารณะที่ส่งต่อคำขอไปยังเซิร์ฟเวอร์บอทในเครื่องของคุณ
ฉันจะตรวจสอบคำขอ Telegram bot webhook ได้อย่างไร
ส่ง Secret_token แบบสุ่มเพื่อ setWebhook และเปรียบเทียบส่วนหัว X-Telegram-Bot-Api-Secret-Token ของทุกคำขอกับค่านั้นโดยใช้การเปรียบเทียบที่ปลอดภัยต่อเวลา
เหตุใด Telegram webhook ของฉันจึงได้รับการอัปเดตซ้ำซ้อน
Telegram ลองส่งอีกครั้งไม่สำเร็จ ส่งคืน 2xx อย่างรวดเร็วและขจัดงานที่ซ้ำกันด้วย update_id ดังนั้นการลองใหม่จะไม่สามารถเกิดผลข้างเคียงซ้ำได้
ฉันสามารถใช้ getUpdates ขณะที่ Telegram webhook ทำงานอยู่ได้หรือไม่
ไม่ใช่ Bot API ของ Telegram ไม่อนุญาตให้ใช้ getUpdates ในขณะที่กำหนดค่า webhook ขาออก ลบ webhook ก่อนที่จะกลับไปสู่การโพลแบบยาว