สร้าง Line Bot ง่ายๆ ด้วย Python: ตอบกลับข้อความทันใจ!
สวัสดีทุกคน! บทความนี้ไม่ได้จะมาสอนอะไรที่ซับซ้อนมากนะ แต่จะพาไปดูว่าการทำ Line Bot เนี่ยมันง่ายกว่าที่คิดเยอะ!
ส่วนตัวเคยคิดว่าทำ Line Bot มันต้องยุ่งยากแน่ๆ ทั้งเรื่อง API, Webhook อะไรไม่รู้เต็มไปหมด แต่พอได้ลองทำจริงๆ โค้ดมันไม่ได้เยอะเลย แถมใช้ Python นี่แหละ ง่ายสุดๆ ละ.
เราจะมาสร้างบอทที่ตอบกลับข้อความที่เราส่งไปแบบ 'Echo' หรือก็คือส่งข้อความที่เราพิมพ์ไปกลับมาหาเรานั่นแหละ.
สิ่งที่ต้องเตรียม
- บัญชี Line Developers: เข้าไปสร้าง Messaging API Channel ที่ developers.line.biz ตรงนี้จะได้ Channel Access Token กับ Channel Secret มา.
- ngrok: เอาไว้สร้าง Public URL ชั่วคราว ชี้มาเครื่องเรา เพราะ Line มันจะส่ง Webhook มาหา URL ที่เข้าถึงได้จากข้างนอก. โหลดได้ที่ ngrok.com.
- Python 3.x: แน่นอนละ
- 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 ก็ค่อนข้างตรงไปตรงมา ไม่ได้มีฟีเจอร์ซับซ้อนอะไรให้งงเยอะ. เหมาะกับการทำอะไรเล็กๆ น้อยๆ เพื่อเพิ่มความสะดวกสบายมากๆ เลยนะ.
แค่นี้แหละ! หวังว่าจะเป็นประโยชน์นะ!