django – as a Dialogflow Webhook #03

บทความนี้ จะกล่าวถึง การใช้ django ทำหน้าที่เป็น Webhook จาก Dialogflow ผ่าน Fulfillment ทาง HTTP Post Request ด้วย JSON object และ ทำการประมวลผล แล้วตอบกลับไปเป็น JSON Object เช่นกัน เพื่อให้ Dialogflow ตอบสนองต่อผู้ใช้ได้ตามต้องการ เช่น อาจจะให้ไปค้นข้อมูลจากฐานข้อมูลในองค์กรมาตอบ เป็นต้น

Source: https://dialogflow.com/docs/intro/fulfillment

ในมุมของ django django (ดี)จังโก้ ดีอย่างไร #01 ได้กล่าวถึงการสร้าง Web Application จาก Model โดยกำหนด Fields ต่าง ๆ จากนั้น django ก็จะสร้าง Web Form ต่าง ๆ ให้อัตโนมัติ และยังสามารถสร้าง Users ของระบบ พร้อมทั้ง กำหนดสิทธิ์การเข้าถึงของแต่ละคนได้อีกด้วย แล้วนำไปผูกกับส่วน Admin เพื่อให้ผู้ใช้ทำการ Authentication ก่อนเข้าจัดการกับข้อมูลต่างได้ และในบทความ django – Deploy to Production #02 ได้แนะนำวิธีการ Deploy ระบบที่สร้างขึ้นสู่ Production ตามลำดับ

ในบทความนี้ จะใช้ “view” ซึ่งเป็นอีกส่วนของ django ตามขั้นตอนต่อไปนี้

ใน myproject สร้าง App ใหม่ ชื่อ fulfillment

python manage.py startapp fulfillment

เพิ่ม ‘fulfillment’ app ลงใน myproject/settings.py ที่ INSTALLED_APPS
( ในตัวอย่างก่อนหน้า เราเพิ่ม worklog app ไว้แล้ว) 

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'worklog',
    'fulfillment'
]

จากนั้น แก้ไขไฟล์ myproject/fulfillment/views.py ตามนี้

from django.http import HttpRequest, HttpResponse
from django.views.decorators.csrf import csrf_exempt
import json
# Create your views here.
@csrf_exempt
def sayHi(request):
    j = json.loads(request.body)
    x = {  "fulfillmentText": "This is a text response"
        }
    return HttpResponse(json.dumps(x))

ในส่วนนี้ จะ import packages ต่อไปนี้

  • HttpRequest เพื่อรับ Input ผ่าน HTTP
  • HttpResponse เพื่อตอบ Output ผ่าน HTTP
  • csrf_exempt เพื่อบอกว่า ยอมให้ทำงานผ่าน HTTP POST โดยไม่ต้องมี CSRF Token (ถ้าไม่ใส่ อยู่ ๆ จะส่ง POST เข้ามาไม่ได้ )
  • json เพื่อจัดการ JSON object

จากนั้น สร้าง Function ชื่อ “sayHi” มี function ที่เรียกใช้งานดังนี้

  • json.loads(request.body) ทำหน้าที่แปลง JSON Object จาก HTTP Request เข้ามาอยู่ในรูป Python Object ในที่นี้ จะนำข้อมูลจาก Dialogflow Fulfillment ที่ได้จาก Intent Matching และ Parameter Extraction ส่งมา
  • json.dumps(x) ทำหน้าที่แปลงข้อมูล จาก Python Object (ในรูปแบบ dict) ไปเป็น JSON Object ในที่นี้ แปลง { “fulfillmentText” : “This is a text response” } ไปเป็น JSON Object แล้วตอบกลับไปทาง HTTP Response

ต่อไป สร้างไฟล์ myproject/fulfillment/urls.py เพื่อกำหนด URL ที่จะเรียกใช้ function ดังนี้

from django.urls import path
from . import views
urlpatterns = [    
	path('hi', views.sayHi )
]

ในส่วนนี้ import package “path” เข้ามา และ import views ที่สร้างขึ้นใน ‘fulfillment’ app และกำหนดว่า เมื่อการเรียก “hi” ให้ไปเรียก function “sayHi” ซึ่งเป็น views

สุดท้าย แก้ไขไฟล์ myproject/urls.py เพื่อเพิ่ม URL path ให้ fulfillment

from django.contrib import admin
from django.urls import path, include
urlpatterns = [
	path('admin/', admin.site.urls),
	path('fulfillment/', include('fullfillment.urls'))
]

เมื่อมีการเรียก http://server-domain/fulfillment/ ก็จะส่งไปให้ views ใน fulfillment ทำงาน โดย Include fulfillment.urls เข้ามา

เมื่อเรียก  http://server-domain/fulfillment/hi ก็จะไปเรียก function sayHi ที่เขียนข้างต้นนั่นเอง

Dialogflow Fulfillment

ใน Dialogflow Console คลิกที่ Fulfillment แล้ว Enable Webhook จากนั้นใส่ URL ของ django production server ที่เราสร้างขึ้น ในตัวอย่างจะเป็น

https://xxxxxxxxx.psu.ac.th/fulfillment/hi

จากนั้น กดปุ่ม Save ด้านล่าง (ในทางปฏิบัติจริง ๆ ต้องมีเรื่อง Authentication/Authorization อีกพอสมควร แต่ในตัวอย่างนี้ ทำแบบง่าย ๆ ก่อน)

ต่อไป สร้าง Intent ชุดที่ต้องการให้ส่งให้ Fulfillment ทำงาน แล้วก็คลิกที่ Fulfillment > Enable webhook call for this intent แล้ว Save

จากนั้น ลองทดสอบดู จะเห็นได้ว่า Default Response จะแสดงข้อความ “This is a text response” แทนที่จะเป็น Text Response ที่กำหนดใน Intent นั้น

ลองคลิก Diagnostic Info

จะเห็นว่า มี fulfillmentText เป็น “This is a text response” ตามที่เขียนไว้ เป็นอันว่า Dialogflow สามารถเชื่อมต่อไปยัง django Webhook ที่สร้างขึ้นได้แล้ว

หวังว่าจะเป็นประโยชน์ครับ