rivescript

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 18, 2016 License: MIT Imports: 10 Imported by: 14

README

RiveScript-Go

Build Status

Introduction

This is a RiveScript interpreter library written for the Go programming language. RiveScript is a scripting language for chatterbots, making it easy to write trigger/response pairs for building up a bot's intelligence.

This project is currently in Beta status.

Documentation

Installation

go get github.com/aichaos/rivescript-go

For the stand-alone binary for testing a RiveScript bot:

go install github.com/aichaos/rivescript-go/cmd/rivescript

Usage

The distribution of RiveScript includes an interactive shell for testing your RiveScript bot. Run it with the path to a folder on disk that contains your RiveScript documents. Example:

# (Linux)
$ rivescript eg/brain

# (Windows)
> rivescript.exe eg/brain

See rivescript --help for options it accepts, including debug mode and UTF-8 mode.

When used as a library for writing your own chatbot, the synopsis is as follows:

package main

import (
    "fmt"
    rivescript "github.com/aichaos/rivescript-go"
)

func main() {
    bot := rivescript.New()

    // Load a directory full of RiveScript documents (.rive files)
    err := bot.LoadDirectory("eg/brain")
    if err != nil {
      fmt.Printf("Error loading from directory: %s", err)
    }

    // Load an individual file.
    err = bot.LoadFile("brain/testsuite.rive")
    if err != nil {
      fmt.Printf("Error loading from file: %s", err)
    }

    // Sort the replies after loading them!
    bot.SortReplies()

    // Get a reply.
    reply := bot.Reply("local-user", "Hello, bot!")
    fmt.Printf("The bot says: %s", reply)
}

UTF-8 Support

UTF-8 support in RiveScript is considered an experimental feature. It is disabled by default. Enable it by setting RiveScript.UTF8 = true.

By default (without UTF-8 mode on), triggers may only contain basic ASCII characters (no foreign characters), and the user's message is stripped of all characters except letters, numbers and spaces. This means that, for example, you can't capture a user's e-mail address in a RiveScript reply, because of the @ and . characters.

When UTF-8 mode is enabled, these restrictions are lifted. Triggers are only limited to not contain certain metacharacters like the backslash, and the user's message is only stripped of backslashes and HTML angled brackets (to protect from obvious XSS if you use RiveScript in a web application). Additionally, common punctuation characters are stripped out, with the default set being /[.,!?;:]/g. This can be overridden by providing a new Regexp object as the RiveScript.UnicodePunctuation attribute. Example:

// Make a new bot with UTF-8 mode enabled.
bot := rivescript.New()
bot.UTF8 = true

// Override the punctuation characters that get stripped from the
// user's message.
bot.UnicodePunctuation = regexp.MustCompile(`[.,!?;:]`);

The <star> tags in RiveScript will capture the user's "raw" input, so you can write replies to get the user's e-mail address or store foreign characters in their name.

Building

I use a GNU Makefile to make building and running this module easier. The relevant commands are:

  • make setup - run this after freshly cloning this repo. It runs the git submodule commands to pull down vendored dependencies.
  • make build - this will build the front-end command from cmd/rivescript and place its binary into the bin/ directory. It builds a binary relevant to your current system, so on Linux this will create a Linux binary. It's also recommended to run this one at least once, because it will cache dependency packages and speed up subsequent builds and runs.
  • make build.win32 - cross compile for Windows, but see below.
  • make run - this simply runs the front-end command and points it to the eg/brain folder as its RiveScript source.
  • make dist - creates a binary distribution (see Distributiong below).
  • make dist.win32 - cross compiles a binary distribution for Windows, equivalent to build.win32
  • make clean - cleans up the .gopath, bin and dist directories.
Cross-compile for Windows

If you're using Go v1.5 or higher, and aren't running Windows, you can build the rivescript.exe file using the cross compilation feature.

If you're using Go as provided by your distribution's package maintainers, you need to mess with some path permissions for the Win32 build to work. This is because Go has to build the entire standard library for the foreign system (for more information, see this blog post on the topic).

Run mkdir /usr/lib/golang/pkg/windows_386 and chown it as your user account.

Then run make build.win32 to cross compile the Win32 binary and output it to bin/rivescript.exe

You should sanity test that the binary actually runs from a Windows environment. It might not run properly via Wine.

Distributing

The GNU Makefile can build distributable binary forms of the RiveScript command for the host OS (usually Linux) and cross-compile for Windows. Building for Mac OS X, and building from within a Windows dev environment have not yet been tested.

  • make dist - build a distributable for your current system (usually Linux, but Mac would probably work too).
  • make dist.win32 - build a distributable for Windows using cross compilation.

The dist commands will create a directory named dist/rivescript which you can inspect afterwards, and creates a zip file (Windows) or a tar.gz (Linux and Mac) with the contents of that folder, with names like rivescript-0.0.2-win32.zip and rivescript-0.0.2-Linux.tar.gz in the current directory (the root of the Git repo).

The distributable directory contains only the following types of files:

  • The executable binary (rivescript.exe for Windows or rivescript otherwise)
  • Metadata files: README.md, LICENSE, etc.
  • Example brain at eg/brain
  • (Windows only) a super simple batch file for launching rivescript.exe and pointing it to the example brain: example.bat

License

The MIT License (MIT)

Copyright (c) 2016 Noah Petherbridge

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

See Also

The official RiveScript website, http://www.rivescript.com/

Documentation

Overview

Package rivescript implements the RiveScript chatbot scripting language.

UTF-8 Support

UTF-8 support in RiveScript is considered an experimental feature. It is disabled by default. Enable it by setting `RiveScript.UTF8 = true`.

By default (without UTF-8 mode on), triggers may only contain basic ASCII characters (no foreign characters), and the user's message is stripped of all characters except letters, numbers and spaces. This means that, for example, you can't capture a user's e-mail address in a RiveScript reply, because of the @ and . characters.

When UTF-8 mode is enabled, these restrictions are lifted. Triggers are only limited to not contain certain metacharacters like the backslash, and the user's message is only stripped of backslashes and HTML angled brackets (to protect from obvious XSS if you use RiveScript in a web application). Additionally, common punctuation characters are stripped out, with the default set being `/[.,!?;:]/g`. This can be overridden by providing a new `Regexp` object as the `RiveScript.UnicodePunctuation` attribute. Example:

// Make a new bot with UTF-8 mode enabled.
bot := rivescript.New()
bot.UTF8 = true

// Override the punctuation characters that get stripped from the
// user's message.
bot.UnicodePunctuation = regexp.MustCompile(`[.,!?;:]`);

The `<star>` tags in RiveScript will capture the user's "raw" input, so you can write replies to get the user's e-mail address or store foreign characters in their name.

See Also

The official homepage of RiveScript, http://www.rivescript.com/

Index

Examples

Constants

View Source
const (
	VERSION            = "0.0.2"
	RS_VERSION float64 = 2.0
)

Constants

Variables

This section is empty.

Functions

This section is empty.

Types

type MacroInterface

type MacroInterface interface {
	Load(name string, code []string)
	Call(name string, fields []string) string
}

type RiveScript

type RiveScript struct {
	// Parameters
	Debug              bool // Debug mode
	Strict             bool // Strictly enforce RiveScript syntax
	Depth              int  // Max depth for recursion
	UTF8               bool // Support UTF-8 RiveScript code
	UnicodePunctuation *regexp.Regexp
	// contains filtered or unexported fields
}
Example
package main

import (
	"fmt"
	rivescript "github.com/aichaos/rivescript-go"
)

func main() {
	bot := rivescript.New()

	// Load a directory full of RiveScript documents (.rive files)
	bot.LoadDirectory("eg/brain")

	// Load an individual file.
	bot.LoadFile("testsuite.rive")

	// Sort the replies after loading them!
	bot.SortReplies()

	// Get a reply.
	reply := bot.Reply("local-user", "Hello, bot!")
	fmt.Printf("The bot says: %s", reply)
}
Output:

Example (Javascript)
package main

import (
	"fmt"
	rivescript "github.com/aichaos/rivescript-go"
	"github.com/aichaos/rivescript-go/lang/rivescript_js"
)

func main() {
	// Example for configuring the JavaScript object macro handler via Otto.

	bot := rivescript.New()

	// Create the JS handler.
	jsHandler := rivescript_js.New(bot)
	bot.SetHandler("javascript", jsHandler)

	// Now we can use object macros written in JS!
	bot.Stream(`
		> object add javascript
			var a = args[0];
			var b = args[1];
			return parseInt(a) + parseInt(b);
		< object

		> object setname javascript
			// Set the user's name via JavaScript
			var uid = rs.CurrentUser();
			rs.SetUservar(uid, args[0], args[1])
		< object

		+ add # and #
		- <star1> + <star2> = <call>add <star1> <star2></call>

		+ my name is *
		- I will remember that.<call>setname <id> <formal></call>

		+ what is my name
		- You are <get name>.
	`)
	bot.SortReplies()

	reply := bot.Reply("local-user", "Add 5 and 7")
	fmt.Printf("Bot: %s\n", reply)
}
Output:

Example (Subroutine)
package main

import (
	"fmt"
	rivescript "github.com/aichaos/rivescript-go"
)

func main() {
	// Example for defining a Go function as an object macro.

	bot := rivescript.New()

	// Define an object macro named `setname`
	bot.SetSubroutine("setname", func(rs *rivescript.RiveScript, args []string) string {
		uid := rs.CurrentUser()
		rs.SetUservar(uid, args[0], args[1])
		return ""
	})

	// Stream in some RiveScript code.
	bot.Stream(`
		+ my name is *
		- I will remember that.<call>setname <id> <formal></call>

		+ what is my name
		- You are <get name>.
	`)
	bot.SortReplies()

	_ = bot.Reply("local-user", "my name is bob")
	reply := bot.Reply("local-user", "What is my name?")
	fmt.Printf("Bot: %s\n", reply)
}
Output:

func New

func New() *RiveScript

func (*RiveScript) ClearAllUservars

func (rs *RiveScript) ClearAllUservars()

ClearAllUservars clears all variables for all users.

func (*RiveScript) ClearUservars

func (rs *RiveScript) ClearUservars(username string)

ClearUservars clears all a user's variables.

func (*RiveScript) CurrentUser

func (rs *RiveScript) CurrentUser() string

CurrentUser returns the current user's ID.

func (*RiveScript) DeleteSubroutine

func (rs *RiveScript) DeleteSubroutine(name string)

DeleteSubroutine removes a Go object macro.

func (*RiveScript) DumpSorted

func (rs *RiveScript) DumpSorted()

DumpSorted is a debug method which dumps the sort tree from the bot's memory.

func (*RiveScript) DumpTopics

func (rs *RiveScript) DumpTopics()

DumpTopics is a debug method which dumps the topic structure from the bot's memory.

func (*RiveScript) FreezeUservars

func (rs *RiveScript) FreezeUservars(username string) error

FreezeUservars freezes the variable state of a user.

This will clone and preserve the user's entire variable state, so that it can be restored later with `ThawUservars()`.

func (*RiveScript) GetAllUservars

func (rs *RiveScript) GetAllUservars() map[string]map[string]string

GetAllUservars gets all the variables for all the users.

This returns a map of username (strings) to `map[string]string` of their variables.

func (*RiveScript) GetUservar

func (rs *RiveScript) GetUservar(username string, name string) (string, error)

GetUservar gets a user variable.

This is equivalent to `<get name>` in RiveScript. Returns `undefined` if the variable isn't defined.

func (*RiveScript) GetUservars

func (rs *RiveScript) GetUservars(username string) (map[string]string, error)

GetUservars gets all the variables for a user.

This returns a `map[string]string` containing all the user's variables.

func (*RiveScript) GetVariable

func (rs *RiveScript) GetVariable(name string) (string, error)

GetVariable gets a bot variable.

This is equivalent to `<bot name>` in RiveScript. Returns `undefined` if the variable isn't defined.

func (*RiveScript) LastMatch

func (rs *RiveScript) LastMatch(username string) (string, error)

LastMatch returns the user's last matched trigger.

func (*RiveScript) LoadDirectory

func (rs *RiveScript) LoadDirectory(path string, extensions ...string) error

LoadDirectory loads multiple RiveScript documents from a folder on disk.

Params:

path: Path to the directory on disk
extensions...: List of file extensions to filter on, default is '.rive' and '.rs'

func (*RiveScript) LoadFile

func (rs *RiveScript) LoadFile(path string) error

LoadFile loads a single RiveScript source file from disk.

Params:

path: File path to

func (*RiveScript) RemoveHandler

func (rs *RiveScript) RemoveHandler(lang string)

DeleteHandler removes an object macro language handler.

func (*RiveScript) Reply

func (rs *RiveScript) Reply(username string, message string) string

Reply fetches a reply from the bot for a user's message.

Params:

username: The name of the user requesting a reply.
message: The user's message.

func (*RiveScript) SetDebug

func (rs *RiveScript) SetDebug(value bool)

SetDebug sets the value of rs.Debug (maybe useful for non-Go bindings)

func (*RiveScript) SetDepth

func (rs *RiveScript) SetDepth(value int)

SetDepth sets the value of rs.Depth (maybe useful for non-Go bindings)

func (*RiveScript) SetGlobal

func (rs *RiveScript) SetGlobal(name string, value string)

SetGlobal sets a global variable.

This is equivalent to `! global` in RiveScript. Set the value to `undefined` to delete a global.

func (*RiveScript) SetHandler

func (rs *RiveScript) SetHandler(lang string, handler MacroInterface)

SetHandler sets a custom language handler for RiveScript object macros.

func (*RiveScript) SetPerson

func (rs *RiveScript) SetPerson(name string, value string)

SetPerson sets a person substitution pattern.

This is equivalent to `! person` in RiveScript. Set the value to `undefined` to delete a person substitution.

func (*RiveScript) SetStrict

func (rs *RiveScript) SetStrict(value bool)

SetStrict sets the value of rs.Strict (maybe useful for non-Go bindings)

func (*RiveScript) SetSubroutine

func (rs *RiveScript) SetSubroutine(name string, fn Subroutine)

SetSubroutine defines a Go object macro from your program.

Params:

name: The name of your subroutine for the `<call>` tag in RiveScript.
fn: A function with a prototype `func(*RiveScript, []string) string`

func (*RiveScript) SetSubstitution

func (rs *RiveScript) SetSubstitution(name string, value string)

SetSubstitution sets a substitution pattern.

This is equivalent to `! sub` in RiveScript. Set the value to `undefined` to delete a substitution.

func (*RiveScript) SetUTF8

func (rs *RiveScript) SetUTF8(value bool)

SetUTF8 sets the value of rs.UTF8 (maybe useful for non-Go bindings)

func (*RiveScript) SetUnicodePunctuation

func (rs *RiveScript) SetUnicodePunctuation(value string)

SetUnicodePunctuation sets the value of rs.UnicodePunctuation (maybe useful for non-Go bindings)

func (*RiveScript) SetUservar

func (rs *RiveScript) SetUservar(username string, name string, value string)

SetUservar sets a variable for a user.

This is equivalent to `<set>` in RiveScript. Set the value to `undefined` to delete a substitution.

func (*RiveScript) SetUservars

func (rs *RiveScript) SetUservars(username string, data map[string]string)

SetUservars sets a map of variables for a user.

Set multiple user variables by providing a map[string]string of key/value pairs. Equivalent to calling `SetUservar()` for each pair in the map.

func (*RiveScript) SetVariable

func (rs *RiveScript) SetVariable(name string, value string)

SetVariable sets a bot variable.

This is equivalent to `! var` in RiveScript. Set the value to `undefined` to delete a bot variable.

func (*RiveScript) SortReplies

func (rs *RiveScript) SortReplies()

SortReplies sorts the reply structures in memory for optimal matching.

After you have finished loading your RiveScript code, call this method to populate the various sort buffers. This is absolutely necessary for reply matching to work efficiently!

func (*RiveScript) Stream

func (rs *RiveScript) Stream(code string) error

Stream loads RiveScript code from a text buffer.

Params:

code: Raw source code of a RiveScript document, with line breaks after each line.

func (*RiveScript) ThawUservars

func (rs *RiveScript) ThawUservars(username string, action string) error

ThawUservars unfreezes a user's variables.

The `action` can be one of the following: * thaw: Restore the variables and delete the frozen copy. * discard: Don't restore the variables, just delete the frozen copy. * keep: Keep the frozen copy after restoring.

func (*RiveScript) Version

func (rs *RiveScript) Version() string

type Subroutine

type Subroutine func(*RiveScript, []string) string

Subroutine is a Golang function type for defining an object macro in Go.

Directories

Path Synopsis
cmd
rivescript
Stand-alone RiveScript Interpreter.
Stand-alone RiveScript Interpreter.
lang
rivescript_js
Package rivescript_js implements JavaScript object macros for RiveScript.
Package rivescript_js implements JavaScript object macros for RiveScript.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL