Step 18: Get the balance

Let’s assume every user has some amount on their account and can use this money to order food. We need to show the available amount on the page when the user logs in and allow asking about it with voice. To do this, we will use Alan’s project API.

The project API functionality allows sending any information from the app to the voice script and triggering activities without a voice command. To use it, you need to do the following:

  1. Define a new project API method in the voice script

  2. Call this method from the app when needed

To let the user log in to the web page:

  1. At the top of the <body> section in the app, add the login form:

    <body>
        <div id="login">
            <form onSubmit="login()">
                <label for="username">Username</label>
                <input id="username" type="text" placeholder="Enter Username">
                <label for="password">Password</label>
                <input id="password" type="password" placeholder="Enter Password">
                <input type="submit" value="Login" />
            </form>
        </div>
        <div id="balance"></div>
    ...
    </body>
    
  2. To the app, add a link to the jquery library and the serverRequest() and login() functions to allow the user logging in, sending a request to the server and obtaining an authentication token.

    <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    
    // Sending a request to the server
    function serverRequest(method, data, callback) {
        $.ajax({
            type: 'POST',
            url: 'https://studio.alan.app/api_playground/' + method,
            crossDomain: true,
            data: JSON.stringify(data),
            dataType: 'json',
            success: callback,
            error: () => alert('POST failed')
        });
    }
    
    // Logging in
    function login() {
        event.preventDefault();
        var username = document.getElementById('username').value;
        var password = document.getElementById('password').value;
        serverRequest(
            'tutorialLogin', {
                username: username,
                password: password
            },
            function(res) {
                if (res.error) {
                    alert(res.error);
                    return;
                }
                let token = res.token;
                document.getElementById('login').innerHTML = 'Hello, ' + username;
            }
        );
    }
    

    Now, try logging in with the following credentials:

    • User name: alan

    • Password: alan

    Once logged in, you will see a greeting on the page.

  3. If the user has successfully logged in and the token is obtained, let’s play a greeting to the user on the server side. For this, we will use project API. To the voice script, add a new project API method:

    projectAPI.setToken = function(p, param, callback) {
        if (!param || !param.token) {
            callback("error: token undefined");
        }
        p.play(`Hey, ${param.username}, nice to see you again!`);
        callback();
    };
    

    Next, update the login() function: we will activate the Alan button programmatically with the activate() method and call the new project API method we have defined. In the callProjectApi() method, we will also pass the user’s name and obtained token to the server script:

    function login() {
        event.preventDefault();
        var username = document.getElementById('username').value;
        var password = document.getElementById('password').value;
        serverRequest(
            'tutorialLogin', {
                username: username,
                password: password
            },
            function(res) {
                if (res.error) {
                    alert(res.error);
                    return;
                }
                let token = res.token;
                // Activating the Alan button programmatically
                alanBtnInstance.activate();
                // Calling the setToken method and passing the user's name and token to the voice script
                alanBtnInstance.callProjectApi("setToken", {
                    username: username,
                    token: token
                }, (err) => {
                    if (err) alert(err)
                });
                document.getElementById('login').innerHTML = 'Hello, ' + username;
            }
        );
    }
    

    Try logging in with the same credentials again. When you click Login, you will hear a message from Alan. To make the message more unique, Alan plays the user’s name passed from the app.

  4. We want to allow the user to ask about the balance with voice. First, we will save the passed token to the userData object. This object can be used to store any user-specific data and pass it between intent calls. In the voice script, update the setToken() method:

     projectAPI.setToken = function(p, param, callback) {
         if (!param || !param.token) {
             callback("error: token undefined");
         }
         // Saving the token to userData
         p.userData.token = param.token;
         p.play(`Hey, ${param.username}, nice to see you again!`);
         callback();
     };
    

    Add the getBalanceFromServer() function and a new intent to the voice script:

    function getBalanceFromServer(token, callback) {
        let req = {
            url: "https://studio.alan.app/api_playground/tutorialBalance",
            method: 'POST',
            json: {
            "token": token
            }
        };
        api.request(req, (err, res, body) => {
            const error = err || body.error;
            if (error) {
                callback(error);
            }
            callback(null, body.balance);
        });
    }
    
    intent('(What is my|) balance', p => {
        if (!p.userData.token) {
            p.play('Please log in to get balance');
            return;
        }
        getBalanceFromServer(p.userData.token, (err, balance) => {
            if (err) {
                p.error(err);
                p.play('error');
                return;
            }
            p.play(`Your balance is ${balance} dollars`);
        });
    });
    

    Try logging in and asking about the balance in the web page.

  5. Finally, let’s show the balance on the web page when the user logs in. To the voice script, add one more project API method — getBalance(). When invoked, this method will call the getBalanceFromServer() function we have in the script.

    projectAPI.getBalance = function(p, param, callback) {
        getBalanceFromServer(p.userData.token, callback);
    }
    

    In the app, add the requestBalance() function that will call the added project API method to display the balance in the balance field on the page. Then, update the login() function to call requestBalance():

    function login() {
        event.preventDefault();
        var username = document.getElementById('username').value;
        var password = document.getElementById('password').value;
        serverRequest(
            'tutorialLogin', {
                username: username,
                password: password
            },
            function(res) {
                if (res.error) {
                    alert(res.error);
                    return;
                }
                let token = res.token;
                alanBtnInstance.activate();
                alanBtnInstance.callProjectApi("setToken", {
                    username: username,
                    token: token
                }, (err) => {
                    if (err) alert(err)
                });
                // Calling requestBalance()
                requestBalance();
                document.getElementById('login').innerHTML = 'Hello, ' + username;
            }
        );
    }
    
    // Requesting the balance from the server
    function requestBalance() {
        alanBtnInstance.callProjectApi("getBalance", {}, (err, balance) => {
            if (err) {
                alert(err);
                return;
            }
            document.getElementById('balance').innerHTML = "Your balance is: $" + balance;
        });
    }
    

    Web page source | Voice script

Test your dialog: log in to the web page and ask about the balance with voice.