สร้าง Line Bot ง่ายๆ ด้วย Python: ตอบกลับข้อความทันใจ!

สวัสดีทุกคน! บทความนี้ไม่ได้จะมาสอนอะไรที่ซับซ้อนมากนะ แต่จะพาไปดูว่าการทำ Line Bot เนี่ยมันง่ายกว่าที่คิดเยอะ!

ส่วนตัวเคยคิดว่าทำ Line Bot มันต้องยุ่งยากแน่ๆ ทั้งเรื่อง API, Webhook อะไรไม่รู้เต็มไปหมด แต่พอได้ลองทำจริงๆ โค้ดมันไม่ได้เยอะเลย แถมใช้ Python นี่แหละ ง่ายสุดๆ ละ.

เราจะมาสร้างบอทที่ตอบกลับข้อความที่เราส่งไปแบบ 'Echo' หรือก็คือส่งข้อความที่เราพิมพ์ไปกลับมาหาเรานั่นแหละ.

สิ่งที่ต้องเตรียม

  1. บัญชี Line Developers: เข้าไปสร้าง Messaging API Channel ที่ developers.line.biz ตรงนี้จะได้ Channel Access Token กับ Channel Secret มา.
  2. ngrok: เอาไว้สร้าง Public URL ชั่วคราว ชี้มาเครื่องเรา เพราะ Line มันจะส่ง Webhook มาหา URL ที่เข้าถึงได้จากข้างนอก. โหลดได้ที่ ngrok.com.
  3. Python 3.x: แน่นอนละ
  4. pip install line-bot-sdk flask: ไลบรารีที่เราจะใช้.

ลุยโค้ดกันเลย!

มาเริ่มโค้ด Python กันก่อนดีกว่า ใช้ Flask ง่ายสุดละสำหรับงานแบบนี้.

from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import os

app = Flask(__name__)

# หาค่าจาก Line Developers Console
# แนะให้ใส่ใน Environment Variable ไม่ใช่ Hardcode แบบนี้นะ!
# แต่เพื่อความรวดเร็ว ขอแบบนี้ไปก่อน
CHANNEL_ACCESS_TOKEN = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', 'YOUR_CHANNEL_ACCESS_TOKEN')
CHANNEL_SECRET = os.getenv('LINE_CHANNEL_SECRET', 'YOUR_CHANNEL_SECRET')

line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(CHANNEL_SECRET)

@app.route("/callback", methods=['POST'])
def callback():
    # รับข้อมูล X-Line-Signature header
    signature = request.headers['X-Line-Signature']

    # รับข้อมูล Body ของ request
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # จัดการ webhook event
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        # เจอบ่อยมากๆ ตอนเซ็ตอัพ ถ้า Channel Secret ผิด หรือข้อมูลไม่ตรงกัน
        # Line จะบ่นว่า InvalidSignatureError
        # ตรวจดีๆ ว่าได้ Channel Secret มาถูกอันมั้ย
        # แล้วก็ดูว่าเวลาบนเครื่องเราตรงกับเวลาจริงไหม (บางทีก็เป็นเรื่องเวลา)
        print("Invalid signature. Please check your channel access token/channel secret.")
        abort(400)

    return 'OK'

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    # Echo message กลับไป
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text)
    )


if __name__ == "__main__":
    # ในโปรดักชั่นไม่ควรใช้ app.run() แบบนี้ตรงๆ นะ!
    # ใช้ Gunicorn หรือ uWSGI แทน
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

ข้อควรระวังสำคัญ: อย่าลืมเปลี่ยน YOUR_CHANNEL_ACCESS_TOKEN กับ YOUR_CHANNEL_SECRET ด้วยของจริงนะ! หรือจะใช้ Environment Variable ก็ได้ ปลอดภัยกว่าเยอะ

รัน ngrok เพื่อให้ Line คุยกับเครื่องเราได้

เปิด Terminal ขึ้นมา แล้วรันคำสั่งนี้:

ngrok http 5000

พอรันแล้ว ngrok มันจะให้ URL มา เช่น https://abcd1234.ngrok.io เราก็เอา URL นี้แหละ ไปใส่ในหน้า Line Developers Console ตรงส่วนของ Webhook URL แล้วตามด้วย /callback เช่น https://abcd1234.ngrok.io/callback

อย่าลืมกดปุ่ม Verify ในหน้า Line Developers ด้วยนะ ถ้า Verify ผ่านก็แสดงว่า Line คุยกับเครื่องเราได้แล้ว.

มาลองเทสกัน!

เปิด Line App ในมือถือ แล้วส่งข้อความไปหา Bot ของเราเลย! มันควรจะตอบกลับข้อความเดิมที่เราส่งไปหา.

ถ้าเจอ InvalidSignatureError เหมือนที่เขียนในโค้ด อันนี้ประสบการณ์ตรงเลยคือเช็ค CHANNEL_SECRET ดีๆ บางทีก็อปมาผิด หรือไปเอา Access Token มาใส่แทน Secret. อีกทีคือเรื่องเวลาบน server ที่รันโค้ด ถ้ามันไม่ตรงกับเวลาจริงมาก ๆ บางที Line ก็มีปัญหาได้.

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

แค่นี้แหละ! หวังว่าจะเป็นประโยชน์นะ!

Read more

ดราม่า "เบิร์ด วันว่างๆ" กับยาแนว: บทเรียนสำคัญของอินฟลูเอนเซอร์และความปลอดภัยบนโซเชียล

ดราม่า "เบิร์ด วันว่างๆ" กับยาแนว: บทเรียนสำคัญของอินฟลูเอนเซอร์และความปลอดภัยบนโซเชียล

เจาะลึกดราม่า "เบิร์ด วันว่างๆ" ใช้ยาแนวเล่นสงกรานต์ คำชี้แจง และผลกระทบต่อสังคม บทเรียนสำคัญสำหรับความรับผิดชอบของอินฟลูเอนเซอร์

By ทีมงาน devdog
Xiaomi 17T หลุดสเปคเด็ดบน Geekbench! ยืนยัน Dimensity 8500 พร้อมแบต 7,000mAh จ่อเปิดตัว

Xiaomi 17T หลุดสเปคเด็ดบน Geekbench! ยืนยัน Dimensity 8500 พร้อมแบต 7,000mAh จ่อเปิดตัว

Xiaomi 17T เตรียมเปิดตัว! พบข้อมูลบน Geekbench ยืนยันใช้ชิป Dimensity 8500 พร้อมแบตเตอรี่จุใจ 7,000mAh คาดบุกตลาดรองเรือธงเร็วๆ นี้

By ทีมงาน devdog
กยศ. เปิดทางรอด! ปรับโครงสร้างหนี้ออนไลน์ หยุดถูกฟ้อง ก่อน 5 ก.ค. 69

กยศ. เปิดทางรอด! ปรับโครงสร้างหนี้ออนไลน์ หยุดถูกฟ้อง ก่อน 5 ก.ค. 69

ผู้กู้ กยศ. กว่า 1 แสนราย เสี่ยงถูกฟ้อง! รีบปรับโครงสร้างหนี้ออนไลน์ผ่านเป๋าตัง/ThaID ก่อน 5 ก.ค. 69 รับสิทธิประโยชน์ ลดดอกเบี้ย หลีกเลี่ยงคดีความ

By ทีมงาน devdog
Baseus MC2: หูฟังคลิปหนีบหูสุดล้ำ แบตอึด 60 ชม. เสียง LDAC กันน้ำ IP67 เพื่ออิสระทางเสียงของคุณ

Baseus MC2: หูฟังคลิปหนีบหูสุดล้ำ แบตอึด 60 ชม. เสียง LDAC กันน้ำ IP67 เพื่ออิสระทางเสียงของคุณ

พบ Baseus MC2 หูฟังคลิปหนีบหูดีไซน์ล้ำ สวมใส่สบายตลอดวัน ด้วยแบตเตอรี่ 60 ชม., กันน้ำ IP67, เสียง LDAC ระดับ Hi-Res และราคาเข้าถึงง่าย

By ทีมงาน devdog