Published Date : 2019年7月16日9:24

Deep Manzai Part 9 〜 AIML Web App 〜

This article has an English translation.

A brief summary of the previous article.


We've gone as far as creating a Python chat app using AIML.



Now we're going to deploy on Heroku, which failed two times before.


Please refer to the content of Heroku of the previous episode.




This is the code I used.

Now that AI is in vogue, it's time to build a rule-based chat bot with AIML [Python] Part 2

Thank you for the valuable information.


I'll write the code now. Let's get started!

アプリ構築 -building an application-

まず、ファイルの構造はこんな感じにします。 各自適当な作業用フォルダを作って、この記事を参考に必要なファイルを作っていってくだちぃ。

First, the file structure looks like this. Create your own working folder and use this article as a guide for creating the files you need.

Responsive image

本体のコードです。 ポートエラーが出るので、Herokuに合わせてポート番号を取得するように変えてあります。

The code of the body. I got a port error, so I changed it to get the port number for Heroku.
from flask import Flask, render_template, request, jsonify

# AIMLはXMLなので、XMLを操作するのに必要なモジュールをインポート。
# Because AIML is XML, you import the modules you need to work with the XML.
import xml.etree.ElementTree as ET
import os
import time

# AIMLの操作に必要なモジュールをインポート。
# Import the modules required for AIML operations.
import aiml

app = Flask(__name__)

global k
k = aiml.Kernel()


def chat():
    return render_template('chat.html')

@app.route("/ask", methods=['POST'])
def ask():
    # メッセージを取得
    global k
    message = str(request.form['messageText'])

    while True:
        if message == "quit":

            bot_response = k.respond(' '.join(list(message)))
            # チャットボットの返答を返す
            return jsonify({'status':'OK','answer':bot_response})

# ユーザーが求める応答文を作らせる関数。
# A function that allows the user to create the response statement they want.
@app.route("/generator", methods=['POST'])
def generator():
    global k
    # メッセージを取得。
    # Get Message.
    requestText = str(request.form['requestText'])
    responseText = str(request.form['responseText'])

    # AIMLファイルを作っていく。
    # Create an AIML file.
    tree_ = ET.ElementTree(file="manzai_aiml.xml")
    root = tree_.getroot()

    category = ET.SubElement(root, 'category')
    pattern = ET.SubElement(category,'pattern')

    pattern.text = ' '.join(list(requestText))

    template.text = responseText
    tree_.write("manzai_aiml.xml", encoding='utf-8', xml_declaration=True)


    # 保存後、ファイルの内容を反映させる。
    # Reflect the contents of the file after saving.
    k = aiml.Kernel()    

    return jsonify({'status':'OK','result':'言葉を覚えたよ。\nページを更新してね。\nOkay. AIML learned the language.\nPlease reload the page.'})

if __name__ == "__main__":
    # Herokuからポート番号を取得するようにする。
    # Get the port number from Heroku.
    port = int(os.getenv("PORT"))'', port=port, debug=True)

お次はGunicornの設定です。 ポート番号と設定を少し変えました。

Next is the Gunicorn configuration. I changed the port number and settings a little.

web: gunicorn hello:app --preload --timeout 10 --max-requests 1200 --log-file=-

お次はHTMLファイルです。 変更部分はユーザーの入力を受け付けて、処理をする部分。

Next is the HTML file. The change is the part that accepts user input and processes.

<!DOCTYPE html>

<head lang="ja-jp">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>変な会話 チャットボット</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" >
    <script src=""></script>
    <link href="" rel="stylesheet">
    <link href="" rel="stylesheet">


    <div class="container background-color: rgb(255,0,255);">

        <div class="row">
            <h3 class="text-center header_text">
            <div class="col-md-4 col-md-offset-4">
                <div id="chatPanel" class="panel panel-info">
                    <div class="panel-heading" style='background-color: #0275d8 !important;'>
                    <div class="panel-body fixed-panel" style='background-color: #fff !important;  height:80%;'>
                        <ul class="media-list">
                    <div class="panel-footer">
                        <form method="post" id="chatbot-form">
                            <div class="input-group">
                                <input type="text" class="form-control" placeholder="メッセージを入力してね" name="messageText" id="messageText" autofocus/>
                                <span class="input-group-btn">
                                    <button class="btn btn-info" type="button" id="chatbot-form-btn">送信</button>

    <!-- Modal -->
    <div class="modal fade" id="modalGenerateResponse" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
        <div class="modal-header text-center">
            <h4 class="modal-title" id="exampleModalCenterTitle">日本語限定の応答文作成<br>Create a response in Japanese only.</h4>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">×</span>
        <div class="modal-body">
            <form method="post" id="generator-form">
                <div class="input-group">
                    <input type="text" class="form-control" placeholder="覚えさせたい言葉を入力してくだちぃ。" name="requestText" id="requestText" autofocus/>
                    <label data-error="wrong" data-success="right" for="defaultForm-pass">Enter the words you want AIML to remember.</label>
                <div class="input-group">
                    <input type="text" class="form-control" placeholder="どんな言葉が返ってくるといいですか?" name="responseText" id="responseText" autofocus/>
                    <label data-error="wrong" data-success="right" for="defaultForm-pass">What kind of words should I get from AIML?</label>
        <div class="modal-footer d-flex justify-content-center">
            <button class="btn btn-primary" type="button" id="genrate-aiml-btn">言葉を覚えさせる<br>cause to learn words.</button>
    <div class="modal fade bd-example-modal-sm" tabindex="-1" role="dialog" id="small-dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-sm">
            <div class="modal-content">

    <script src="" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="" integrity="sha384-7aThvCh9TypR7fIc2HV4O/nFMVCBwyIUKL8XCtKE+8xgCgl/PQGuFsvShjr74PBp" crossorigin="anonymous"></script>

    <script src="" integrity="sha256-wS9gmOZBqsqWxgIVgA8Y9WcQOa7PgSIX+rPA0VL2rbQ=" crossorigin="anonymous"></script>
    <script src=""></script>
        $(function () {
            $('#chatbot-form-btn').click(function (e) {

            $('#chatbot-form').submit(function (e) {

                var message = $('#messageText').val();
                    '<li class="media"><div class="media-body"><div class="media"><div class="media-body"><div class="balloon1-left"><p>' +
                    message + '</p></div></div></div></div></li>');
                    type: "POST",
                    url: "/ask",
                    data: $(this).serialize(),
                    success: function (response) {

                        var answer = response.answer;
                        const chatPanel = document.getElementById("chatPanel");
                        if (answer != '') {
                                '<li class="media" style="text-align: right;"><div class="media-body"><div class="media"><div class="media-body"><div class="balloon1-right"><p>' + answer +
                                scrollTop: $(".fixed-panel")[0].scrollHeight
                            }, 1000);
                        } else {
                            '<li class="media" style="text-align: right;"><div class="media-body"><div class="media"><div class="media-body"><div class="balloon1-right"><p>' + "ファイルにはありません。" +
                            '<br>' + "日本語限定ですが、<br>言葉を覚えさせたいですか?<br>" + '<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modalGenerateResponse">It does not exist in the AIML file. <br> It is limited to Japanese,<br> but do you want aiml to memorize words?</button>' +

                    error: function (error) {

        $('#genrate-aiml-btn').click(function (e) {
        $('#generator-form').submit(function (e) {
            var requestText = $('#requestText').val();
            var responseText = $('#responseText').val()
                type: "POST",
                url: "/generator",
                data: $(this).serialize({
                success: function (response) {
                error: function (error) {


変更箇所の詳細は、 BootstrapのModalを使用して、入力を受け付ける。 JQueryを使用して、Flask APIに値を渡し、AIMLファイルを作成、反映させる。

For more information about changes, see Use Bootstrap's Modal to accept input. Use JQuery to pass values to the Flask API to create and populate the AIML file.


You can read more about the JQuery part in this article.

Herokuへデプロイ -Deploy to Heroku-


Now deploy to Heroku from the command line.

$ heroku login
$ git init
$ heroku create (アプリの名前) --buildpack heroku/python
$ heroku git:remote -a (アプリの名前)
$ git add .
$ git commit -m "my first app"
$ git push heroku master


Let's see if the app is deployed successfully.

$ heroku open
Responsive image
Responsive image
Responsive image
Responsive image
Responsive image
Responsive image

とりあえず終了 -Let's finish-


This application is installed in the Navi bar as an example, so please use it.

Deep Learningを使った漫才生成は勉強しておきます。 とりあえずこのシリーズはここで一旦打ち切り。

I will study Manzai generation using Deep Learning. For the time being, this series will be discontinued.

See You Next Page!