Line Covid Chatbot ด้วย Dialogflow และ Python

ผู้เขียนบทความ : นายปัณณวัชญ์ ตราทองคำ coe#12

1. ความเป็นมา

 เนื่องจากเชื้อไวรัสโคโรน่าสายพันธุ์ใหม่ 2019 หรือ COVID-19 เป็นไวรัสข้ามสายพันธุ์ที่สันนิษฐานว่าเกิดจากค้างคาวมาติดเชื้อในคน โดยเริ่มระบาดในมณฑลอู่ฮั่นของประเทศจีนในช่วงปลายปี ค.ศ.2019 จนกระทั่งมีการระบาดไปยังประเทศอื่นๆ ทั่วโลก สถานการณ์การแพร่ระบาดของ COVID-19 มีความรุนแรงเพิ่มมากขึ้น ปัจจุบันสถานการณ์การแพร่ระบาดของเชื้อ COVID-19 มีความรุนแรงเพิ่มขึ้นอย่างต่อเนื่อง องค์การอนามัยโลกได้ประกาศว่าการแพร่ระบาดของเชื้อดังกล่าวเป็นภัยพิบัติฉุกเฉินระดับโลก เพื่อให้ประชาชนสามารถเข้าถึงข้อมูลรายงานสถานการณ์ COVID-19 ได้ ผู้เขียนจึงได้จัดทำ LINE COVID CHATBOT ขึ้นมาเนื่องจาก LINE เป็นแอปพลิเคชันที่ทุกคนใช้งานกันในชีวิตประจำวันอยู่ทั่วไปแล้วนั้นเอง

2. วัตถุประสงค์

2.1 เพื่อศึกษาหาความรู้ในการใช้ภาษา Python
2.2 เพื่อพัฒนาโปรแกรม Chatbot ที่ใช้ในการรับข้อมูลข่าวสารเกี่ยวกับ Covid ไปประยุกต์ใช้ได้จริง
2.3 เพื่อนำความรู้ที่ได้ไปใช้ต่อยอดในการศึกษาและการทำงาน

3. ขอบเขต

3.1 โปรแกรม Chatbot สามารถรองรับการทำงานได้ทั้งใน PC, IOS และ Andriod
3.2 โปรแกรม Chatbot สามารถแสดงข้อมูลโควิด-19 ได้

4. ประโยชน์ที่คาดว่าจะได้รับ

4.1 ผู้ใช้สามารถใช้โปรแกรม Line Chatbot เพื่อตรวจสอบข้อมูลโควิด-19 ได้
4.2 มีคำสั่งเฉพาะเพื่อค้นหาเพียงข้อมูลที่ต้องการทราบ

5. ความรู้ที่เกี่ยวข้อง

ในส่วนกระบวนการการทำงานของทั้งระบบนั้นผู้เขียนได้ทำเป็นภาพแสดงการทำงานโดยย่อไว้ดังนี้

5.1 API

สำหรับระบบนี้สิ่งที่สำคัญที่สุดและไม่สามารถขาดไปได้เลยคือ API หรือ Application Programing Interface ซึ่งเป็นบริการช่องทางในการเชื่อมต่อเพื่อแลกเปลี่ยนข้อมูลจากระบบหนึ่งไปอีกระบบหนึ่ง ซึ่งผู้เขียนได้ใช้บริการ LINE Messaging API ของ LINE Developer เพื่อใช้งาน Chatbot GUI และส่วนต่อมาคือบริการข้อมูล COVID-19 API ของกรมควบคุมโรค

API ที่ใช้ในระบบ
กรมควบคุมโรค รายงานสถานการณ์ โควิด-19
LINE Messaging API

ในส่วนของ LINE Messaging API สามารถดูวิธีการใช้บริการได้ที่หัวข้อ 5.3 ด้านล่างนี้เลย

ในส่วนของ COVID-19 API นั้นทางผู้ให้บริการได้ให้ API มาในรูปแบบ JSON ซึ่ง JSON เป็นข้อมูลรูปแบบ text ที่มีการเก็บข้อมูลในรูปแบบ key, value

ยกตัวอย่างข้อมูลใน COVID-19 API

{"Confirmed":28863}

จะให้ได้ว่าข้อมูลใน API นี้เป็นรูปแบบ JSON โดยมี key คือ Confirmed และ value คือค่าด้านหลังซึ่งมีการอัพเดทเปลี่ยนแปลงตามผู้ให้บริการ ซึ่งในหนึ่ง JSON API สามารถเก็บข้อมูลได้หลายตัวด้วยกัน เช่น

{"Confirmed":28863,"Recovered":27426,"Hospitalized":1343,"Deaths":94}

โดยเราสามารถเข้าถึงข้อมูลได้ด้วยการใช้ภาษา Python โดยใช้ Library JSON และ Requests ซึ่งมีเขียนอธิบายด้านล่างในหัวข้อที่ 5.5

5.2 ภาษา Python และ Virtual Environments venv

ส่วนแรกที่ต้องใช้คือ พื้นฐานการใช้ภาษา Python ทั่วไป โดยผู้เขียนใช้ Virtual Environments venv ในการทำโปรเจคนี้

เริ่มแรกให้สร้างโฟลเดอร์ที่ต้องการเก็บไฟล์โครงงานขึ้นมาก่อน จะสร้างชื่ออะไรก็ได้ ไปที่ path ข้างบนพิมพ์ว่า cmd เพื่อเปิด command line จากนั้นให้พิมพ์คำสั่งว่า

pip install virtualenv

เมื่อพิมพ์เสร็จให้สร้าง virtualenv ตามด้วยชื่อ โดยผู้เขียนได้ตั้งชื่อโฟลเดอร์ว่า venv

virtualenv venv

เมื่อสร้างเสร็จจะมีโฟลเดอร์ venv ปรากฏขึ้น ภายในจะเป็น python กลับมาที่ cmd ต่อจากนั้นให้พิมพ์ว่า

venv\Scripts\activate 

จะเห็นว่า path ของเราเปลี่ยนไปเป็นมี (venv) มาอยู่ข้างหน้าแล้ว ให้เราพิมคำสั่งว่า

code . 

เพื่อเข้าไปที่ Text Editor ของ vscode

เมื่อเปิดมาแล้วโปรกรม vs code จะทำงานอยู่ภายใน venv เวลาจะ install ก็ต้อง activate ก่อนมันถึงจะเรียกใช้ได้  ถ้าไม่ activate ก่อนมันจะไม่สามารถทำงานได้ เพราะมันเรียกหาไฟล์แพตเกจต่างๆที่เราลงไว้ไม่เจอ เพราะทุกอย่างอยู่ใน venv ทั้งหมด และเราสามารถเช็คได้ด้วยว่ามันทำการ activate ให้เรารึยังจากรูปด้านล่างเลย ถ้าทำการ active แล้วมันจะขึ้นมาให้แถบฟ้าๆ

5.3 Line Messaging Api

เพื่อให้เราสามารถใช้งานโปรแกรม Chat bot ของ LINE ได้ เราจำเป็นต้องสมัคร LINE Developer เพื่อขอการใช้งาน Messaging API โดยในที่นี้ผู้เขียนขอไม่ลงรายละเอียด แต่สามารถทำตามแหล่งอ้างอิงที่ผู้เขียนได้ทำตามได้เลย

ปฐมบทการสร้าง LINE Bot

ซึ่งเมื่อเราสร้างเสร็จสิ้นตามทุกขั้นตอนแล้ว ก็ให้เราทำการเพิ่ม LINE Chat bot เพื่อใช้งานในขั้นต่อไป

5.4 การใช้ Dialogflow

ในส่วนต่อมาคือ Dialogflow เราใช้เพื่อสร้าง Intent ในการโต้ตอบระหว่างผู้ใช้กับ Chat bot 
สามารถสมัครใช้งานได้ที่ Link : https://dialogflow.cloud.google.com/#/getStarted

เมื่อสมัครใช้งานเสร็จเรียบร้อยแล้ว ให้ทำการเชื่อมต่อการใช้งานกับ LINE หลังจากนั้นใช้เพื่อสร้าง Intent ในการโต้ตอบระหว่างผู้ใช้กับ Chat bot ซึ่งผู้เขียนได้ทำการใส่อ้างอิงข้อมูลการใช้งาน Dialogflow ไว้แล้วในส่วนอ้างอิง

5.5 Library JSON, Flask และ Requests

ก่อนที่จะไปลงรายละเอียดในการใช้งาน Library แต่ละตัวนั้นมาดูที่วิธีการติดตั้งกันก่อน โดยผู้เขียนใช้ Flask Microframework เพื่อใช้งาน Python ร่วมกับ webserver และใช้ Requests ซึ่งเป็น HTTP Library โดยให้พิมพ์คำสั่งเพื่อติดตั้ง Flask และ Requests

pip install flask

และ

pip install requests

หลังจากที่ติดตั้งเสร็จเรียบร้อยแล้ว ในส่วน Library ที่ผู้เขียนใช้เป็นหลักนั้น ส่วนแรกคือ JSON encoder and decoder โดยใช้สำหรับการอ่านและเขียน JSON ซึ่งมีคำสั่งต่างๆที่จำเป็นต้องใช้อยู่ใน Library นี้ โดยเราสามารถเรียกใช้คำสั่งได้โดยการเขียนโค้ดว่า

import json

และคำสั่งที่จำเป็นต้องใช้เพื่อแปลงข้อมูล JSON เพื่ออ่านและส่งข้อมูลมีดังนี้

json.dumps()
คือการแปลง Python Object (Dict) ไปเป็น JSON String หรือ Object

json.loads()
คือการแปลง JSON  String ไปเป็น Python Object (Dict)

ต่อมาในส่วนของ Library Requests สามารถเรียกใช้งานโดยเขียนโค้ดไว้ว่า

import requests

หลังจากนั้นให้เขียนโค้ดดังนี้เพื่อเก็บข้อมูล API ไว้

r = requests.get('ลิ้งของผู้ให้บริการ API', auth=('user', 'pass'))
--หากในส่วนผู้ให้บริการ API ไม่ได้มีการเข้ารหัสไว้สามารถเขียนได้ดังนี้
r = requests.get('https://covid19.th-stat.com/api/open/today')

ต่อมาในส่วนของ Library Flask ผู้เขียนใช้เพื่อสร้าง web server ในการเชื่อมต่อระหว่าง Dialogflow โดยสามารถเรียกใช้งานได้ดังนี้

from flask import Flask

หลังจากนั้นเราใช้ Flask เพื่อเขียนให้โปรแกรมของเราทำงานในรูปแบบ web server โดยใช้ port localhost:5000

# Flask HTTP METHOD
app = Flask(__name__)

@app.route('/', methods=['POST', 'GET'])
---
ใส่ฟังก์ชันของโปรแกรมตามต้องการ
---
#Flask deploy web server on http port 5000 
if __name__ == '__main__':
    port = int(os.getenv('PORT', 5000))
    print("Starting app on port %d" % port)
    app.run(debug=False, port=port, host='0.0.0.0', threaded=True)

5.6 Ngrok

Ngrok เป็นตัวช่วยในการทำให้ localhost server ของเรามี public url ทำให้เราสามารถทำ url นี้ไปใช้ webhook เพื่อติดต่อสื่อสารส่งข้อมูลกับ Dialogflow ได้ สามารถดูรายละเอียดวิธีใช้งานได้ในหัวข้อต่อไป

6.ผลการดำเนินงาน

ตัวอย่างภาพการทำงานของระบบโดยเริ่มการทำงานที่ผู้ใช้สามารถดูได้ดังรูป

เริ่มต้นการทำงานโปรแกรมด้วยการรันโปรแกรมใน Python

เมื่อรันแล้วจะเห็นได้ว่า มีการใช้งานบน Port 5000 ให้เราไปที่ Ngrok เพื่อสร้าง public url ให้พิมพ์คำสั่งว่า

ngrok http 5000


เมื่อรันแล้วจะได้ public url ให้เรา copy เพิ่อไปเชื่อมต่อ webhook ใน dialogflow

หลังจากนั้นกด Save แล้วสามารถใช้งาน LINE Chat bot ได้เลย

ในขั้นตอนแรกเป็นการใช้คำสั่ง help เพื่อแสดงวิธีการใช้คำสั่งทั้งหมดในการแสดงข้อมูล


สามารถเรียกข้อมูลโควิด-19 ได้ตามคำสั่งดังรูป

นอกจากนี้หากใช้แอพ LINE ใน IOS หรือ Android จะมีส่วนที่เรียกว่า Rich Menu ซึ่งลิ้งตรงกับรายงานสถานการณ์โควิด-19 ของกรมควบคุมโรคได้โดยตรง โดยไม่ต้องพิมพ์คำสั่ง

โค้ดทั้งหมด

#Import Library
#import statements load Python code that allow us to work with the JSON data format and the HTTP protocol.
import json
import os
import requests
from flask import Flask
from flask import request
from flask import make_response

# Flask
app = Flask(__name__)

@app.route('/', methods=['POST', 'GET'])

def MainFunction():

    #รับ intent จาก DailogflowJay
    question_from_dailogflow_raw = request.get_json(silent=True, force=True)

    #เรียกใช้ฟังก์ชัน generate_answer เพื่อแยกส่วนของคำถาม
    answer_from_bot = generating_answer(question_from_dailogflow_raw)
    
    #ตอบกลับไปที่ Dailogflow
    r = make_response(answer_from_bot)
    r.headers['Content-Type'] = 'application/json' #การตั้งค่าประเภทของข้อมูลที่จะตอบกลับไป

    return r

def generating_answer(question_from_dailogflow_dict):

    #Print intent ที่รับมาจาก Dailogflow
    print(json.dumps(question_from_dailogflow_dict, indent=4 ,ensure_ascii=False))

    #เก็บต่า ชื่อของ intent ที่รับมาจาก Dailogflow
    intent_group_question_str = question_from_dailogflow_dict["queryResult"]["intent"]["displayName"] 

    #ลูปตัวเลือกของฟังก์ชั่นสำหรับตอบคำถามกลับ
    if intent_group_question_str == 'dev':
        answer_str = covid_dev()
    elif intent_group_question_str == 'covid':
        answer_str = covid_today()
    elif intent_group_question_str == 'confirmed':
        answer_str = c_confirmed()
    elif intent_group_question_str == 'recovered':
        answer_str = c_recovered()
    elif intent_group_question_str == 'hospitalized':
        answer_str = c_hospitalized()
    elif intent_group_question_str == 'deaths':
        answer_str = c_deaths()   
    elif intent_group_question_str == 'test_text':
        answer_str = test_text()
    else: answer_str = "Error"

    #สร้างการแสดงของ dict 
    answer_from_bot = {"fulfillmentText": answer_str}
    
    #แปลงจาก dict ให้เป็น JSON
    answer_from_bot = json.dumps(answer_from_bot, indent=4) 
    
    return answer_from_bot
    
def test_text():
    answer_function = 'ข้อความจาก python'
    return answer_function

def covid_today():
    data = requests.get('https://covid19.th-stat.com/api/open/today')
    json_data = json.loads(data.text)

    json_confirmed = json_data['Confirmed']
    c_confirmed = json.dumps(json_confirmed)

    json_recovered = json_data['Recovered']
    c_recovered = json.dumps(json_recovered)

    json_hospitalized = json_data['Hospitalized']
    c_hospitalized = json.dumps(json_hospitalized)

    json_deaths = json_data['Deaths']
    c_deaths = json.dumps(json_deaths)

    answer_function = 'ยอดติดเชื้อสะสม : ' + c_confirmed + ' คน\n' + 'รักษาหายแล้ว : ' + c_recovered + ' คน\n' + 'รักษาอยู่ในโรงพยาบาล : ' + c_hospitalized + ' คน\n' + 'เสียชีวิต : ' + c_deaths + ' คน'
    return answer_function

def covid_dev():
    c = requests.get('https://covid19.th-stat.com/api/open/today')
    c.json()
    data = json.loads(c.text)
    data = json.dumps(data)
    answer_function3 = data
    #answer_function2 = '{"line":{"text": ' + data + ',"type": "text"} }'
    return answer_function3

def c_confirmed():
    data = requests.get('https://covid19.th-stat.com/api/open/today')
    json_data = json.loads(data.text)
    covid = json_data['Confirmed']
    c_confirmed = json.dumps(covid)
    answer_function = 'ยอดติดเชื้อสะสม : ' + c_confirmed + ' คน'
    return answer_function

def c_recovered():
    data = requests.get('https://covid19.th-stat.com/api/open/today')
    json_data = json.loads(data.text)
    covid = json_data['Recovered']
    c_recovered = json.dumps(covid)
    answer_function = 'รักษาหายแล้ว : ' + c_recovered + ' คน'
    return answer_function

def c_hospitalized():
    data = requests.get('https://covid19.th-stat.com/api/open/today')
    json_data = json.loads(data.text)
    covid = json_data['Hospitalized']
    c_hospitalized = json.dumps(covid)
    answer_function = 'รักษาอยู่ในโรงพยาบาล : ' + c_hospitalized + ' คน'
    return answer_function

def c_deaths():
    data = requests.get('https://covid19.th-stat.com/api/open/today')
    json_data = json.loads(data.text)
    covid = json_data['Deaths']
    c_deaths = json.dumps(covid)
    answer_function = 'เสียชีวิต : ' + c_deaths + ' คน'
    return answer_function

#Flask 
if __name__ == '__main__':
    port = int(os.getenv('PORT', 5000))
    print("Starting app on port %d" % port)
    app.run(debug=False, port=port, host='0.0.0.0', threaded=True)

7. สรุปผลและข้อเสนอแนะ

โปรแกรมสามารถใช้งานได้อย่างถูกต้องและไม่มีปัญหา ทั้งนี้มีองค์ประกอบอย่างอื่นขึ้นอยู่กับผู้ใช้ เช่น พิมพ์คำสั่งไม่ถูกต้อง การเชื่อมต่ออินเตอร์เน็ตไม่เสถียร หรือจากฝั่งผู้ให้บริการข้อมูล เช่น กรมควบคุมโรคมีการอัพเดทข้อมูล หรือ การข้อผิดพลาดทำให้ไม่สามารถให้บริการข้อมูล API ได้ และในส่วนของทางฝั่งโปรแกรมผู้เขียนได้ใช้ ngrok ได้การเปิด public url ซึ่งต้องทำทุกครั้ง ทำให้ลำบากต่อการแก้ไข
ข้อเสนอแนะ
– การประยุกต์ใช้กับ Database Server หรือ Public Server จะทำให้สามารถดึงประสิทธิของการใช้งานมาได้ดีกว่าหากเทียบกับการใช้งานในรูปแบบ localhost ที่เครื่องของผู้เขียนเอง แต่อาจมีค่าใช้จ่ายในส่วน Server เพิ่มเติมเข้ามา
– ในส่วนของผู้ให้บริการข้อมูล API อย่างกรมควบคุมโรค มีการอัพเดทข้อมูลที่ล่าช้าในบางครั้ง และหากเกิดปัญหาที่ทำให้ไม่สามารถเรียกข้อมูลมาได้ จะทำห้ไม่สามารถเรียกใช้งานในส่วนของโปรแกรมนี้ได้เลย

8.ข้อมูลอ้างอิง

  1. API ที่ใช้ในระบบ
    กรมควบคุมโรค รายงานสถานการณ์ โควิด-19
    LINE Messaging API
  2. ข้อมูลอ้างอิงเกี่ยวกับการใช้งาน Python 
    venv
    การใช้งาน JSON ร่วมกับ Python ครบจบในบทความเดียว
    ใช้ Python ดึงข้อมูล API ของ Corona-virus (COVID-19)
    Python API Tutorial: Getting Started with APIs
    Documentations for the API — v.1
    ดึงข้อมูล COVID-19 จาก API ที่ส่งค่ากลับมาเป็น JSON ด้วย Python
    สร้าง CHATBOT ด้วย PYTHON
    How To Use Web APIs in Python 3
    API Integration in Python
    HTTP Requests in Python 3
    Python – Convert JSON to string
  3. ข้อมูลอ้างอิงเกี่ยวกับการใช้ LINE และ Dialogflow
    สอน+วิธีทำ Line Messaging Api
    สร้าง Line Chatbot ด้วย Dialogflow, Python, และ Firebase🔥🔥🔥 ง่ายมากๆ!!!
    Building LINE Chatbot using DialogFlow
    ใช้งาน Dialogflow ผ่าน API detectIntent
    วิธีใช้ Message objects เพิ่มลูกเล่นในการตอบกลับของ Line บน Dialogflow ด้วย Custom payload
    [Dialogflow x LINE] สร้าง Chatbot LINE แบบง่ายๆ ด้วย Dialogflow และ LINE Bot Designer กันเถอะ
    Webhook client
  4. ข้อมูลอ้างอิงเกี่ยวกับการใช้ Flask
    Flask — เริ่มต้นเขียนเว็บง่ายๆด้วย Flask
    Chatbot03 : Backend web service with Flask
    Line API กับเขียน Python ใช้ Flask รับค่าจาก API
  5. ข้อมูลอ้างอิงจาก Youtube
    Python Line Chatbot
    Python using JSON web API | EP.1 อัพเดทสถานการณ์ Covid-19 และแจ้งเตือนผ่าน Line Notify
    EP 18 การประยุกต์ใช้ LIFF กับ ริชเมนูและ Line Chat Bot
    ดึงข้อมูล COVID-19 จาก API ที่ส่งค่ากลับมาเป็น JSON ด้วย Python
    คอร์สเรียน Python REST APIs with Flask สำหรับมือใหม่ (Full Course)
    ทดสอบ LINE Chatbot ที่พัฒนาด้วย LINE Messaging API เเบบไม่ต้อง Deploy ขึ้นเซิฟเวอร์ 
Share

You may also like...

Leave a Reply