# Build your own Chatbot
- The source code of the chatbot is about the research published in Conference IS3C2020:
[Visit here to view source code](https://github.com/shawnlintw/LINE_bot_assistant.git)
- This steps is record that how to build a line chatbot via Django freamwork.
<h2>
Create a new django project
</h2>
1. Switch to python enviroment
2. Create a new django project :
`django-admin startproject PROJECT_NAME`
3. Create a new django app :
`python manage.py startapp APP_NAME`
4. Create "static" folder :
`mkdir -p static`
5. Create "templates" folder :
`mkdir -p templates`
6. This will create or update the database
```
python manage.py makemigrations
python manage.py migratie
```
7. Edit the setting.py. setting.py is the configure file of project.
1. Enable/Disable debug mode change the setting in line 26
``` DEBUG = True/Flase ```
2. Add APP that you create into project configure. add APP_NAME into "INSTALLED_APPS" list
```
INSTALL_APPS =[
'django.contrib.admin',
'django.contrin.auth',
.
.
.
'APP_NAME', # The App you create.
]
```
3. Setting the path of template
```
TEMPLATES =[
'BACKEND':'django.template.backends.django.DjangoTemplates',
'DIRS' :[os.path.join(BASE_DIR, 'templates')],
'APP_DIRS' : True,
]
```
4. Setting the path of static
```
STATIC_URL='/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR, 'static'),
]
```
5. Setting the timezone and language
```
LANGUAGE_CODE= 'zh-Hant' # Traditional Chinese
TIME_ZONE ='Asia/Taipei'
```
8. Edit the urls.py
1. For example : Add two functions that named say_hello, hello2
```
from django.conf.urls import url
from APP_NAME.views import sayhello,hello2
urlpatterns =[
path('admin/', admin.site.urls),
url(r'^$', sayhello),
url(r'^hello2/(\w+)/$', hello2)
]
```
10. Define the application function ( all function define in views.py )
1. For example : Add two functions that named say_hello, hello2
```
form django.http import HttpResponse
.
.
.
def sayhello(request):
return HttpResponse("Hello Django!")
def hello2(request, username):
return HttpResponse("Hello" + username)
```
11. Now we use the template to display instand of HttpResponse
1. Add a new function named hello3.
1. In views.py (locals() means pass all local variables to render function.)
```
from django.shortcuts import render
from datetime import datetime
def hello3(request, username):
now=datetime.now()
return render(request, "hello3.html", locals())
```
2. In urls.py
```
url(r'^hello3/(\w+)/$', hello3),
```
3. Create hello3.html in template folder.
```
<!DOCTYPE html>
<html>
<head>
<meta charset = 'utf-8'>
<title> First template </title>
</head>
<body>
<h1> Welcome {{username}} </h1>
<h2> Now is {{now}} </h2>
</body>
</html>
```
12. Execute service
```
python manage.py runserver
```
<h2>
Use Django Database
</h2>
1. Define data table class in model.py
2. create the middleware between database and django by use:
```
python manage.py makemigrations
```
3. Updata database
```
python manage.py migrate
```
For example:
1. Create a data table name db_test. Add db class to model.py
```
from django.db import models
class db_test(models.Model):
cName = models.CharField(max_length =20, null=False)
cSex = models.CharField(max_length =2, default='M', null=False)
cEmail = models.EmailField(max_length=100, blank=True, default = '')
def __str__(self):
return self.cName
```
2. Then Update the Database
```
python manage.py makemigrations
python manage.py migrate
```
3. Manage database by using django backend management.
1. Edit database class in model.py to admin.py.
```
form APP_NAME.models import db_test
#Register your models here.
admin.site.register(db_test)
```
2. Create the user account for database manager.
```
python manage.py createsuperuser
```
3. Running the service and open Browser and open web site in 127.0.0.1:8000/admin/
4. Database inquiry by using the models method : objects.get() and objects.all()
```
datatable.objects.get(inquiry arg)
```
1. For example : Display data by using Template. Add these line in urlpatterns section in urls.py
```
url(r'^listone/$',listone),
url(r'^listall/$',listall),
```
2. Then create the instance in views.py
```
from APP_NAME.models import db_test
def listone(request):
try:
unit= db_test.objects.get(cName="shawn") # inquire one record.
except:
errormessage=("Reading Failed.")
return render(request, "listone.html",locals())
def listall(request):
try:
names= db_test.objects.all().order_by('id') # inquire all records and sort by id.
except:
errormessage=("Reading Failed.")
return render(request, "listall.html",locals())
```
3. Create listone.html in template folder:
```
<!DOCTYPE html>
<html>
<head>
<title>Show one Record </title>
</head>
<body>
<h2>Errormessage : {{errormessage}}</h2>
No.: {{unit.id}} <br />
Name: {{unit.cName}} <br />
Sex: {{unit.cSex}} <br />
Email: {{unit.cEmail}} <br />
</body>
</html>
```
4. Create listall.html in template folder:
```
<!DOCTYPE html>
<html>
<head>
<title>Show all Records </title>
</head>
<body>
<h2>Errormessage : {{errormessage}}</h2>
<table border="1" cellpadding ="0" cellspacing = "0">
<th>No.</th> <th>Name</th> <th>Sex</th> <th>Email</th>
{% for name in names %}
<tr>
<td> {{name.id}}</td>
<td> {{name.cName}} </td>
<td> {{name.cSex }} </td>
<td> {{name.cEmail}}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
```
5. Add Insert Delete record
1. Add record :
1. edit in views.py
```
def insert(request):
unit = db_test.objects.create(cName='Alex', cSex='F', cEmail='Alex@test.com.tw')
unit.save()
names = db_test.objects.all().order_by('-id')
return render(request, "listall.html", locals())
```
2. Add these line in urlpatterns section in urls.py
```
url(r'^insert/$', views.insert),
```
2. Modify record :
1. edit in views.py
```
def modify(request):
unit=db_test.objects.get(cName='Alex')
unit.cEmail='Alex_1@test.com.tw'
unit.save()
names=db_test.objects.all().order_by('-id')
return render(request, "listall.html", locals())
```
2. Add these line in urlpatterns section in urls.py
```
url(r'^modify/$',views.modify),
```
3. Delete record :
1. edit in views.py
```
def delete(request, cName=''):
unit = db_test.objects.get(cName='Alex')
unit.delete()
names=db_test.objects.all().order_by('-id')
return render(request, "listall.html", locals())
```
3. Add these line in urlpatterns section in urls.py
```
url(r'^delete/$', views.delete),
```
<h2>
LINE BOT API
</h2>
1. Create a LINE development account in [web site](https://developers.line.biz/en/)
2. Install LINE Bot SDK:
```
pip install line-bot-sdk==1.8.0
```
3. Get the LINE Bot CHANNEL_ACCESS_TOKEN and CHANNEL_SECRET from LINE develop
4. Add LINE_CHANNEL_ACCESS_TOKEN and CHANNEL_SECRET to settings.py
```
LINE_CHANNEL_ACCESS_TOKEN = 'developer's channel access token'
LINE_CHANNEL_SECRET = 'developer's channel secret'
```
5. Modify the Allowed host in setting.py
```
ALLOWED_HOSTS = ['*']
```
6. For Example, we create a 'callback' function. Add these lines to views.py
```
from django.conf import settings
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
from django.views.decorators.csrf import csrf_exempt
from linebot import LineBotApi, WebhookParser
from linebot.exceptions import InvalidSignatureError, LineBotApiError
from linebot.models import MessageEvent, TextSendMessage
line_bot_api = LineBotApi(settings.LINE_CHANNEL_ACCESS_TOKEN)
parser = WebhookParser(settings.LINE_CHANNEL_SECRET)
@csrf_exempt
def callback(request):
if request.method == 'POST':
signature = request.META['HTTP_X_LINE_SIGNATURE']
body = request.body.decode('utf-8')
try:
events = parser.parser(body, signature)
except InvalidSignatureError :
return HttpResponseForbidden()
except LineBotApiError:
return HttpResponseBadRequest()
for event in evnets:
if isinstance(event, MessageEvent):
#do somethings
return HttpResponse()
else:
return HttpResponseBadRequest()
```
7. Download and install [ngrok](https://ngrok.com/download)
8. Execute the Django service and ngrok
```
python manage.py runserver
ngrok http PORT_NUMBER
```
9. Configure the LINE Bot Webhook URL in Line [develop site](https://ngrok.com/download)
Paste the ngrok web site into the webhooks field.
For example : ngrok : https://1234abcd.ngrok.io
Fill the https://1234abcd.ngrok.io/callback into webhook field.
<h2>
Django Channel
<h2/>
1. Reference is [here](https://channels-docs-zhtw.readthedocs.io/zh_TW/latest/tutorial/index.html)