Skip to content
pbrisbin edited this page Jun 16, 2012 · 7 revisions

There are three methods used for creating basil plugins.

Responders

A responder will only be used on messages that are to basil:

Basil.respond_to(/a regex/) do

  # logic that either returns a Message or nil

end

Within the block, you have access to two very useful instance variables:

  • @msg is the Message that the plugin is currently responding to
  • @match_data contains the MatchData object that resulted from applying your regex

You've also got all the methods from Basil::Utils and Basil::ChatHistory.

Watchers

Watchers are exactly like responders except that they can be triggered on messages to anyone. One example might be to show titles for any urls mentioned in the chat:

Basil.watch_for(/https?:\/\/\S+/) do

  if get_html(@match_data[0]) =~ /<title>(.*?)<\/title>/
    says "Title: #{$1}"
  end

end

Email

If your server is configured to broadcast messages, basil will spawn a thread and check his email on the configured interval. If this is the case, incoming mail is dispatched (similarly to normal chat messages) through any registered email_checkers.

Basil.check_email(/a regex/) do

   # logic that either returns a Message or nil

end

If an email is received, and the subject matches the regex you've supplied, a @msg instance variable is constructed with the From and Body parts of the email as the from, from_name and text attributes (to is set to Config.me). @match_data is still set with the matches of your regex. With these variables set, your block will be executed.

One caveat: the chat attribute is initialized to nil. Although it's server-specific, broadcasting usually uses the chat attribute to determine which chat to broadcast to (if any); therefore, it's important you set the correct chat attribute to avoid problems (and Utils#set_chat is even provided for just that).

Guidelines

  • Don't write plugins that can be accomplished via factoids:
# bad
Basil.respond_to('beer') do
  says "have a beer!"
end

The same can be setup in chat, by anyone:

# good
> basil, beer is <say>have a beer!
Ta-da!
  • No exception handling.

In order to provide consistent behavior, it's best if any exceptions are handled by the dispatcher. rescues are permitted only if it greatly simplifies the method.

# bad
Basil.respond_to(/.../) do
  begin
    resp = get_html("http://...")
    reply resp if resp
  rescue
    reply "error accessing site!"
  end
end

# good
Basil.respond_to(/.../) do
  reply get_html("http://...")
end

# OK
Basil.respond_to(/.../) do
  resp = Object.any.method.could.be.nil rescue nil
  reply resp if resp
end
  • If a plugin requires a lot of logic, put the logic in a class (or classes) defined in the plugin file, then use the classes from within your plugin. Defining the classes to be within the Basil module is discouraged.

  • Do group related plugins in a single file and do not group unrelated plugins in a single file.

Clone this wiki locally