Implementing Login Functionality in SUSI Web Chat

SUSI Web Chat is fully equipped with all the accounting features which are being provided by the SUSI.AI API. This blog discloses all the API features one needs to know to embed the Login functionality in SUSI Web Chat. To embed the Login feature, first we create a form using material-ui.com components with the followng fields Email Password Note: We can also chose a Custom Server while logging in, here I have used the Standard Server ie. http://api.susi.ai to make the user Login The form can be made with the help of the following fields TextField for Email, props to be passed Name - email Value - this.state.email which gets the value of the current email floatingLabelText is Email, errorText is the message which we want to show when the email does not match the regex or its empty. Code Snippet - <TextField name="email" value={this.state.email} onChange={this.handleChange} errorText={this.emailErrorMessage} floatingLabelText="Email" /> PasswordField for Password Name - password Value - this.state.password which gets the value of the current email floatingLabelText is Password, errorText is the message which we want to show when the password is not filled. Code Snippet- <PasswordField name='password' value={this.state.password} onChange={this.handleChange} errorText={this.passwordErrorMessage} floatingLabelText='Password' /> The next elements are RadioButton groups taken from material-ui.com. This ensures the user signs into a standard server or even to a custom server. This is not compulsory as of now. And lastly we need a submit button, which is disabled until all the fields are filled. Code Snippet - <RaisedButton label="Login" type="submit" labelColor="#fff" disable={!this.state.validForm} /> For the full form, check out this file at Login.react.js A Sample UI could be as shown in the image Next after creating the Login Screen, we make the onSubmit prop which is to be hooked up with another function called handleSubmit. An example code snippet from Login.react.js- handleSubmit = (e) => { e.preventDefault(); // Get the trimmed values from the fields var email = this.state.email.trim(); var password = this.state.password.trim(); // Set the default server to login let BASE_URL = defaults.Server; // handle all the details of the chosen server let serverUrl = this.state.serverUrl; if(serverUrl.slice(-1) === '/'){ serverUrl = serverUrl.slice(0,-1); } if(serverUrl !== ''){ BASE_URL = serverUrl; } // if email and password is filled return true if (!email || !password) { return this.state.isFilled; } // Check the regex of email let validEmail = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(email); // Pass the parameters to the loginEndPoint let loginEndPoint = BASE_URL+'/aaa/login.json?type=access-token&login=' + this.state.email + '&password=' + this.state.password; // If email and password is filled and valid call AJAX if (email && validEmail) { // AJAX Calls } } Then we make the Ajax Calls and store the created token from hitting the URL at http://api.susi.ai/aaa/login.json?type=access-token&login=EMAIL&password=PASSWORD. We store the cookie in browser and generate a session for the user using a package ‘universal-cookies’. $.ajax({ url: loginEndPoint, dataType: 'jsonp', jsonpCallback: 'p', jsonp: 'callback', crossDomain: true, success: function (response) { cookies.set('serverUrl', BASE_URL, { path: '/' }); let accessToken = response.access_token; let state = this.state;// Adding the current State let time = response.valid_seconds; // Get the valid time of the…

Continue ReadingImplementing Login Functionality in SUSI Web Chat

Creating and Maintaining User Sessions Using Universal-Cookies in SUSI Web Chat

If you login to SUSI Web Chat, and come back again after some days, you find that you didn’t have to login and all your previous sent messages are in there in the message pane. To achieve this, SUSI Web Chat uses cookies stored in your browser which is featured in this blog.   In ReactJS, it’s highly misleading and extensive to use the conventional Javascript methodology of saving tokens and deleting them. However, universal-cookie, a node package allows you to store and get cookies with the least possible confusion. In the following examples, I have made use of the get, set and remove functions of the universal-cookie package which have documentations easily available at this link. The basic problem one finds while setting cookies and maintaining sessions is the time through which it should be valid and to secure the routes. We shall look at the steps below to figure out how was it implemented in SUSI Web Chat. 1. The first step is to install the packages by using the following command in your project’s root- npm install universal-cookie --save 2. Import the Cookies Class, where-ever you want to create a Cookie object in your repository. import Cookies from 'universal-cookie'; Create a Cookie object at the same time in the file you want to use it, const cookies = new Cookies(); 3. We make use of the set function of the package first, where we try to set the cookie while the User is trying to login to the account. Note - The cookie value can be set to any value one wants, however, here I am setting it to the access token which is generated by the server so that I can access it throughout the application. AJAX Call to the server Login endpoint for SUSI AI http://api.susi.ai/aaa/login.json?type=access-token&login=EMAIL&password=PASSWORD $.ajax({ options: options, success: function (response) { //Get the response token generated from the server let accessToken = response.access_token; // store the current state let state = this.state; // set the time for which the session needs to be valid let time = response.valid_seconds; //set the access token in the state state.accessToken = accessToken; // set the time in the state state.time = time; // Pass the accessToken and the time through the binded function this.handleOnSubmit(accessToken, time); }.bind(this), error: function ( jqXHR, textStatus, errorThrown) { // Handle errors } }); Function -  handleOnSubmit() // Receive the accessToken and the time for which it needs to be valid handleOnSubmit = (loggedIn, time) => { let state = this.state; if (state.success) { // set the cookie of with the value of the access token at path ‘/’ and set the time using the parameter ‘maxAge’ cookies.set('loggedIn', loggedIn, { path: '/', maxAge: time }); // Redirect the user to logged in state and reload this.props.history.push('/', { showLogin: false }); window.location.reload(); } else { // Handle errors } } 4.  To access the value set to the cookie, we make use of the get function. To check the logged in state of the…

Continue ReadingCreating and Maintaining User Sessions Using Universal-Cookies in SUSI Web Chat

Using react-url-query in SUSI Chat

For SUSI Web Chat, I needed a query parameter which can be passed to the components directly to activate the SUSI dreams in my textarea using just the URL which is not easy when one is using react-router. React URL Query is a package for managing state through query parameters in the URL in React. It integrates well with React Router and Redux and provides additional tools specifically targeted at serializing and deserializing state in URL query parameters. So for example, if one wants to pass some parameters to populate in your component directly through the URL, you can use react-url-query. Eg. http://chat.susi.ai/?dream=fossasia will populate fossasia in our textarea section without actually typing the term textarea. So this in the URL, Will produce this in the textarea, To achieve this. the following steps are required: First we proceed with installing the packages (Dependencies  - history) npm install history --save npm install react-url-query --save   We then instantiate a history in our component where we want to listen to the parameters like the following code. Our class ChatApp is where we want to pass the params. ChatApp.react.js import history from '../history'; //Import the history object from the History package. // force an update if the URL changes inside the componentDidMount function componentDidMount() { history.listen(() => this.forceUpdate()); }  Next, we define the props of the parameters in our Message Section. For that we need the following props- urlPropsQueryConfig - this is where we define our URLConfig Static proptypes - the query param to which we want to pass the value, so for me it’s dream. The defaultProps when no such value is being passed to our param should be left a blank. And then we finally assign the props. This is then passed to the Message Composer Section from where we receive the value passed. MessageSection.react.js // Adding the UrlConfig const urlPropsQueryConfig = { dream: { type: UrlQueryParamTypes.string } }; // Defining the query param inside our ClassName static propTypes = { dream: PropTypes.string } // Setting the default param static defaultProps = { dream: '' } //Assigning the props inside the render() function const { dream } = this.props; //Passing the dream to the MessageComposer Section <MessageComposer threadID={this.state.thread.id} theme={this.state.darkTheme} dream={dream} /> //Exporting our Class export default addUrlProps({ urlPropsQueryConfig })(ClassName); Next we update the Message Composer section by the props we had passed. For this we first check if the props are null, we don’t populate it in our textarea if it is, otherwise we populate the textarea with the value ‘dream + props.dream’ so the value passed in the URL will be prepend by a word dream to enable the ‘dream value’ in our textarea. The full file is available at MessageComposer.js //Add Check to the constructor constructor(props) { super(props); this.state = {text: ''}; if(props.dream!==''){ //Setting the text as received ‘dream dreamPassed’ this.state= {text: 'dream '+ props.dream} } } // Populate the textarea <textarea name="message" value={this.state.text} onChange={this._onChange.bind(this)} onKeyDown={this._onKeyDown.bind(this)} ref={(textarea)=> { this.nameInput = textarea; }} placeholder="Type a message..." /> // Add props to…

Continue ReadingUsing react-url-query in SUSI Chat

Using SUSI as your dictionary

SUSI can be taught to give responses from APIs as well. I made use of an API called Datamuse which is a premier search engine for English words, indexing 10 million unique words and phrases in more than 1000 dictionaries and glossaries. 1. First, we head towards creating our dream pad for creating rules for the skill. To do this we need to create a dream at dream.susi.ai and give it a name, say dictionary. 2. After that one needs to go to the API and check the response generated. 3. Going through the docs of the API, one can create various queries to produce informative responses as follows - Word with a similar meaning. define *| Meaning of *| one word for * !console: $word$ { "url":"https://api.datamuse.com/words?ml=$1$", "path":"$.[0]" } eol Word related to something that start with a given letter. word related to * that start with the letter * !console: $word$ { "url":"https://api.datamuse.com/words?ml=$1$&sp=$2$*", "path":"$.[0]" } eol Word that sound like a given word.. word that sound like *|sounding like * !console: $word$ { "url":"https://api.datamuse.com/words?sl=$1$", "path":"$.[0]" } eol Words that are spelled similarly to a given word. words that are spelled similarly to *| similar spelling to *| spelling of * !console: $word$ { "url":"https://api.datamuse.com/words?sp=$1$", "path":"$.[0]" } eol Word that rhyme with a given word. rhyme *| word rhyming with * !console: $word$ { "url":"https://api.datamuse.com/words?rel_rhy=$1$", "path":"$.[0]" } eol Adjectives that are often used to describe a given word. adjective to describe *|show adjective for *|adjective for * !console: $word$ { "url":"https://api.datamuse.com/words?rel_jjb=$1$", "path":"$.[0]" } eol Suggestions for a given word. suggestions for *| show words like *| similar words to * | words like * !console: $word$ { "url":"https://api.datamuse.com/sug?s=$1$", "path":"$.[0]" } eol This is a sample query response for define * To create more dictionary skills go to http://dream.susi.ai/p/dictionary and add skills from the API. To contribute by adding more skills, send a pull request to the susi_skill_data.  To test the skills, you can go to chat.susi.ai

Continue ReadingUsing SUSI as your dictionary

20 Amazing Things SUSI can do for You

SUSI.AI has a collection of varied skills in numerous fields such as knowledge, entertainment, problem solving, small-talk, assistants etc. Here’s a list of top skills which SUSI possesses. Knowledge Based Ask SUSI to describe anything. Sample Queries - describe * Ask SUSI the distance between any two cities. Sample queries - distance between * and *|What is distance between * and * ?| What is distance between * and *          Ask SUSI about your site’s rank. Sample Query - site rank of *                 Ask SUSI to know the location of any place. Sample Queries - where is *          Ask SUSI the time in any city.  Sample Query - current time in *          Ask SUSI the weather information of any city. Sample Queries - temperature in * , hashtags * *, mentions * *, weather in *, Tell me about humidity in *|What is humidity in *|Humidity in *|* Humidity, Tell me tomorrow's weather in *|Weather forecast of *          Ask SUSI to wiki about anything. Sample Query - wiki *              Ask SUSI about any word, words etc. Sample Queries - define *| Meaning of *| one word for *, word related to * that start with the letter *, word that sound like *|sounding like *, words that are spelled similarly to *| similar spelling to *| spelling of *, rhyme *| word rhyming with *, adjective to describe *|show adjective for *|adjective for *, suggestions for *| show words like *| similar words to * | words like * Ask SUSI about a day in the calendar. Sample Queries - Date * ?, Day * ?, Day on year * month * date *?          Ask to convert a currency to USD for you.  Sample Queries -  convert * to USD          Problem Solving Based Ask SUSI to solve a problem for you in Mathematics.   Sample Queries - compute *| Compute *| Calculate *| calculate *          Entertainment Based Ask SUSI to draw a card for you. Sample Query - draw a card          Ask SUSI to toss a coin for you. Sample Query - flip a coin          Ask SUSI to tell you a Big Bang Theory Joke. Sample Query - * big bang theory| tell me about big bang theory|geek jokes|geek joke|big bang theory * Ask SUSI to generate a meme for you.  Sample Query - get me a meme                   Ask SUSI to give you a recipe.  Sample Queries - * cook *, cook *|how to cook *|recipe for   Ask SUSI to tell you a random joke. Sample Queries - tell me a joke|recite me a joke|entertain me Ask SUSI to give you a random gif. Sample Query - random gif          Assistants Ask SUSI to translate something for you Sample Queries - What is * in french|french for * , What is * in german|german for *, What is * in spanish|spanish for *,  What is * in hindi|hindi for * Ask SUSI to search anything for you. Sample…

Continue Reading20 Amazing Things SUSI can do for You

Using Flux to embed SUSI’s API Service in a Chat System.

To embed SUSI’s API Service in a chat-like system, I needed a view which could populate the content dynamically and maintain the state of the Application at the same time. Flux follows a unidirectional data flow path and I used this feature to the advantage of the Chat Application to maintain the real time state of the Chat View. A Flowchart model of Flux looks like   src: https://github.com/facebook/flux Flux uses a dispatcher service to render its views, thus making the data flow in a unidirectional path. When a user reacts with a React view (here through the TextArea in the chat system), the view propagates an action through the dispatcher service, to the various stores that hold the application’s data and finally update the views that are affected. Here’s another flowchart model from the website which helps one understand the model in a better way. For the current Chat Application, I used a single Message Store which contained all the event listeners to detect any change in the view. For example, when I send a “Hey” to SUSI, an action is called to Dispatch this message to the Message Store with an ActionType  “CREATE_MESSAGE”. This store then renders the message in the Message Section View. Here is an example snippet from the Actions.js file which performs an action of type CREATE_MESSAGE and dispatches the messages to the MessageStore.js. export function createMessage(text, currentThreadID) { let message = ChatMessageUtils.getCreatedMessageData(text, currentThreadID); ChatAppDispatcher.dispatch({ type: ActionTypes.CREATE_MESSAGE, message }); ChatWebAPIUtils.createMessage(message); }; The response from the message is generated as soon as another ActionType named “CREATE_SUSI_MESSAGE” is dispatched to the store, thereby rendering the SUSI’s response generated in the view. The file ChatConstants.js which declares all the ActionTypes. import keyMirror from 'keymirror'; export default { ActionTypes: keyMirror({ CREATE_MESSAGE: null, RECEIVE_RAW_CREATED_MESSAGE: null, CREATE_SUSI_MESSAGE: null, RECEIVE_SUSI_MESSAGE: null, RECEIVE_RAW_MESSAGES: null }) }; To get the message up on the view, I have used the following utils to call the API, render the messages to the view and call the different actions. Here’s a code snippet from ChatMessageUtils.js export function createMessage(message) { ChatExampleDataServer.postMessage(message, createdMessage => { Actions.receiveCreatedMessage(createdMessage, message.id); }); ChatExampleDataServer.postSUSIMessage(message, createdMessage => { Actions.createSUSIMessage(createdMessage, message.threadID); }); }; To know more about the project join us on Gitter at gitter.im/fossasia/susi_webchat, or to contribute go to https://github.com/fossasia/chat.susi.ai/. A demo application can be found running at http://chat.susi.ai. Resources - To know more about Flux you can visit the following websites. Docs and In-Depth Overview http://facebook.github.io/flux/docs/in-depth-overview.html#content Video Tutorials - http://facebook.github.io/flux/docs/videos.html#content

Continue ReadingUsing Flux to embed SUSI’s API Service in a Chat System.