Skip to content
Michael Chadwick edited this page Oct 16, 2013 · 25 revisions

Scripting commands

/install installs a script from the local file system.
/scripts lists the names of all currently running scripts. The script name can be set with setName().
/uninstall <name> uninstalled the script with the given name.

Example

The following script creates a custom “/dance” command that outputs “(>'-')> <('-'<) ^(' - ')^ <('-'<) (>'-')>” when typed.

setName('/dance');
setDescription('Type /dance have a Kirby dance');

send('hook_command', 'dance');

var dance = "(>'-')> <('-'<) ^(' - ')^ <('-'<) (>'-')>";
this.onMessage = function(e) {
  send(e.context, 'command', 'say', dance);
  propagate(e, 'none');
};

Also check out the auto_identify, which hides the user's NickServ password and automates identifying with NickServ.

API

Set the script's name

setName(name)

Send an event

send(opt_context, type, name, args...)

For example, the following code sends a command that emulates the user typing "hello world!".

send(context, 'command', 'say', 'hello world!')
```
See the events section for details on what value `type` and `name` can have.

**Register to receive a notification on a certain event**  
```javascript
send('hook_server', 'joined')
```
The first argument is the type of event (either `hook_server`, `hook_message` or `hook_command`).
The second argument is the is the subtype of the event. 
For example, if the type is `hook_command`, then the subtype might be `kick` or `msg`.

**Stop an event from being received by the client**  
```javascript
propagate(receivedEvent, 'none')
```

**Allow an Event to be received by the client**  
```javascript
propagate(receivedEvent, 'all')
```
Note: propagate should be called every time an event is received

**Save or load a JavaScript Object or primitive to/from sync storage**  

An item can be saved to storage with `saveInStorage(item)` and loaded with `loadFromStorage()`.  

After `loadFromStorage()` is called, an event with type "system" and name "loaded" will be fired. The first argument of the event is the loaded item, or undefined if there was nothing saved.

Note: It's important to call `setName(<my_name>)` before using sync storage. The script's name is used to uniquely identify it in storage.

### Events
To listen to events, define an onMessage function
```javascript
onMessage = function (event) { // code here };
```

Events have the following fields
* **type** is the kind of event (either “command”, “server” or “message”)
* **name** is the name or subtype of the event (e.g. “kick”, “joined”, “nickinuse”)
* **context** is where the event happened
  * **server** (e.g. “irc.freenode.net”)
  * **channel** (e.g. “#bash”)
* **args** is a variable length array of any arguments (e.g. the text to print on /say)

There are four types of events
* **command** represents an entered command (e.g. “/kick #sugarman”)
* **server** represents server related activity (e.g. we connected to a server or got kicked from a room)
* **message** represents anything that gets printed on the screen (e.g. the MOTD or a notice message)

For example, an event triggered by a private message being displayed might look like this:
```javascript
event = {
  type: 'message',
  name: 'privmsg',
  context: {
    server: 'irc.freenode.net',
    channel: '#circ'
  }
  args: [
    'noah', // from
    'events are exciting!' // message
  ]
}
```

A full list of message events can be found in the `_handlers` object of [irc_message_handler](https://github.com/flackr/circ/blob/master/src/chat/irc_message_handler.coffee).

A full list of server events can be found in the `onServerEvent()` function of [chat](https://github.com/flackr/circ/blob/master/src/chat/chat.coffee).

A full list of command events can be found in the `_init` function of [user_command_handler](https://github.com/flackr/circ/blob/master/src/chat/user_command_handler.coffee).

## Implementation

### Loading
Scripts are loaded for the first time from the local file system using chrome.fileSystem. Once a script is loaded it is saved to a persistent local storage and automatically loaded each time the program starts.

### Sandboxing
The script source code is passed to a sandboxed iframe, which calls eval(). This prevents the script from accessing the IRC window object and chrome.* APIs. Because the script runs in an iframe, it communicates with the application asynchronously using window.postMessage(). This complicates the code slightly, but has no effect on performance.
Clone this wiki locally