EzEzLife Developers
ภาษาไทย
Bot API
EZLIFE / BOT PLATFORM

เอกสาร Bot API

ตั้งแต่สร้างบอตจนถึงเชื่อมต่อโปรแกรม

คู่มือ BotMother การส่งข้อความ คัดลอกรหัสยืนยัน และปุ่มตอบกลับ ตัวอย่างใช้ค่าจำลองทั้งหมด

อัปเดต HTTPS · JSON · UTF-8

ภาพรวมและความสามารถ

#

เมธอดสาธารณะคือ getMe, sendMessage, getUpdates ส่งข้อความส่วนตัวหรือกลุ่ม และรับเหตุการณ์ที่อาจมีเนื้อหาอื่นนอกจากข้อความ

ใช้ copy_text แสดงปุ่มคัดลอกรหัส และ reply_markup แสดงปุ่มข้อความใต้ช่องเขียนแชตส่วนตัว

โดเมนนี้เป็นเอกสาร API ยังคงอยู่ที่ im.ez7.life ใต้ /bot-api/ คัดลอก ID ผู้รับที่ ตั้งค่า → รายละเอียดบัญชี → ID ใช้ message.chat.id ที่ได้รับเพื่อตอบกลับ ในเหตุการณ์กลุ่มจะเป็น ID กลุ่ม

ที่อยู่หลัก API
https://im.ez7.life/bot-api/<BOT_TOKEN>/<METHOD>

เริ่มต้นอย่างรวดเร็ว

#
  1. ค้นหาและเพิ่ม @BotMother แล้วเปิดการจัดการบอตด้านบนของแชต
  2. สร้างบอต คัดลอก Token และเก็บในตัวแปรสภาพแวดล้อมฝั่งเซิร์ฟเวอร์ EZLIFE_BOT_TOKEN
  3. เรียก getMe ตรวจสอบบอต แล้วเรียก sendMessage ด้วย ID ผู้รับ
  4. เรียก getUpdates เป็นระยะ บันทึก offset ถัดไปหลังประมวลผลสำเร็จเท่านั้น
bash
python3 bot.py

จัดการด้วย BotMother

#

ชื่อที่แสดงยาว 1–64 ตัวอักษร คำนำหน้าบัญชีในแบบฟอร์มยาว 3–28 ตัว เริ่มด้วยตัวอักษรอังกฤษ ใช้ตัวอักษร ตัวเลข และขีดล่าง แบบฟอร์มเติม _bot ให้อัตโนมัติ โปรดตรวจสอบชื่อก่อนสร้าง

ค้นหาบอต ดู ID สถานะ เวลาสร้าง และ **** ตามด้วย Token 6 ตัวท้าย รวมทั้งออก Token ใหม่หรือเพิกถอนได้ ผู้ดูแลกำหนดจำนวนบอตสูงสุด

คำสั่งหน้าที่
/startแสดงวิธีจัดการ
/newbotเริ่มสร้างบอต
/mybotsแสดงบอตของคุณ
/token @usernameออก Token ใหม่ ยกเลิกของเดิม
/revoke @usernameเพิกถอน Token ปัจจุบัน
/cancelยกเลิกขั้นตอนสร้าง
/helpแสดงความช่วยเหลือ

Token และความปลอดภัย

#

Token เต็มแสดงเฉพาะตอนสร้างหรือออกใหม่ ถือเป็นรหัสผ่านบอต เก็บฝั่งเซิร์ฟเวอร์ อย่าใส่ในเว็บไซต์ แอป คลังสาธารณะ หรือบันทึกเหตุการณ์

ออกใหม่ทำให้ Token เดิมใช้ไม่ได้ทันที การเพิกถอนปิดการเรียกจากภายนอก ส่วนท้ายที่ปิดบังไม่สามารถกู้ Token ได้ หากสูญหายให้ออกใหม่และแก้โปรแกรม

Token เก่าจะบันทึกส่วนท้ายในการเรียก Bot API ที่ถูกต้องครั้งถัดไป Token API จากรายละเอียดบัญชีใช้กับ API บัญชี ส่วน Bot API นี้ใช้ Token จาก BotMother

getMe · ข้อมูลบอต

#
POST/bot-api/<BOT_TOKEN>/getMe

ไม่ต้องส่งพารามิเตอร์ธุรกิจ คืน ID บอต ชื่อที่แสดง ชื่อบัญชี และสถานะความสามารถด้านกลุ่ม ใช้ตรวจสอบ Token ได้

คำขอ
curl --fail-with-body --request POST \
  "https://im.ez7.life/bot-api/${EZLIFE_BOT_TOKEN}/getMe" \
  --header 'Content-Type: application/json' --data '{}'
การตอบกลับ
{
  "ok": true,
  "result": {
    "id": "1000000000",
    "is_bot": true,
    "display_name": "Example Bot",
    "username": "example_bot",
    "can_join_groups": true,
    "can_read_all_group_messages": true
  }
}

sendMessage · ส่งข้อความ

#
POST/bot-api/<BOT_TOKEN>/sendMessage

ใช้ POST application/json ส่ง chat_id เป็นสตริงเสมอ แชตส่วนตัวใช้ ID ผู้รับ แชตกลุ่มใช้ ID กลุ่มและ chat_type: "group"

ข้อความยาว 1–5000 ตัวอักษร ตัดช่องว่างหัวท้าย เก็บ message_id ที่ได้รับ ยังไม่มีคีย์ป้องกันส่งซ้ำ เมื่อหมดเวลารอให้ตรวจผลก่อนส่งอีกครั้ง

พารามิเตอร์ชนิดจำเป็นคำอธิบาย
chat_idstringใช่ID ผู้รับ หรือ ID กลุ่ม เป็นสตริงเสมอ
textstringใช่ข้อความยาว 1–5000 ตัวอักษร
chat_typestringไม่ใช่ค่าเริ่มต้น private กลุ่มใช้ group และรองรับ supergroup
copy_textstringไม่ใช่สตริงตัวเลข 4–12 หลักที่ปรากฏครบใน text
reply_markupobject / JSON stringไม่ใช่ออบเจ็กต์แป้นหรือสตริง JSON ไม่บังคับ
คำขอ
curl --fail-with-body --request POST \
  "https://im.ez7.life/bot-api/${EZLIFE_BOT_TOKEN}/sendMessage" \
  --header 'Content-Type: application/json' --data-binary @- <<'JSON'
{
  "chat_id": "USER_ID",
  "text": "ดำเนินการคำสั่งซื้อแล้ว"
}
JSON
sendMessage · group
{
  "chat_id": "GROUP_ID",
  "chat_type": "group",
  "text": "ดำเนินการคำสั่งซื้อแล้ว"
}
การตอบกลับ
{
  "ok": true,
  "result": {
    "message_id": "EXAMPLE_MESSAGE_ID",
    "date": 1794297600,
    "chat": {
      "id": "USER_ID",
      "type": "private"
    },
    "text": "ดำเนินการคำสั่งซื้อแล้ว"
  }
}

ส่งสำเร็จคืน ok: true และ result พร้อม copy_text สำหรับรหัส และ reply_markup กับ reply_keyboard_revision สำหรับเมนู รับข้อมูลเป็นอาร์เรย์ result ถ้าไม่มีเหตุการณ์คือ result: []

คัดลอกรหัสยืนยัน

#

ใส่ชื่อระบบ วัตถุประสงค์ และอายุรหัสในข้อความ แล้วเพิ่ม copy_text เป็นสตริงตัวเลข ASCII 4–12 หลักซึ่งปรากฏครบใน text การใช้สตริงรักษาเลขศูนย์นำหน้า

ไอคอนคัดลอกเฉพาะรหัส โปรแกรมของคุณต้องสร้าง ตรวจสอบ และกำหนดอายุรหัสเอง ฟิลด์นี้ควบคุมเพียงการแสดงและคัดลอก ไคลเอนต์เก่ายังอ่านข้อความได้

sendMessage · copy_text
{
  "chat_id": "USER_ID",
  "text": "รหัสเข้าสู่ระบบตัวอย่าง: 003812 ใช้ได้ 5 นาที",
  "copy_text": "003812"
}

แป้นพิมพ์ปุ่มตอบกลับ

#

เป็นแป้นปุ่มข้อความหลายแถว เมื่อกดจะส่งชื่อปุ่มเป็นข้อความปกติ ให้จัดการผ่าน message.text ใน getUpdates

มี 1–8 แถว แถวละ 1–4 ปุ่ม รวมไม่เกิน 24 ปุ่ม ชื่อยาว 1–64 ตัวอักษร ห้ามว่าง ขึ้นบรรทัดใหม่ หรือมีอักขระควบคุม ปุ่มเป็นสตริงหรือออบเจ็กต์ที่มีเพียง text

ไม่ส่ง reply_markup จะคงแป้นเดิม แป้นใหม่แทนที่แป้นเก่า ส่ง remove_keyboard: true เพียงอย่างเดียวเพื่อลบแป้นและปุ่มเปิด

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

แป้นใช้เฉพาะแชตส่วนตัว ส่ง reply_markup ในกลุ่มได้ 422 text ยังจำเป็น ใช้ JSON true/false ห้ามใช้สตริง ตัวเลือกแป้น/ปุ่มที่ไม่รองรับจะถูกปฏิเสธ reply_markup แบบสตริง JSON สูงสุด 16 KiB

พารามิเตอร์ชนิดจำเป็นคำอธิบาย
reply_markupobject / JSON stringไม่ใช่ออบเจ็กต์แป้นหรือสตริง JSON ไม่บังคับ
keyboardarray[]ใช่อาร์เรย์สองมิติ แต่ละอาร์เรย์ย่อยคือหนึ่งแถว
resize_keyboardbooleanไม่ใช่ค่าเริ่มต้น true ใช้ปุ่มกะทัดรัด false ใช้ปุ่มสูงขึ้น
one_time_keyboardbooleanไม่ใช่ค่าเริ่มต้น false ค่า true ซ่อนหลังส่งปุ่มสำเร็จ
remove_keyboardbooleanไม่ใช่true ลบแป้น ห้ามใช้ร่วมกับตัวเลือกแป้นอื่น
sendMessage · reply_markup
{
  "chat_id": "USER_ID",
  "text": "เลือกบริการ:",
  "reply_markup": {
    "keyboard": [
      [
        {
          "text": "ตั้งค่าภาษา"
        },
        {
          "text": "ติดตามพัสดุ"
        }
      ],
      [
        {
          "text": "ตั้งค่าการแจ้งเตือน"
        },
        {
          "text": "กรอกเลขพัสดุ"
        }
      ]
    ],
    "resize_keyboard": true,
    "one_time_keyboard": false
  }
}
sendMessage · one_time_keyboard
{
  "chat_id": "USER_ID",
  "text": "เลือกบริการ:",
  "reply_markup": {
    "keyboard": [
      [
        "ตั้งค่าภาษา",
        "ติดตามพัสดุ"
      ]
    ],
    "one_time_keyboard": true
  }
}
sendMessage · remove_keyboard
{
  "chat_id": "USER_ID",
  "text": "ดำเนินการเสร็จแล้ว",
  "reply_markup": {
    "remove_keyboard": true
  }
}

getUpdates · รับข้อความ

#
POST/bot-api/<BOT_TOKEN>/getUpdates

เป็นการดึงแบบสั้น ไม่มีข้อความจะคืนอาร์เรย์ว่างทันที เรียกทุก 1–3 วินาทีและเพิ่มช่วงรอเมื่อผิดพลาด ยังไม่มี webhook สาธารณะหรือการดึงแบบยาว

หลังประมวลผลสำเร็จตั้ง offset เป็น update_id สุดท้าย + 1 เหตุการณ์ก่อนหน้าถือว่ายืนยันแล้ว หากล้มเหลวคง offset เดิมและใช้ update_id หรือคีย์ธุรกิจป้องกันซ้ำ

ประสานโปรแกรมที่รับข้อมูลบอตเดียวกันเพื่อไม่ให้เลื่อน offset ของกันและกัน ตรวจ content_type และ raw_content เมื่อไม่ใช่ข้อความ

พารามิเตอร์ชนิดจำเป็นคำอธิบาย
offsetintegerไม่ใช่ID เหตุการณ์ถัดไปจำนวนเต็มไม่ติดลบ ค่าเริ่มต้น 0
limitintegerไม่ใช่ครั้งละ 1–100 เหตุการณ์ ค่าเริ่มต้น 100
คำขอ
curl --fail-with-body --request POST \
  "https://im.ez7.life/bot-api/${EZLIFE_BOT_TOKEN}/getUpdates" \
  --header 'Content-Type: application/json' \
  --data '{"offset": 0, "limit": 100}'
การตอบกลับ
{
  "ok": true,
  "result": [
    {
      "update_id": 120,
      "message": {
        "message_id": "EXAMPLE_MESSAGE_ID",
        "date": 1794297600,
        "chat": {
          "id": "1000000001",
          "type": "private"
        },
        "from": {
          "id": "1000000001",
          "display_name": "Example User"
        },
        "text": "ตั้งค่าภาษา",
        "content_type": 101,
        "raw_content": "{\n  \"content\": \"ตั้งค่าภาษา\"\n}"
      }
    }
  ]
}
พารามิเตอร์คำอธิบาย
update_idID เพิ่มขึ้นสำหรับยืนยันการประมวลผล
message_idID ข้อความของแพลตฟอร์ม
dateเวลา Unix หน่วยวินาที
chatID ผู้ส่งในแชตส่วนตัวหรือ ID กลุ่ม พร้อมชนิด private/group
fromID และชื่อที่แสดงของผู้ส่งจริง
textเนื้อหาข้อความ อาจว่างสำหรับเหตุการณ์อื่น
content_typeชนิดเนื้อหา 101 คือข้อความ
raw_contentเนื้อหาต้นฉบับของรูป ไฟล์ และเหตุการณ์อื่น

โปรแกรม Python ฉบับเต็ม

#

ตัวอย่างเต็มใช้ไลบรารีมาตรฐาน Python รับ /start, /ping และชื่อปุ่ม พร้อมเก็บ offset เรียกในไดเรกทอรีส่วนตัว

แทนที่การจัดการปุ่มตัวอย่างด้วยงานจริง งานสั่งซื้อหรือชำระเงินต้องป้องกันการทำซ้ำก่อนบันทึกความคืบหน้า

bot.py
import json
import os
import time
import urllib.error
import urllib.request
from pathlib import Path

TOKEN = os.environ["EZLIFE_BOT_TOKEN"]
BASE = "https://im.ez7.life/bot-api/" + TOKEN
OFFSET_FILE = Path("bot-offset.json")
MENU = [
  [
    "ตั้งค่าภาษา",
    "ติดตามพัสดุ"
  ],
  [
    "ตั้งค่าการแจ้งเตือน",
    "กรอกเลขพัสดุ"
  ]
]

class ApiFailure(Exception):
    pass

class NoRedirect(urllib.request.HTTPRedirectHandler):
    def redirect_request(self, *args):
        return None

HTTP = urllib.request.build_opener(NoRedirect())

def api(method, payload):
    req = urllib.request.Request(
        BASE + "/" + method,
        data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with HTTP.open(req, timeout=20) as response:
            body = json.load(response)
    except urllib.error.HTTPError as error:
        raise ApiFailure("HTTP " + str(error.code)) from None
    except (urllib.error.URLError, TimeoutError, OSError, ValueError):
        raise ApiFailure("Network or response failure") from None
    if not body.get("ok"):
        raise ApiFailure("API error " + str(body.get("error_code", "unknown")))
    return body["result"]

def handle(update):
    message = update.get("message", {})
    chat = message.get("chat", {})
    text = message.get("text", "")
    if not chat.get("id"):
        return
    payload = {"chat_id": str(chat["id"]),
               "chat_type": chat.get("type", "private")}
    if text == "/start" and payload["chat_type"] == "private":
        payload.update(text="เลือกบริการ:", reply_markup={
            "keyboard": MENU, "resize_keyboard": True,
            "one_time_keyboard": False,
        })
    elif text == "/ping":
        payload["text"] = "pong"
    elif text in [label for row in MENU for label in row]:
        payload["text"] = "ดำเนินการเสร็จแล้ว"
    else:
        return
    api("sendMessage", payload)

def save_offset(value):
    temp = OFFSET_FILE.with_suffix(".tmp")
    fd = os.open(temp, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
    with os.fdopen(fd, "w", encoding="utf-8") as stream:
        json.dump(value, stream)
        stream.flush()
        os.fsync(stream.fileno())
    os.replace(temp, OFFSET_FILE)

def main():
    offset = json.loads(OFFSET_FILE.read_text()) if OFFSET_FILE.exists() else 0
    if isinstance(offset, bool) or not isinstance(offset, int) or offset < 0:
        raise ValueError("Invalid offset file")
    delay = 1
    while True:
        try:
            updates = api("getUpdates", {"offset": offset, "limit": 100})
            for update in updates:
                handle(update)
                next_offset = int(update["update_id"]) + 1
                save_offset(next_offset)
                offset = next_offset
            delay = 1
            time.sleep(2)
        except (ApiFailure, OSError, ValueError):
            print("Processing failed; offset retained. Check configuration.", flush=True)
            time.sleep(delay)
            delay = min(delay * 2, 30)

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        pass

กลุ่มและขอบเขตข้อความ

#

บอตต้องอยู่ในกลุ่มก่อน ค่าเริ่มต้นต้องให้เจ้าของอนุมัติ ตรวจคำเชิญที่แชตบอต → เพิ่มเติม → ตั้งค่าบอต → กลุ่มที่เข้าร่วม

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

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

ตั้งค่าบอตและตอบกลับอัตโนมัติ

#

เจ้าของเท่านั้นที่ตั้งค่าอนุมัติเข้ากลุ่ม เข้าถึงภายนอก รับรายกลุ่ม และคำตอบตามคำสำคัญ ปิดภายนอกจะเก็บ Token แต่ปฏิเสธการเรียก API

สูงสุด 50 กฎ คำสำคัญ 1–100 ตัวอักษร คำตอบ 1–2000 ตรวจการมีคำโดยไม่แยกตัวใหญ่เล็กตามลำดับ ตอบด้วยกฎที่เปิดและตรงข้อแรก

ตอบอัตโนมัติในแชตส่วนตัวและกลุ่มที่เปิดรับ พร้อมป้องกันบอตตอบต่อกันไม่จบ การเชื่อมต่อ AI API ยังเป็นแผน ไม่มีเมธอดสาธารณะ

จัดการข้อผิดพลาด

#

ข้อผิดพลาดรับข้อมูลเริ่มต้น เช่น JSON ผิดหรือเนื้อหาใหญ่เกิน ใช้ errorCode กับ message ข้อผิดพลาด API อื่นใช้ error_code กับ description ตรวจ HTTP และ ok ก่อนเสมอ

การตอบกลับ
{
  "ok": false,
  "error_code": 422,
  "description": "chat_id 与 1–5000 字的 text 为必填"
}
สถานะวิธีแก้ไข
400JSON ไม่ถูกต้อง ตรวจการเข้ารหัสและไวยากรณ์
401Token ไม่ถูกต้อง ถูกเพิกถอน ออกใหม่ หรือบอตถูกระงับ โปรดอัปเดตข้อมูลรับรอง
403เจ้าของปิดการเข้าถึงภายนอก เปิดในตั้งค่าบอต
404ตรวจเส้นทาง /bot-api/ รูปแบบ Token และชื่อเมธอด
409กำลังอัปเดตแป้นของบอต/ผู้ใช้เดียวกัน รอสักครู่แล้วลองใหม่
413เนื้อหาคำขอเกิน 1 MiB โปรดลดขนาด
422แก้พารามิเตอร์ รูปแบบรหัส หรือโครงสร้างแป้น
500ผิดพลาดชั่วคราว คง offset และเพิ่มเวลารอ ตรวจผลส่งก่อนลองใหม่

ข้อจำกัดและการรองรับไคลเอนต์

#

คู่มือนี้ตรงกับ API ปัจจุบัน ยังไม่มีเมธอดส่งสื่อ ปุ่ม inline callback ขอข้อมูลติดต่อ/ตำแหน่ง หรือ webhook สาธารณะ

แป้นตอบกลับต้องใช้ Web/H5 ปัจจุบัน แอปที่ฝัง H5 เก่าต้องอัปเดตจึงจะเห็นปุ่มใหม่

คำขอทั้งหมดสูงสุด 1 MiB ปรับความถี่ตามโหลดจริง คู่มือไม่รับประกันปริมาณงานคงที่ แฟล็กความสามารถกลุ่มไม่แทนการเข้าร่วม การอนุมัติ หรือสิทธิ์รับ