With so many different AIM clients out there, how can we tell if a client supports a particular feature? The answer is capabilities. Each screen name has a list of capabilities (GUIDs) that are asserted by the client and plugins.
How can I read these capabilities in the AIM SDK, you might ask? You can see what a user supports via the AccUserProp_Capabilities property and what the client asserts via the AccSessionProp_Capabilities property.
Here is a dump of the capabilities property for one of my screen names as seen by my CoreWitness plugin:
AccUserProp_Capabilities = Array { ...GUIDs removed from trace here... }
{09461345-4C7F-11D1-8222-444553540000} = Direct IM
{748F2420-6287-11D1-8222-444553540000} = Chat
{09461343-4C7F-11D1-8222-444553540000} = File Transfer
{67753137-6A38-6C77-4672-762D49755071} = UUID of a plugin: 'Gus Verdun's Core Test Plug-in (Dev)'
{09461346-4C7F-11D1-8222-444553540000} = Buddy Icon
{9FD3969B-84CB-45C1-B5DF-72DF5FAAB98E} = RX-PluginThe AIM SDK returns an array of GUIDs in string form for those two properties. The CoreWitness plugin will automatically map the GUIDs to friendly names. When it encounters a GUID it does not recognize, it scans to see if the GUID matches that of any plugin you have installed. Yes, you can assert your plugin’s key as a capability if you want too. However, this is not required even thought your plugin’s key is reserved for you. I chose long ago to assert a different GUID as a capability for my RX-Plugin as you can see above. The capability is used to change the behavior of the IMpulse feature when both users have the RX-Plugin installed.
The AIM SDK always returns VB arrays in JavaScript so you must convert them to a JS array by using the toArray() method. Here is one way you can test to see if a buddy supports a particular capability:
// Test to see if buddy (IAccUser) has the RX-Plugin capability asserted function HasRXPlugin(buddy) { if ( SafeHasCapability(buddy, '{9FD3969B-84CB-45C1-B5DF-72DF5FAAB98E}') ) alert('yes'); else alert('no'); } // cap must be in upper case. function SafeHasCapability(user, cap) { try { return user.capabilities.toArray().join('').indexOf(cap) >= 0; } catch ( e ) { return false; } }
The first function calls the more general function to test if the buddy has the capability asserted by my RX-Plugin.
You can use capabilities in your plugins for anything. They can be used to indicate that something is “on”, “selected”, etc. You can even have more than one—within reason. The AIM Vote ‘08 plugin uses capabilities to indicate your vote for McCain or Obama and then tallies up the number of buddies with either of those capabilities.
You can install a plugin by running the .amo file. I typically do “start plugin.amo” from the command line or make file. AIM registers itself as a handler for this file extension. You can install a plugin even while offline.
You should enable the debugging setting in IE for other apps. This helps you attach the JavaScript debugger during development and warns you about unhandled exceptions. With debugging enabled (i.e. not disabled), you can insert “debugger;” statements in your code to trigger the debugger. Go to the Internet Settings control panel and uncheck the highlighted option is to do this.
Create aliases for the window.external.* objects. This makes it easier to use these by assigning them to a variable. I put these at the top of my JavaScript file:
Set the AMO_TRACE_ENABLE environment variable to “true” in order to use the window.external.client.trace(msg) function that sends output to the debugger. I do it via the Environment Variables dialog in the System Properties control panel (Windows+Break key, click on Advanced tab, then “Environment Variables” button.)
If your plugin fails to install for some reason, make sure your plugin.xml file is
