Posts Tagged ‘Open AIM’

Tips on Developing AMO Plugins

Monday, January 19th, 2009

AIM 6.8 and the AIM 6.9 betas all support AIM Modules. These are HTML and JavaScript based plugins that have full access to the Open AIM API plus client level services like HTTP requests and window management.

One of the nicest aspects of AMO plugins is that you can install and uninstall them without having to sign off. This is fantastic from both a development and user perspective.

I recommend that you get an extra plugin key for developing plugins. Once you publish version 1 and set a finger print (optional) you will not be able to develop your plugin further with that key since only plugins with the registered fingerprint will be allowed to load. The solution to this is to get an extra key that you use for development purposes. Don’t forget to change to the deploy key before publishing.

Here are five tips to help get you started on developing your first plugin:

1 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.

1You 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.

Enable IE Debugging for AMO plugins

1Create 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:

debug=1;
prefs = window.external.prefs;
client= window.external.client;
wnd = window.external.window;
plugin= client.pluginInfo;

1Set 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.)

Set AMO_TRACE_ENABLE environment variable

I also create a trace function that helps me leave trace message that are suppressed when the plugin is deployed. This is a good practice. Note that this code uses the global variables ‘debug’ and ‘client’ that I set up the previous tip. Remember to set debug=0 when you deploy your plugin.

function trace(m)
{
    if (debug)
        client.trace(m);
}

1If your plugin fails to install for some reason, make sure your plugin.xml file is well-formed and that the minimum required attributes are there. Here are the minimum. The UUID must be your key with {}’s:

<?xml version="1.0" encoding="utf-8"?>
<plugin 
    schema     = "1"
    type       = "html"
    uuid       = "{00000000-0000-0000-0000-000000000000}"
    name      = "any name you want"
    .
    .
    .
</plugin>

Bonus Tip: See my posts tagged with “tips” for more.

Reading an AIM SDK Preference via JavaScript

Thursday, January 15th, 2009

Last year AOL released AIM 6.8 which is the first version of AIM to support plugins written in HTML and JavaScript. These plugins are called AIM Modules. They are a zip file that contains the plugin’s manifest, content, and code with a .amo extension. NOTE: a.m.o (addons.mozilla.org) and AMO plugins are not related.

A complete introduction to AMOs is beyond the scope of this post. You can read more about the AIM Module Plugin API on the AIM Developer web site. I have written a few of these plugins under the AMO Factory brand.

In my previous post, I demonstrated how to read a preference via C++. Here is a sample that accomplishes the same in JavaScript.

// Make a shorter name for this. See the AMO API for docs on this class
client = window.external.client;
// Get the primary IAccSession object. 
// (primary is the first account that signs on.)
session = client.primarySession;
// Get the IAccPreferences object for this session
prefs = session.prefs;
 
// See the IAccPreferences API
function safeGetPref(spec, default)
{
    try {
        // method names of AIMcc objects are not case sensitive.
        return prefs.GetValue(spec);
    } catch (e) {}
    return default;
}
 
function canDisclosePluginsToBuddyFeed()
{
    return safeGetPref("aimcc.privacy.disclosePluginsToBuddyFeed", 
        false);
}
 
if (canDisclosePluginsToBuddyFeed()) 
{
    alert('preference is true');
}

I recommend that you use try/catch blocks around AIMcc method calls since they can return COM error results that throw exceptions in JavaScript. The safeGetPref() function takes care of this and returns the default value if AIMcc returns any error.

TIP: The e.number property in the catch block has the HRESULT as a negative number. You can find the symbolic name for this error via the Symbol Lookup dialog in my CoreWitness plugin. Just enter the number in the find box to do the reverse lookup.

Reading an AIM SDK Preference via C++

Wednesday, January 14th, 2009

The AIM SDK (AIMcc) has an interface called IAccPreferences that is used for reading and writing preferences. Preferences are associated with a session so they can only be accessed once you have an IAccSession object.

It is up to clients to implement the actual data store behind these preferences by registering an object that implements either IAccPreferencesHook or IAccPreferencesHook2. You can find more information about these interfaces in technote 3 of the AIM SDK.

In this two-part series I will provide some sample code for reading preferences. This first post provides an ATL/C++ example and my next post will provide a JavaScript example.

In the process of making easy to use sample code, I will need to create some helper classes. These classes will be part of an evolving distribution called AccEx which I am hereby placing in the public domain. I will start by distributing these as source files only until I have more classes. AccEx distributions will be available here.

For this post, I created a helper class in AccEx called CAccExPreferences in order to make it easy to read and write preferences in C++. This class has overloaded methods to help you read a preference in various native formats like bool, int, float, etc. and one method to write a preference from a CComVariant.

So let’s use this thing. Like I said above, the IAccPreferences interface is implemented by AIMcc and associated with the IAccSession since they are (mostly) per-user preferences. Therefore, the only thing you need to initialize a CAccExPreferences object is an IAccSession pointer. The class will take care of acquiring the IAccPreferences interface for you. Here is a simple use-case that reads a real AIMcc preference.

// This sample source is public domain
#include <stdafx.h>
#include "AccExPreferences.h"
 
static WCHAR kDisclosePluginsToBuddyFeed[] = 
    OLESTR("aimcc.privacy.disclosePluginsToBuddyFeed");
 
HRESULT CanDisclosePluginsToBuddyFeed(IAccSession *pIAccSession)
{
    bool enabled;
    AccEx::CAccExPreferences prefs(pIAccSession);
 
    if ( SUCCEEDED( 
            prefs.GetPref(kDisclosePluginsToBuddyFeed, enabled) 
         ) && enabled )
    {
        // preference is enabled.
        return S_OK;
    }
    return S_FALSE;
}

Stay tuned for my next post where I will do the same using JavaScript.

Tip on Finding Preferences in Open AIM

Tuesday, January 13th, 2009

Every now and then I have to look up a preference specifier in AIM in order to use it in a plugin.

For example, the other day I wanted to determine if the user has enabled the pushing of AIM Plugins to their buddy feed. I usually check in technote 10 on preferences in the AIM SDK technotes. However, you can also do this empirically in AIM with my CoreWitness plugin. All ‘aimcc.*’ preference changes will cause the OnPreferenceChanged event to fire on all listeners so you can simply make a change in the client to see what preference specifier is changing.

To make it easier, the latest version of my CoreWitness plugin lets you filter the messages being logged by pressing the * button in the title bar. To filter the log to just the OnPreferenceChanged event, open the filter dialog and proceed as follows. Click on the ‘clear all’ button and then start typing the word “preference” in the filter edit box until you see “OnPreferenceChange” appear in the list. Select this event and click OK. Here is a screen shot of this step:

DAccEvents Monitor Filter

After doing the above, I changed the ‘I have installed a new AIM Plugin’ check box in the privacy tab of AIM 6.9’s Settings and clicked apply. Here is a screen shot of my results:

As you can see the preference is called ‘aimcc.privacy.disclosePluginsToBuddyFeed’. Finding the preference specifier is only the beginning. I will cover how to read it in a future post.

NOTE: This will only work for aimcc.* preferences. So it is possible that you can make a change in the settings that does not get notified via OnPreferenceChange because it is internal to the client. Internal preferences are not available to pluigns at this time.

Easy tool for generating AIM plugin fingerprints

Sunday, December 7th, 2008

Ever wanted a command line version of acchash.exe that simply displays the fingerprint and copies it to the clipboard without any mouse clicks?

Here you go:

use Digest::SHA;
use Win32::Clipboard;
 
$file = shift;
 
if ( -e $file && -f $file )
{
   $hash = uc( Digest::SHA->new(256)->addfile($file, 'b')->hexdigest );
   print "Plugin Fingerprint for '$file' (copied to clipboard): $hash\n";
   Win32::Clipboard()->Set( $hash );
}
else
{
   print "Usage: gushash [plugin_file_to_hash]\n";
}

Save this as gushash.pl in a location where your command shell can find it.

You will need Perl and the Digest-SHA package to use this script. The latter can be obtained through the ppm (Perl Package Manager) tool that is installed with Perl.

I’m always making little tools like this in Perl and Python to help me automate stuff.

This is here in case someone finds it useful…

CoreWitness 1.0.7 Shipped

Monday, July 28th, 2008

I have updated the CoreWitness Plugin. This version has two new features called DAccEvents Wizard and Symbol Lookup.

The DAccEvents Wizard helps you generate the code needed to handle Open AIM events in your own clients and plugins. It can generate code in C++ and JavaScript. The latter is useful for developing AMO plugins.

The Symbol Lookup window lets you quickly find the value of a particular constant. You can search by entering a partial name to see all the symbols containing that name. Or, you can do a reverse look up by entering a numeric value to see all the symbols with that value. You can click on any of the static text elements under the list box to copy the text to the clipboard. Clicking on the symbol’s name will copy an assignment statement to the clipboard.

You can find more information including screen shots and a download link here.

Open AIM Signon Problem

Tuesday, March 11th, 2008

As noted here, you need to make sure your system clock is fairly accurate when using the Open AIM SDK 1.6.7 in a client. This will be fixed in the next release.

Incidentally, the APIs we use for signon are clientLogin and startOSCARSession which are documented in the OSCAR protocol specifications.

AIM SDK 1.6.7 Q&A Volume I

Monday, March 10th, 2008

A number of you are trying out the recently released AIM SDK 1.6.7. I thought it would be a good idea to answer some of the early questions. So here they are in my usual Q&A style…

Q: What SDK files do I need to run an Open AIM client or bot?
A: You need to copy some of the DLL files from the dist\release folder into your application’s folder. You can omit the jg*.dll files if you don’t need to support talk (aka voice) sessions with legacy AIM clients like AOL 9.x and AIM 5.9. You can also omit the sipxtapi.dll if you don’t need to support the newer SIP based Audio/Video sessions in AIM 6.x. You only need the accjwrap.dll and the accjwrap.jar files if your bot or client is written in Java. All other DLLs are required.

Q: What are all these new DLLs for?
A: We added support for SSL based encryption to Open AIM clients, which is based on NSS and NSPR from Mozilla. We also updated the audio/video stacks for full multimedia support in Open AIM.

Q: How do I enable SSL based encryption in my bot or client?
A: You can enable this via the boolean preference named “aimcc.connect.secure”. The default is false.

Q: What does SSL based encryption protect?
A: This encrypts all regular IM traffic between the client and the AIM host. It will not encrypt direct IMs, picture sharing sessions, A/V sessions, file transfers, buddy art retrievals and uploads, or alerts. Note: for end to end security your buddy also needs to be running a client that uses SSL encryption, like AIM 6.5.9.1.

If I did not answer your question, feel free to ask in a comment or post it in one of the forums.

Open AIM 2.0

Thursday, March 6th, 2008

Open AIMWith AOL’s recent announcement on Open AIM 2.0 now live and getting lots of great attention, I thought I should write a quick post on it. This is truly exciting news. We are dramatically expanding our community when we open things up like this. So with that, I want to say “Welcome” to all the great developers out there. Here is this incredible AIM network that you can now use and build on.

I have actually been a part of the AIM core team for a number of months now, so I am available to help answer questions on Open AIM. I can now claim to have written code in imapp.dll, acccore.dll, coolcoreXX.dll, and xprtX.dll. Lastly, this guy sits next to me.

There are more great things to come.