Skip to content
hartzler edited this page Nov 30, 2011 · 4 revisions

For plugin developers. See lib/plugin.rb for latest :)

DSL

You define plugins by making a file or directory in the plugins folder. The name of the file or directory is the name of your plugin. The plugin DSL makes heavy use of blocks and closures. Checkout existing plugins for more examples and ideas.

Methods

The following methods are available to your plugin:

  • command([name=plugin.name],options={},&block)

    Starts a new command block. If you don't give a name, it defaults to the plugin name.

  • resource([name=plugin.name],[options={}],[&block])

    shortcut for setting up a command with default actions

  • action([name],[options={}],&callback)

    create a new action for the current command (must be called within a command block). See Command DSL for more info.

  • timer(seconds, &callback)

  • _setup a timer. TODO: callback block has what params?

  • send(options={})

    Send a message. Optionas are :to,:from,:html|:txt

  • on(event_name, &callback)

    subscribe to an event

  • publish(event_name, args...)

    publish an event

  • config(name,options,&block)

    Specify a configuration option for your plugin. Options are :description and :default. The optional block param takes 3 args, |value,configured_value,default_value| and it is run whenever the config option is accessed. The result of the block is the value of the config option.

Objects

The following objects are in scope for you to reference in your plugin:

  • self

    the plugin instance

  • plugin

    deprecated

  • bot

    the bot instance

  • config

    access the config object. any properties you reference must have been setup with a config() DSL call from above, or an error will be raised.

Commands

Random notes about commands. Probably move this to its own page.

Typical pattern:

  • <command> <action> <arg1>
  • <command> <action> <arg1> <arg2>
  • <command> <action> [<arg1>]

Often with a default action:

  • <command> [<action>] # default no arg action
  • <command> [<action>] <arg1> # default 1 arg (optional or required)
  • <command> [<action>] <arg1> <arg2> # default 2 arg (optional or required)
  • <command> [<action>] [<arg>] # default N arg (optional or required)

Actions

Each command syntax has a corresponding regex and behavior. We call this an action. For this to work, we must sort each action regex by [name>no-name (aka default action), then by higher required arity]. Something like:

  • /^command\s+action\s+(.?)\s$/
  • /^command\s+action\s*$/
  • /^command\s+(.?)\s+(.?)\s*$/ ; run command.default($1,$2)
  • /^command\s+(.?)\s$/ ; run command.default($1)
  • /^command\s*$/ ; run command.default() note: lowest arity so must sort last

Command DSL

Only valid within command blocks.

description(str) : set the description for this command

aliases(alias1, alias2, ...) : set one or more aliases for this command

action([name],[options],&callback) : create an action. If no name, its a default action. Options are :required, :optional, :html, :is_public, :description. Callback block is called when the command/action regex matches the result of which are sent

Examples

Plugin Plugin

This is a fun name :)

syntax:

  • plugin [status]
  • plugin [status] # show
  • plugin enable
  • plugin disable

code:

command do |cmd|
   description  'manage plugins'

   action :list, :default=>true do |msg|
   end

   action :show, :required=>:plugin, :default=>true do |msg,plugin|
   end

   action :enable, :optional=>:plugin  do |msg,plugin|
   end

   action :disable, :required=>:plugin do |msg,plugin|
   end
end

produces the following regexes:

  • /^plugin\s+show\s+(.*)$/ # plugin.show($1)
  • /^plugin\s+show\s+$/ # plugin.show()
  • /^plugin\s+enable\s+(.*)$/ # plugin.enable($1)
  • /^plugin\s+enable\s+(.*)$/ # plugin.disable($1)
  • /^plugin\s+(.*)$/ # default, run plugin.show($1)
  • /^plugin\s*$/ # default action, run first noarg plugin action

Hot Plugin

syntax:

  • hot [trends]
  • hot [search] <topic>

code:

command :hot do
  description 'Whats hot on twitter'

  action :trends, :default=>true do 
    format(popular())
  end

  action :search, :required=>:topic, :default=>true do |topic|
    format(search(topic))
  end
end

regexes:

  • /^hot\s+trends\s*$/ # run hot.popular()
  • /^hot\s+search\s+(.?)\s$/ # run hot.search($1)
  • /^hot\s+(.?)\s$/ # run hot.search($1)
  • /^hot\s*$/ # run hot.popular()

Resources

Commands with default actions that manage REST like resources.

Examples

Lunch Plugin

The code:

resource :lunch do
  action :custom, :default=>true do
    (load_data||[]).sample
  end
end

creates the following command syntax:

  • lunch add # add new lunch
  • lunch del # remove lunch
  • lunch list # shows all lunch
  • lunch # shows random from list, aka default action

which is equivalent to:

command :lunch do
  description "foo"

  action :list, :default=>true do
  end

  action :add, :alias=>[:+], :required=>:name do |msg,name|
  end

  action :delete, :alias=>[:del,:-] do    
  end

  action :custom, :default=>true do
    "Custom response"
  end
end

TODO

  • check action callback arity, and don't pass the msg unless arty is 1 greater than action arty
  • better handle conflict on helpers (better scoping somehow?)
Clone this wiki locally