MSN Projects » Messenger Web Services » API Tutorial

Obviously, the web services plugin gets it's information from websites. The required information is located at a different place on each website. Therefor, the Web Services plugin uses little scripts, called parsers. Those parsers are written in Visual Basic Script or Javascript. With the help of the Web Services plugin, they can filter out the necessary information from any website. If you're a scripter, you can easily write your own parsers! Let's explain how it works.

Make a new file in the parser directory (Messenger Plus dir/plugins/MEWS/parsers/) and give it either a .vbs or .js extension, depending on the language you'll be writing it in. You can open the file with notepad, or any other txt/script editor. The name of the file (without the extension) will become the name of your parser. The user will call your parser with this name (/xmews <parsername>).

Note: All the sample code in this tutorial is VBScript, the javascript code wouldn't differ much (only basic syntax changes like operators, etc.). Take a look at the parser 'citytime_js.js' for an example javascript parser.

Every parser contains at least two procedures: info() and run(). The info() procedure gives the main plugin information about the parser. How do we set this info?

sub info()
     engine.description = "Purpose of the parser here"
     engine.help = "Explanation of how to use the parser"
     engine.syntax = "What parameters your parser accepts (for example '<query>')"
end sub

As you can see, the main plugin gives you access to a special object, called engine. In the info() procedure you can set 3 properties of the engine object. Now let's take a look at the second procedure: run(), this is the main procedure of your parser. It gets called when the user types /xmews <parsername>. Before I show you an example of a run() procedure, let's check out some more of the engine object's features.

engine.argument
This is a string containing the words the user typed after the parser name (/xmews <parsername> <arguments>).
engine.output(msg as string)
Sends msg to the user's chatwindow, it should only be called one single time.

We now can make a little run sub:

sub run()
     engine.output "Hello world, nice for" & _ 
      "calling me with argument(s): " & engine.argument
end sub

Now we still can't get any useful information from a website, this is where the next function comes in:

engine.getXML(url as string, handler as string, optional cleanhtml as boolean = false, optional preXMLHandler as string)
It's probably the most important function of the engine object. Let's take some time to cover all the parameters.
url
The url to be examined, and later on given to the handler.
handler
The name of the handler procedure, this handler should have the format handler(domdocument) it will be called with a MS XML DOMDocument object. This object will make it very easy for you to extract all the necessary information from a website, because it transfers all the source code to node-objects.
cleanhtml
A boolean indicating whether the document should be 'cleaned' to valid xml document before making a MS XML DOMDocument. It's necessary to set this boolean to true when the given url isn't a valid xml/xhtml document.
preXMLHandler
If the HTML to XML cleaner gives you some errors, you might need to clean some html tags manually. If set the function gets called before the url is put into a XML document, and even before the engine tries to convert a HTML document to X(HT)ML when the cleanhtml boolean is set to true.

The last two optional parameters might not yet seem totally clear for you, I'll explain them more thoroughly later on. Let's first check an easy parser. Suppose http://www.urltobeparsed.com/books.xml contains the following XML code:

<?xml version="1.0"?>
<books>
     <book>
          <author>James Peterson</author>
          <title>MSN for dummies</title>
     </book>
     <book>
          <author>Patchou</author>
          <title>Messenger Plus!</title>
     </book>
</books>

When the user types /xmews books we want to return a list of all the books, but when he types /xmews books Patchou we only want to list Patchou's book(s). We can now write the following parser.

sub info()
     engine.description = "Gives a list of books"
     engine.help = "When you don't supply any arguments,the parser will return a list of all the books in the database. When you supply an author as argument, the parser will give you the name of his book."
     engine.syntax = "<author (optional)>"
end sub

sub run()
     engine.getXML "http://www.urltobeparsed.com/books.xml", "parseHandler"
end sub

sub parseHandler(xml)
     if engine.argument = "" then
          for each item in xml.childNodes.item(1).childnodes 'For each book in books
               ret = ret & item.selectSingleNode("title").text & " by " & item.selectSingleNode("author").text & vbCrLf
          next
          engine.output ret
     else
          for each item in xml.childNodes.item(1).childnodes 'For each book in books
               if item.selectSingleNode("author").text = engine.argument then
                    ret = ret & vbCrLf & item.selectSingleNode("title").text
               end if
          next
          if ret = "" then
               ret = "No books found by " & engine.argument
          else
               engine.output "Books by " & engine.argument & ":" & ret
          end if
     end if
end sub

As easy as that it is! It could be you've never heard of the MS XML DOMDocument object and it's features. So let's examine our sample xml file a bit further. We can call each of the nodes in the following way with xml as the DOMDocument object:

<?xml>
xml.childnodes.item(0)
books
xml.childnodes.item(1)
first book
xml.childnodes.item(1).childnodes.item(0)
author of first book
xml.childnodes.item(1).childnodes.item(0).childnodes.item(0) or even better: xml.childnodes.item(1).childnodes.item(0).selectSingleNode("author")
title of first book
xml.childnodes.item(1).childnodes.item(0).childnodes.item(1) or even better: xml.childnodes.item(1).childnodes.item(0).selectSingleNode("title")
second book
xml.childnodes.item(1).childnodes.item(1)
author of second book;
xml.childnodes.item(1).childnodes.item(1).childnodes.item(0) or even better: xml.childnodes.item(1).childnodes.item(1).selectSingleNode("author")
title of second book
xml.childnodes.item(1).childnodes.item(1).childnodes.item(1) or even better: xml.childnodes.item(1).childnodes.item(1).selectSingleNode("title")

When you obtained the correct node, you can call the method .text to obtain the text inside the method. And .nodeName to obtain the node name, obiously.

For more information about MS XML take a look at the MSDN documentation and inspect some sample parsers.

This concludes our tutorial on how to use the MEWS API. You're always welcome to contact us if you need any help. Also, notify us when you've created a parser, so we can add it to our Parser Database. Remember to take a look at already existing parsers, so you can learn the basics as well as all the little tricks!

Check out the green menu at the left for more pages regarding to MEWS