by Doug Schwartz
July 11, 2007
Introduction
In my previous article, I created an AIM Lite plugin that sent a text file as part of an IM. In this article I show a simple way to send any file during an IM session, using a new plugin.
The sending plugin lets the user select any file and sends that file to their current buddy.
We are going to create the plugin in the following order:
- Create the plugin.xml file.
- Create the main.box file.
- Create the main.js file.
Creating the plugin.xml File
The plugin.xml file contains a single widget element.
This element can contain a number of subelements,
but the only required subelement is the uuid, which is a
developer or deployment key.
The only differences between this
plugin.xml
file and the one for the receiving plugin are the
uuid,
name,
and
description. Don't forget to replace YOUR_DEVELOPER_KEY with your developer key
in the following code.
<?xml version="1.0" encoding="utf-8" ?>
<widget
uuid = "{YOUR_DEVELOPER_KEY}"
version = "1.0"
name = "SendFile"
description = "This plugin sends a file"
vendor = "Me, Myself, and I Inc."
/>
Creating the main.box File
This file is exactly the same as the
main.box
for the receiving plugin.
The main.box file contains a single window element.
This element defines the user interface (UI) for the plugin.
A plugin can be visible, invisible (no UI),
or only visible in response to an event.
The plugin is invisible,
and main.box contains the following text:
<?xml version="1.0" encoding="utf-8" ?>
<window
xmlns="http://www.aol.com/boxely/box.xsd"
xmlns:s="http://www.aol.com/boxely/style.xsd"
xmlns:on="http://www.aol.com/boxely/reaction.xsd"
on:constructed="onConstructed();"
on:destroyed="onDestroyed();"
s:height="0"
s:width="0"
hidden="true"
collapsed="true"
floating="true"
>
<code id="main" language="jscript" src="main.js"/>
</window>
You can easily tell the plugin is invisible by the hidden="true" element. If the window weren't defined as "hidden," then a new window would pop up onto the screen each time the plugin was instantiated (i.e., each time AIM Lite is run). In fact, a new window is created for each plugin you install, but for plugins that perform most of their work in the background, the windows never appear because the plugin windows are declared as hidden in main.box.
Creating the main.js File
The main.js file is where the plugin's operational activity is coded. The main differences in this code for the current plugin versus the previous plugin is that in
this plugin, the sendFile function utilizes a
SecondaryManager object to send the file.
GetSecondaryManager is a member of the IAccSession interface. IAccSession is the main interface for accessing AIM functionalities. If you're going to be programming using the AIM SDK, IAccSession is something you'll need to learn about. The new online AIM SDK documentation has all the details of the IAccSession interface.
The first five lines of main.js contain five global variables.
var kCommandId = 0; var gSession; var sendTo; var AccSecondarySessionServiceId_FileXfer = 3; var AccFileXferFlags_ForceNonSecure = 0x2;
Where:
kCommandId- defines the integer value of the plugin command
gSession- caches the session object
sendTo- contains the name of the current buddy
AccSecondarySessionServiceId_FileXfer- identifies a secondary session that is sending files to another user
AccFileXferFlags_ForceNonSecure- identifies a non-secure call
Other than the cmd.text assignment, the
onConstructed
function is the same as in the previous plugin.
function onConstructed() {
var dict = scene.paramsDictionary;
gSession = dict.valueForKey("session");
var pInfo = dict.valueForKey("pluginInfo");
var cmd = pInfo.addCommand(kCommandId);
cmd.text = "Send file to current buddy";
scene.connectObject(gSession, "session_");
dict.setValueForKey(new commandListener(), "commandTarget");
}
As in the previous article, the sending plugin traps the IM in the BeforeImSend
function to get the name of the current buddy. It saves
the name of the current buddy in the sendTo variable. We will
use this later to create the IM we send.
function session_BeforeImSend(session, imSession, recipient, im) {
sendTo = recipient.Name;
}
The Exec function only checks whether the incoming id
is that of our command, kCommandId.
If it is, Exec calls the sendFile function.
Here is the Exec function.
commandListener.prototype.Exec=function(id, users) {
if (id == kCommandId) {
sendFile();
}
}
The sendFile function is where the action is.
It performs the following steps.
- Creates the Open File dialog window so the text file can be selected.
- Creates a
SecondaryManagerobject. - Sends the file.
Here is the code of the sendFile function.
function sendFile() {
var filter = "All Files (*.*)|*.*||";
var fileList = appUtils.openFileDialog(this.scene,
"Open File",
null,
null,
filter,
false);
if (fileList) {
var theFile = fileList.getValue(0);
var xferMgr = gSession.GetSecondaryManager(AccSecondarySessionServiceId_FileXfer);
var xferSession = xferMgr.send(sendTo, theFile, "", AccFileXferFlags_ForceNonSecure);
}
}
The appUtils.openFileDialog call brings up a file selection dialog window. Figure 1 shows an example:

Figure 1. The Open File dialog window
A very interesting component of the sendFile function is the instantiation of the GetSecondaryManager method.
GetSecondaryManager is a public member function in the IAccSession interface. Here's its declaration:
HRESULT GetSecondaryManager ([in] xp_int serviceId,[out, retval] IDispatch **ppiManager)
What's happening here is that we are creating a "secondary session," which the IAccSecondarySession interface reference also terms a "rendezvous" session. You've got your standard session where you're communicating with a buddy. Now, using GetSecondaryManager, we create a secondary session, a second communication bridge, which can be used for additional communication, but communication that may be non-standard and which happens behind the scenes.
In passing AccSecondarySessionServiceId_FileXfer to GetSecondaryManager, we're identifying what type of communication we'd like to configure in this particular secondary communication channel. The variable AccSecondarySessionServiceId_FileXfer is initialized as the value 3, which defines that the type of communication on the secondary channel will be file transfers.
There is a lot of flexibility available for secondary sessions. Here are the allowed communication types for secondary sessions:
| ID | AccSecondarySessionServiceID Variable Name |
Communication Type |
1 |
AccSecondarySessionServiceId_Im |
Instant message |
2 |
AccSecondarySessionServiceId_AudioVideo |
Audio or video |
3 |
AccSecondarySessionServiceId_FileXfer |
Transferring files |
4 |
AccSecondarySessionServiceId_FileSharing |
Sharing files |
5 |
AccSecondarySessionServiceId_ShareBuddies |
Sharing buddy lists |
6 |
AccSecondarySessionServiceId_Custom |
Open communications (defined by your programming) |
As with any plugin, the sending plugin also needs to create the
QueryStatus function. Here is the code for this function
and the commandListener object.
function commandListener() {}
commandListener.prototype.QueryStatus=function(id,
users) {
return (id == kCommandId) ? true : false;
}
Testing the plugin
There is no easy way to test this plugin besides deploying it.
- Zip up plugin.xml, content/main.box, and content/main.js, to create SendFile.zip.
- Rename it as SendFile.awi.
- Double-click SendFile.awi.
- Open two AIM Lite clients (see "Creating Multiple AIM Lite Clients").
- Create an IM session between the two AIM Lite clients.
- Select the SendFile plugin in one client.
- Select and send a file.
Creating Multiple AIM Lite Clients
You can create multiple AIM Lite clients on the same computer by using
the standalone option. Open a command window, navigate to the AIM Lite folder (typically
C:\Program Files\AIM Lite), and issue the following command for each client:
aimlite.exe -standalone
Conclusion
Now you understand how to send a file using AIM Lite. The next step would be to create a plugin that lets the receiver change the file name and location where the sent file is stored. I will do this in my next article.
Resources
-
SendFile.zip contains the complete source code for this article.
If you want to see this plugin at work:- Install AIM Lite.
- Unzip SendFile.zip to get the source files.
- Open the plugin.xml file.
-
Change
YOUR_DEVELOPER_KEYto your developer key. - Zip the files back up.
- Change the file extension to AWI.
- Double-click the AWI file to install the plugin.
References
Here are a number of web pages where you can get further information about AIM Lite, plugins, and the source code for this article.
- AIM Lite Plugin contains some basic information on plugins and a number of sample plugins.
- The AIM Developer FAQ contains additional information about Open AIM and AIM plugins.
- AOL Developer Resources contains a wide variety of developer resources.
- Greg's blog is a blog written by one of the AOL developers who wrote many of the AIM plugins.
- AIM Developer Key Management is where you go to get keys for your plugin.

nice work
thanks for links