---
# System prepended metadata

title: Build your own Chatbot

---

# 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)
