I have been working recently on Data warehousing methodologies using the Pentaho Suite of applications. Data warehousing and OLAP applications are based on a multidimensional view of
data, and they work with queries that represent selections of data.
Once the data is organized in the warehouse, design an OLAP metadata model, map the logical
metadata objects to data in the warehouse, create OLAP metadata objects. An OLAP
API application can then get the OLAP metadata objects and use them to create
queries that operate on the data in the warehouse.
I found a lot of it fairly intuitive to learn and use, and want to write about my experiences with creating Mondrian OLAP Cubes. This is not intended to explain what an OLAP Cube is, but instead to describe the steps I took to create mine.
Tables Used:
Fact Table:
AGGR_TEST_TABLE
Dimension tables for the Cube:
DIMENSION1
DIMENSION2
Aggregate tables created for the Cube:
AGGREGATE1
AGGREGATE2
AGGREGATE3
AGGREGATE4
The below define the dimensions that the measures are aggregated by. DDL and DML are checked into CVS under projects/pcg/common/Mondrian
Cube Details:
Cube Name: AGGR_MYTEST_CUBE
Dimensions:
* TestDimension1
* TestDimension2
Measures:
* Total1
* Cost1
Creation of the Cube(step by step):
Setting up the Pentaho bi test server:
* Download Pentaho BI Server, Schema Workbench and Aggregation designer from sourceforge, I got version 3.7 of the biserver.
* Run the server from /biserver-ce/tomcat/bin/start-pentaho.sh
* View the deployment on http://localhost:8080/pentaho/Home, cubes are available from ‘New Analysis View’, this is your testing mechanism for a cube you create and deploy
* Create the facts and dimension tables and populate them with the data to be sliced
* Set up the database connection for the data source in the pentaho admin console. This is what the cube will connect to.
Cube creation:
* Run the Schema Workbench and create a new database connection
* Create the cube, the interface is pretty intuitive, a schema, cubes, dimensions, dimension usage, hierarchies, levels that you want to report and slice on
* Save the cube in the xml format.
* Publish the cube by either using schema workbench or copy the xml file to the samples location and modify the system/olap/datasources.xml in the bi server directory (search for it) to add the new schema and cube. It will look something like this:
Provider=mondrian;DataSource=gowri
solution:steel-wheels/analysis/AGGR_MYTEST_CUBE.xml
* Bounce the server and refresh all caches and try out your cube, you should see the schema name in your xml in the drop list and the cube will display and be slicable.
Aggregate Creation:
This can be very tricky since Mondrian and pentaho have a smart way of detecting the existing of aggregate tables and you need to really be careful to verify that the:
Aggregate tables are set up right, populated correctly.
The mondrian.properties are set with correct values, failure to do so will result in errors when testing the cube which are NOT intuitive. One error I got was that the MDX query did not work when the NON EMPTY clause was specified on the rows, the pentaho logfile had the query, I tried the same query in the MDX editor in pentaho interface and it worked fine without the NON EMPTY.
Mondrian.properties needs the folliwing flags set to use aggregates:
mondrian.rolap.aggregates.Use=true
mondrian.rolap.aggregates.Read=true
mondrian.rolap.nonempty=false
mondrian.olap.fun.crossjoin.optimizer.size=100000
mondrian.native.crossjoin.enable=true
mondrian.native.nonempty.enable=false
Steps to generate aggregates:
* Use the Aggregation-designer to create the aggregates, its pretty simple to do.
* Open the xml for the cube in the aggregation designer
* Set up the connection
* Select a cube
* Try to get the aggregation designer to recommend aggregates.
* Make sure you define aggregates for all combinations of the dimensions and levels within dimensions, including aggregates with no dimensions selected, ie All for every dimension/hierarchy/level
* Save the aggregates, run the DDl, DML and the publish of the modified schema xml to the server.
* Test your cube.
I have been working on J2EE, implementing business solutuons deployed on the JBoss portal. After exploring alternatives for deploying configurable modules that can be customozed, we came upon the Liferay Portal, an enterprise web platform for building business solutions. Check out the Liferay Website for more details on who they are and what they do. We are developing modules using ICEFaces. We have been happy with this platform so far, and in future posts, I will provide some more information on our experience with this, good and bad both.
Some initial impressions… both in terms of end user perspective and the developer…
1, The Liferay platform provides a lot for ‘free’. The portlet container archcitecture has a lot of usability built in that can be leveraged.
2. Authentication and authorization, setting up users and roles. The end user who is an administrator can dynamically configure the pages with their admin rights, and hide/show different views or portlets to the non admin users. There is CAS/LDAP integration, and seamless authentication to Pentaho reports and the Alfresco document management system.
3. The Control Panel is a handy way to add portlets, you can set up and configure pages and add your own and third party portlets to build an application using the portlet building blocks.
4. There is a community edition which is free, and the enterprise edition that is supported by Liferay. It may be well worth the cost of buying the support instead of trying to figure out and reinvent solutions others have fixed before.
5. The platform is deceptively simple to use and configure. Most common features are built in, but it can be hard to break free of the portlet/container architecture and do something too custom. The requirements of your application should conform to this paradigm for it to work.
6. Check out the new Liferay 6 features.
7. Check out Alloy UI which is a few feature of Liferay 6

Here is a very relevant article on the real dangers of a company making a decision to rewrite its product from scratch, throwing away legacy code.
I love this comment in the article “It’s harder to read code than to write it.”, I find it hard to read my own code months after I have written it. Having programmed for decades I am intimately familiar with how some developers and architects think. They want to leave THEIR stamp on a product, and the temptation to redo what works to what they THINK will work better can be overwhelming! And it usually ends up being a subjective comparison in the end, where both approaches work with different pros and cons. The oft repeated comment I heard is “I dont UNDERSTAND how this other programmer could write this MESS, so I am simply going to rewrite it because its faster than trying to understand it!”….. ummmm, right, who is going to maintain THIS rewritten code now after you have moved on????
There are sometimes real valid business reasons to rewrite parts of a product to either make the functionality richer, modular, improve performance, security etc, and all those hold valid if done in a sane, low risk monetizable way. My personal belief is to keep the costs and risk minimum without sacrificing innovation and upgrading to the latest where it makes sense to do so.
April 17th, 2010 in
Uncategorized |
2 Comments
I bought a new Dell Inspiron laptop with 64-bit Windows7 which promptly brought my wireless router down on booting.
I found the issue, had to disable uPnP, found the helpful tip of the following link… apparently it is a fairly common issue with the new computers and routers 
>
This is the presentation I gave at work today. I intend to have it available here as a link for people to refer to whenever they want. Enjoy.
Download (PPT, 244KB)
March 12th, 2010 in
SCRUM/Agile |
2 Comments
Here are the detailed steps for generating/installing a GoDaddy CA signed cert on a JBoss/Tomcat deployment.
I figured I would document the entire process for future reference, I added as much detail as I could and documented the issues I ran into.
I also added steps at the end to document a self signed certificate as well.
I used OpenSSL to do the key generating and importing on the NMSU server.
NOTE: ALL the below commands have to be generated on the server that you install the certificate on. You also need admin rights on the server and an email address that is for an admin registered for the domain so that whois.com can be used to look up the server and email address associated with it. The certifying authorities mandate this so that they are sure that they are issuing the certificate to the correct site owner. I tried to add as much detail as possible.
1. Generate Your Private Key:
openssl genrsa -des3 -out server.key 2048
2. Generate the certificate signing request (CSR), an unsigned copy of
the SSL certificate:
Enter the relevant information requested.
IMPORTANT: Make sure that the Common Name is EXACTLY the same as the domain that you are registering for a key, case matching. The country code has to be the right one, US for USA and the case matters. I demonstrated some dummy data below to give an idea…
openssl req -new -key server.key -out server.csr
Country Name (2 letter code) [AU]: US
State or Province Name (full name) [Some-State]: VA
Locality Name (eg, city) []: Alexandria
Organization Name (eg, company) [Internet Widgits Pty Ltd]: myorg
Organizational Unit Name (eg, section) []: dev
Common Name (eg, YOUR name) []: mydomain.com (the exact domain that you are securing)
Email Address []: foo@bar.com
3. List the certificate to ensure all went well so far… I have mangled the below to show a dummy certificate for demo purposes.
cat server.csr
—–BEGIN CERTIFICATE REQUEST—–
MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRAwDgYDVQQH
EwdoZXJuZG9uMQ4wDAYDVQQKEwVudGVseDEMMAoGA1UECx
Ewlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALHKK9/YFGrV
v+DMILzRuUKPpEGEKirh4X9pj/Q+OcB/7yAR
wCq/pRlKwRiBFkTVA0JMTALEg11TUqQSgBDkIYK6+RSkSA==
—–END CERTIFICATE REQUEST—–
4. Send this to the CA by going to the GoDaddy website and submitting the CSR form with the above key copied and pasted into their input window. This site has good directions for doing this part.
5. Remove the PassPhrase From Your Private Key
cp server.key server.key.secure
openssl rsa -in server.key.secure -out server.key
6. Install the certificate on the server:
GoDaddy sends back an approval email, once GoDaddy has approved the cert, they will send the admin email address the an email stating that the cert is ready to be installed. Go to the GoDaddy website as instructed in that email and follow directions from there, its fairly clear at that point what to do.
Download the signed certificate and unzip the contents of the package, you will see 4 files in there.
Some problems I ran into and their solutions:
Beware of gd_bundle.crt in the package they send you, discard it and download the file from their repository at https://certs.godaddy.com/anonymous/repository.seam?cid=116134.
Also download the valicert_class2_root.crt from their site, its a part of their chain that their documentation refers to but fails to deploy or mention explicitly on their instructions.
Finally do the following command which generates the keystore and adds the chain of certs to it.
openssl pkcs12 -export -chain -CAfile gd_bundle.crt -in
mydomain.com.crt -inkey server.key -out keystore.tomcat -name
tomcat -passout pass:changeit
7. List out the installed certificate:
openssl pkcs12 -info -in keystore.tomcat
Here is the output, to give you an idea what the chain looks like in the keystore: The below is a non functional mangled cert which is strictly shown to demonstrate what you can expect.
openssl pkcs12 -info -in keystore.tomcat
Enter Import Password:
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes
friendlyName: tomcat
localKeyID: 81 19 4A 2E 4D FA F4 A6 8E 11 E5 1B 29 52 12 D8 D6 21 E9 2F
subject=/O=nmsu.nxsuite.com/OU=Domain Control Validated/CN=nmsu.nxsuite.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
—–BEGIN CERTIFICATE—–
WQxGTAXBgNVBAMTEG5tc3UubnhzdWl0ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQDDvyy0dyieEG3NebGvvUCVfopO3vsGrRYsjLZV4+izcfWH
6a/HQxB6JkMjdeJpr++WERtQ4dRjMKvBLl5cpCK/Wb33so0DzFVT6/i6aT+iewES
LmNvbS9nZHMxLTE0LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcBMDkwNwYI
dG9yeS8wgYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au
Z29kYWRkeS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdv
ZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSME
DqqqK1puhoJo74K1s2+v4PTRcnkUil/w6TGXyza2ELsReApmU+ImrLdlxso5wCUS
4QrwxHIx7wuZtN+GrdvdrdzJKuajah7gI6kyqLcS+dII4qgs7qOvy6dD57dHrADM
CgYkTOTaWciyBY2ftfxM+jc3mbWRvpGrEsVgi6NXfSWq7zPstTEbJ3zWl3LTUFY=
—–END CERTIFICATE—–
Certificate bag
Bag Attributes:
subject=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
issuer=/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
—–BEGIN CERTIFICATE—–
MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
U+4=
—–END CERTIFICATE—–
Certificate bag
Bag Attributes:
subject=/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
issuer=/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
—–BEGIN CERTIFICATE—–
MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe
biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg
MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw
AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv
Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd
IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1
QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O
WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf
SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==
—–END CERTIFICATE—–
Certificate bag
Bag Attributes:
subject=/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
issuer=/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
—–BEGIN CERTIFICATE—–
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
—–END CERTIFICATE—–
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Bag Attributes
friendlyName: tomcat
localKeyID: 81 19 4A 2E 4D FA F4 A6 8E 11 E5 1B 29 52 12 D8 D6 21 E9 2F
Key Attributes:
Enter PEM pass phrase:
Verifying – Enter PEM pass
8. Location of the certificates are here below and the contents of the directory consist of the certificates from GoDaddy, the private key (server.key), and the keystore (keystore.tomcat)
gd_bundle.crt gd_cross_intermediate.crt keystoreg.tomcat mydomain.com.crt server.key valicert_class2_root.crt
gd_bundle.crtsav gd_intermediate.crt keystore.tomcat server.csr server.key.org
9. Configure Tomcat inside Jboss:
The server.xml is located at /FD-jboss423/server/default/deploy/jboss-web.deployer /server.xml.
You need to modify the keystoreName, keystorePassword to match the certificate installed. The keystoreType is set to PKCS12 since this is the type that was generated by OpenSSL.
Tomcat currently operates with JKS, PKCS11 or PKCS12 format keystores. The JKS format is Java’s standard “Java KeyStore” format, and is the format created by the keytool command-line utility. This tool is included in the JDK. The PKCS12 format is an internet standard, and can be manipulated via (among other things) OpenSSL
port="8443" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" protocol="HTTP/1.1" sslProtocol="TLS" keystoreFile="/mypath/keystore.tomcat" keystoreType="PKCS12" keystorePass="changeit" >
How to get a self signed certificate generated and installed:
Follow ALL the steps above except that instead of submitting a request for a signed cert, sign it and install your self signed server.crt. The keystore can simply be added to the tomcat server.xml to use this instead of the signed cert. I tested this out.
Self Sign Your Certificate Signing Request:
openssl x509 -req -days 365 -in server.csr -signkey server.key -out
server.crt
Install the cert into a keystore:
openssl pkcs12 -export -in server.crt -inkey server.key -out mycert.p12 -name tomcat -CAfile server.crt -caname root -chain
NOTE:
I had no success with keytool, the commands I followed on the GoDaddy help for keytool did not work for me, the certificates were not recognized by Tomcat. Another issue I found with keytool is that it did not export the private key or generate it outside of the keystore.
March 3rd, 2010 in
JBoss,
SSL,
Tomcat |
35 Comments
I will be focusing on more general Software Development issues that I run into and this will not be an AIM focused blog anymore. The AIM developer program has changed and is moving to partnerships. I look forward to sharing my experience in other aspects of development and will be posting shortly on my adventures with SSL!
February 28th, 2010 in
Uncategorized |
8 Comments
An AIM Bot is a screen name that can respond automatically to the IMs it receives. I added more information to the article to the AIM Dev Site which explains the different types of BOTs AOL offers to consumers and partners. The two types are Enterprise BOTs and Consumer BOTs.
Here is a comparison chart that outlines the difference between an Enterprise BOT and a Consumer BOT.
We do have C++ and Java samples that demonstrate how to develop a BOT.
I just released a sample written in C++ that demonstrates the custom session feature in the Open AIM SDK 1.8.2. This code works in both Windows and Linux (tested on Ubuntu and CentOS). This sample is called acccssample, and you can download the source code here. The source code is cross platform, you can choose to build it in Windows using acccsample.vcproj, or use Makefile with g++ under Linux. This sample basically signs on and then allows the user to initiate the Custom Session as follows:
Usage:
acccssample.exe screenname password initiateflag where initiateflag = true or omit parameter.
You can run two instances of this app one to initiate a custom session and one which auto accepts the custom session to test this.
On the initiating side, when you see the below prompt, initiate a custom session with a buddy who is set to receive the custom session:
Enter c:s screenname to initiate a custom session with a buddy
Here are some code snips with some explanation:
// First, assert capability, which is a GUID of your choice that both the initiator and the recipient recognize
// You can do this as soon as your client goes online.
void OnStateChange(IAccSession* piSession, AccSessionState state, AccResult hr)
{
if (state == AccSessionState_Online)
{
HRESULT hr = piSession->AddCapabilities(CAccVariant(kCSCapability));
printf(“AddCapabilities, hr=%08X\n”, hr);
}
}
// start a custom session with the buddy
void StartCustomSession(xp_str buddy)
{
// for demo purposes we only support one session at a time
if (m_customSess == NULL)
{
printf(“Start Custom Session”);
CAccVariant val = 0;
val.vt = VT_INT;
val.intVal = 0;
const CAccBstr uuid_CAccBstr(“{39BB91C6-5134-4662-AFB3-188D42FD95AC}”);
xp_str uuid1(uuid_CAccBstr);
HRESULT hr = m_sp->CreateCustomSession(uuid1, &m_customSess);
m_customSess->put_Property(AccCustomSessionProp_Mode, val);
m_customSess->Invite(buddy, OLESTR(“Join me in this custom session”), &m_transid);
}
else
printf(“Custom Session already exists…”);
}
// Accept the Custom Session at the receiving end.
void OnSecondarySessionStateChange(IAccSession* piSession, IAccSecondarySession* piSecSession, AccSecondarySessionState state, AccResult hr)
{
// always accept incoming custom sessions
if (state == AccSecondarySessionState_ReceivedProposal)
{
CAccVariant v;
piSecSession->get_Property(AccSecondarySessionProp_RemoteUserName, &v);
AccSecondarySessionServiceId id;
piSecSession->get_ServiceId(&id);
CAccBstr x = CAccBstr(v.bstrVal);
char tmp[255];
x.GetUtf8(tmp, 255);
printf(“{%s} has sent you a custom session proposal\n”, tmp);
printf(“We are auto accepting the proposal for testing purposes…\n”);
piSecSession->Accept();
}
}
// send a test message to the buddy
void SendCustomMessage(xp_kstr msg)
{
// since this session is a message only session
// we can just send an IM.
CAccPtr im;
HRESULT hr = m_sp->CreateIm(msg, OLESTR(“text/plain”), &im);
m_customSess->SendData(NULL, 0, im);
}
October 1st, 2009 in
Open AIM | tags:
Custom Session |
2 Comments
Here is sample C++ code which works in accsample deployed with the Open AIM SDK. You can copy and paste the below code and see the capabilities in a debugger.
void OnUserChange( IAccSession* session, IAccUser* oldUser, IAccUser*
newUser, AccUserProp Property, AccResult hr)
{
CAccVariant cv;
newUser->get_Property(AccUserProp_Capabilities, &cv);
SAFEARRAY *psa = V_ARRAY( &cv );
if(!psa)
{
printf(“Why can’t I get capabilities!!”);
}
int n = psa->rgsabound[0].cElements;
for (int i = 0; i < n; i++)
{
CAccVariant item;
long rgIndices[1];
rgIndices[0] = i;
SafeArrayGetElement(psa, rgIndices, &item);
}
}
September 6th, 2009 in
Open AIM | tags:
AIM Capabilities |
30 Comments
The Latest Open AIM Newsletter was released yesterday and is available here. You can subscribe to the newsletter here.
Going forward, we plan to send out a newsletter once a quarter and we’d like to include topics that you’d like to hear about. Please take a few moments and let us know what you’d like to see in the newsletter by posting comments in the Developer’s Dialogue forum.
In order to obtain a buddyIcon you would invole the following URL using HTTP:
http://api.oscar.aol.com/expressions/get?f=xml&t=[screenname]&type=buddyIcon
Where [screenname] is the person you’re looking to find the icon URL for. It will return an XML page that has all the info for screenname.
For example, check out the following link using a test screen name as the target argument for a test buddy who has an icon:
http://api.oscar.aol.com/expressions/get?f=xml&t=mtest004&type=buddyIcon
This should return an XML response with all the details, including the url field.
Response below. To view the icon, navigate to the URL field… http://api.oscar.aol.com/expressions/getAsset?t=mtest004&f=native&type=buddyIcon&id=0110b2e8a16872c770f2147cc10da91f419b
<response>
<statusCode>200</statusCode>
<statusText>Ok</statusText>
<data>
<expressions>
<expression>
<type>buddyIcon</type>
<url>
http://api.oscar.aol.com/expressions/getAsset?t=mtest004&f=native&type=buddyIcon&id=0110b2e8a16872c770f2147cc10da91f419b
</url>
<id>0110b2e8a16872c770f2147cc10da91f419b</id>
</expression>
</expressions>
</data>
</response>
Check out the following link using a test screen name as the target argument for a test buddy who does NOT have an icon:
Request:
http://api.oscar.aol.com/expressions/get?f=xml&t=mtest0002&type=buddyIcon
Response: Note that there is no expression or icon for this test Screenname.
<response>
<statusCode>200</statusCode>
<statusText>Ok</statusText>
<data>
<expressions/>
</data>
</response>
Check it out!!! We just released a new AIM 7 Beta 3 with some cool new features! Please download and help us test drive this beta and send your valuable feedback, if you find any issues or have some ideas, you can click on the “Beta Feedback” link and leave a comment.
A major new and exciting feature is the Lifestream! From the release notes, here is what it basically offers…
Keep tabs on what’s going on with your buddies. We’ve added a convenient “Lifestream” tab to the Buddy List. There is so much to check out:
* Get AIM activities like status updates.
* Got friends on other networks? Add your Facebook or Twitter services and never miss an update.
* You can add your YouTube or Delicious accounts too.
* Leave a comment, like an item. Obviously, if your friends don’t have the beta they won’t know about the Lifestream so if you want to try out commenting back and forth with someone make sure they have the beta too.
* See only what you want, try out the handy filtering tool at the top of your Lifestream tab.
* Share photos on your lifestream. Look for Photos section on the right of the page and start uploading.
* Test out the rest of the site, including adding services (click settings at the top of your page), filtering, and more.
You can also upload pictures with your status messages from your PC that will appear next to your status message in AIM 7 and in the lifestream. For now, the pics will be shown next to your status only when viewed by AIM 7 and lifestream users.
I added a new sample called accfed to the Open AIM Dev site. This is a sample written in C++ that demonstrates how to log into Open AIM using federated tokens and a session secret obtained from a Web AIM application. You need to pass in the federated screenname and do not need a password, but instead pass in your DevId of the Web AIM application that is authenticated using Open Auth and the token and the session secret obtained from the response.
The DevId parameter has to match the DevId of the web application from which you obtain the Token and SessionSecret.
Usage: accfed myUserName myDevId myToken mySessionSecret
Example usage…
accfed mytestsn@myfederatedaccount.com ch1t2PGGC_d42BW1 %2FwQAAAAAAADhcsw5R7qRa5Q094F%2FKh9zooQ
VkorkmECTTU9MSkvjRzg%2Bj%2FhO8D5pOnJGU45qo
KT%2BcF%2FVkzLAYEbAzxdchHc07DpCgrNCKqarreIFue
WpsXLupdnQ51KBLdKZc99YuGevgKJEeiUiFNJMNJM%3D NpW6vM371VSvtK7w
The above methodology is only relevant for AOL partners who are either pursuing or already have a federated partner arrangement so that their non AIM credentials can authenticate into AIM.
The Open Auth documentation for the ClientLogin API is here. This API is ONLY available for use with desktop applications are not web based applications.
There are more documents and samples on the main Open Auth site too.
The new Open AIM SDK 1.8.2 supports Windows, Linux, Mac OSX and Mobile! Check out the new cool features of this release and try out the samples! You can download the SDK here.
You can do a lot with the SDK, build your own BOTs, write custom clients, AIM Widgets, Mobile applications using the Web AIM SDK and if you choose to partner with AOL to develop products, check out the AIM Partner Site.
You can check out the AIM Gallery to see what other developers have published.
Functional changes from the Open AIM SDK 1.6.8 to 1.8.2:
- Added aimcc.alerts.aware, aimcc.alerts.enabled and AccAlertProtocol.
- Added AccSessionProp_FederatedAuthToken and AccSessionProp_FederatedAuthKey.
- Added IAccUser::ReportForSpim() and AccReportSpimInitiation.
- Added AccUserProp_BuddyFeedFaviconUrl, AccUserProp_CellNumber, AccUserProp_HomePhoneNumber, AccUserProp_OtherPhoneNumber, AccUserProp_SmsNumber and AccUserProp_WorkPhoneNumber.
- Added AccGroupProp_Blast and AccGroupProp_Permissions.
- Added AccAvTrackProp_Genres, AccAvTrackProp_AlbumName, AccAvTrackProp_AlbumLink, AccAvTrackProp_ArtistName, AccAvTrackProp_ArtistLink, AccAvTrackProp_PlaylistName, AccAvTrackProp_PlaylistLink, AccAvTrackProp_PodcastName, AccAvTrackProp_PodcastLink, AccAvTrackProp_SeriesName, AccAvTrackProp_SeriesLink, AccAvTrackProp_StartTime and AccAvTrackProp_Duration.
- Added AccUpgradeInfoProp_Hash.
- Added AccSessionProp_NewAccount.
- Added ACC_E_UNCONFIRMED_IDENTITY.
- Added preferences aimcc.buddies.[normalized escaped username].cellNumber, aimcc.buddies.[normalized escaped username].homePhoneNumber, aimcc.buddies.[normalized escaped username].otherPhoneNumber, aimcc.buddies.[normalized escaped username].smsNumber, aimcc.buddies.[normalized escaped username].workPhoneNumber, aimcc.buddyList.autoOfflineGroup, aimcc.connect.emailAccountType, aimcc.folders.morePlugins and aimcc.im.direct.receiveRtim.
- Updated Technote 13 with example XML AIM Module.
- Added Technote 14 about Real-Time IM.
- Added support for sending
in standard IMs for some types of accounts.
- Added to languages supported for AccClientInfoProp_Language.
- Updated AccUserProp_BuddyFeedUrl.
- Improved aimcc.plugins.safemode implementation.
- Sending secondary session invitations is now throttled to avoid rate-limit errors.
- Changed result of getting unknown bart items from ACC_E_NO_DATA to ACC_E_MUST_REQUEST_DATA.
- Changed result of getting missing/empty bart items from S_OK/VT_EMPTY to ACC_E_NO_DATA
- Deprecated AccGroupProp_Shared.
- Deprecated AccSessionProp_AppearOffline.
- Deprecated AccUserProp_AwayMessage (use AccUserProp_RichStatusMessage).
- Deprecated AccSessionProp_MaxAwayMessageLength (use AccSessionProp_MaxRichStatusMessageLength).
- Deprecated AccGroupProp_ReadOnly (use AccGroupProp_Permissions).
- Deprecated AccSessionProp_SuperIconTrigger and AccUserProp_SuperIconTrigger.
- On Win32, added AccPluginCleanup().
- On Win32, revamped AV device management, including dependency on setupapi.dll.
- On Win32, added support for VS2008.
- On Linux & Mac, added AccMessageAvailable().
- AccSupport:
- Added xp_s64 support to CAccVariant.
For more details on the fixes of this release, please refer to the release notes.
I have had several queries on Open AIM Forum on building the Open AIM SDK samples for Linux, the SDK and samples can be downloaded here.
Once you untar the SDK and samples, you need to set LD_LIBRARY_PATH by exporting the following, adjusting the path to wherever your SDK is installed.
export LD_LIBRARY_PATH=/home/gmadkat1/accsdk_linux_rhe4x86_1_8_2/dist/release
You also need the Mozilla NSS libraries installed in order to run the samples, this is security software for SSL AIM sessions. More details found here.
You will need Apache Ant in order to build the Java samples. There is a Java BOT sample and a simple Java signon and signoff sample included for the Linux Distribution.
There also equivalent C++ samples for demonstrating a BOT and signon and off, they are easily built using make.
The binaries built above are put into the dist/release directory and can be run from there.
In order to run the Java samples, you need to do the following Java commands in Linux…
java -cp accjwrap.jar:. AccJSample myScreenname mypassword Key:dsdsdsd_deaZdsdd
java -cp accjwrap.jar:. accjbot myScreenname mypassword
I just added a new page on the AIM Developer site for documenting AIM URLs that are supported by the AIM 6.9 client. Look on the Documentation pane to the left of the http://dev.aol.com/aim site and follow the URL to the AIM URL Documentation.
The AIM URLs are a methodology used to send commands that are executed by the AIM 6.9 client for automatically creating an Instant Message, a chat room, or a Buddy List entry.
URLs can allow web pages to pass commands to AIM clients.
You can launch AIM: URLs in several ways:
1. In Windows, enter the command in the Run dialog from the Start Menu.
2. Click on a hyperlink in the IM history window.
3. Click on a hyperlink in a web page (or just type the URL in the browser’s URL field).
They will work when the user is already online with AIM, when the client is not launched and when the client is launched but not signed on it will prompt to do so.
The URLS documented are…
aim:AddBuddy
aim:AIMToday
aim:BuddyIcon
aim:CheckMail
aim:DockBuddyList
aim:GoAway
aim:GoChat
aim:GoIM
aim:GoTalk
aim:Prefs
aim:RegisterUser
aim:SetItem
aim:SetOption
aim:SetStatus
Here is a link to Gus’s website to some handy tools that help you create some of these AIM URLs.
A user asked us a question, they use fetchEvents method and get event BuddyListEvent, but presenceIcon is empty in the “Presence” in the response.
The AIM Host is configured to not send presence icons in buddylist events, this is because of the overall size of the response when users had large buddylists.
But you can check the state of the buddy, ie online or idle or offline and the icons are static and their location fixed, so you can easily access them programatically.
eg http://o.aolcdn.com/aim/img/online.gif
http://o.aolcdn.com/aim/img/offline.gif
http://o.aolcdn.com/aim/img/mobile.gif
http://o.aolcdn.com/aim/img/idle.gif
http://o.aolcdn.com/aim/img/away.gif
I got a question recently asking the below, the following is not yet documented on the AIM Developer site so I am adding it here until it does make it to the site.
sendIM method response format is SendImSubCode.
It has 2 fields:
1. subError
2. subReason
Is there any documentation about subError codes?
Errors: Format below is Values and Description
0 No subcode supplied
1 Remote im is off
2 Remote restricted by PC
3 User tried to send a msg to a SMS user and is required to accept the
legal text first
4 Client tried to send msg to SMS user without the char counter being displayed
5 Client tried to send msg to SMS but SMS matrix said coco combination not
permitted
6 Client tried to send msg to user they can’t im
7 Required payment
8 Client tried to send to a SMS user, but host couldn’t determine country
9 An IM cannot be initiated by a BOT
10 An IM cannot is not allowed by consumer BOT to an user
11 An IM cannot is not allowed by consumer BOT due to usage limited
12 An IM is not allowed by consumer BOT due to daily usage limited
13 An IM is not allowed by consumer BOT due to monthly usage limited
14 User does not accept offline IMs
15 Exceed max storage limit
16 Multi file transfer request blocked by host
One FAQ I run into is how to set preferences, specifically buddy icons using the Open AIM SDK. Here is some C# code that does the icon setting. You do need to have an image that meets the size restrictions for buddy icons, the easiest way to determine the size is to save your existing buddy icon and view it in Firefox to get the dimensions in pixels. You can then downsample your image and convert it to the size that is optimal. I tested this code using awshbuddy deployed with the Open AIM SDK. piSession is your primary session object which you can obtain from any DAccEvent callback and also save as a global. The same general idea below applies to a C++ client, pass in the image as a variant array to Prefs.SetValue and it will work.
System.Drawing.Image imgfile = System.Drawing.Image.FromFile(“c:\\mytestimages\\test.gif”);
MemoryStream ms = new MemoryStream();
imgfile.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
Byte[] buffer = new Byte[ms.Length - 1];
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
piSession.Prefs.SetValue(“aimcc.personalityDefault.0.data”, ms.ToArray());
piSession.Prefs.SetValue(“aimcc.personalityDefault.1.data”, ms.ToArray());
ms.Close();
If you want to integrate AIM into your web app with javascript, AOL just released a new library to help you do this, it is the aimapi-core library. The theBoot.com website we had released recently which I had mentioned in the below post is created using this API.
You can also use this API if you want to integrate AIM into a Flash, Flex, or AIR app.
Check it out! This is the product I was the development lead on before I moved to Open AIM so I feel a certain sense of nostalgia. You can download it off the AIM Website. My favorite feature, and one that I am happy to share, is that the old AIM Running Man is back.
Apart from performance improvements, you can get status updates from your friends on Twitter and other apps. And if you are looking to add buddies, find them easily with the new look up tools. More information available here. You can also find other reviews on Gus’s blog and Greg’s blog.
Stay tuned for a new Open AIM SDK, with the latest API additions that correspond to the AIM 6.9 release.
April 29th, 2009 in
AIM Client | tags:
AIM 6.9 |
45 Comments
Another frequently asked query I run into is how to find the state of an IAccParticipant (Online, offline or idle)? Some DAccEvent callbacks like BeforeImSend pass in an IAccParticipant and not an IAccUser.
You can use the get_User method to get an IAccUser object for the participant and then get the state…
IAccParticipant* pPart;
IAccUser* pUser;
HRESULT res = pPart->get_User(&pUser);
if (pUser) // check result too
{
CComVariant st;
pUser->get_Property(AccUserProp_State, &st);
xp_int state = st.intVal;
switch (state)
{
case AccUserState_Away:
case AccUserState_Idle:
case AccUserState_Online:
// do what you need
break;
case AccUserState_Offline:
break;
}
}
Check out the following really cool site AOL just released… theBoot.com, there is a very good review of it on TechCrunch here. That is a comprehensive review and I do not have much to add to it!
After you visit theBoot, you will see a thin toolbar along the bottom that is labeled Socialthing on the bottom left and on the bottom right there is a sign in button which is for signing in using your AIM account. Once you sign in, your AIM username and password becomes your username and password for the site, and you can access your Buddy List and chat with your buddies. You can choose to always share your activity on the site with the privacy options.
If you comment on a story or do other actions, that comment or action appears not only in the site updates stream, but all of your buddies on AIM 6.9 will see a little info icon next to your name and you can see it if you expand on the AIM 6.9 client.
Please check it out and send comments and feedback! Below is a screenshot of the experience…

You can download it from here.
This release has some performance enhancements, and emphasizes on friend-finding tools, ways to follow your friends’ updates from sites like Twitter and YouTube, ability to display your photo in your Buddy Info. Please download, try it out and send us your feedback on the beta site or the message boards!
Here is a screenshot of how the new interface looks like…

April 14th, 2009 in
AIM Client |
25 Comments
I will post in a bit, was out all of last week on Sanibel Island, and need a brain reset back to AIM Land
April 11th, 2009 in
Uncategorized |
2 Comments
If you want to detect presence of a Screenname on your website and send the person an IM, here is now to do it. Try the following in a browser for a Screenname that you know is valid, and you will see an icon to indicate if the user is online, offline, mobile, idle or away.
http://api.oscar.aol.com/presence/icon?k=ka17kh28wBBZ01b0&t=ScreennameToSendTo
Directs to the following depending on presence..
http://o.aolcdn.com/aim/img/offline.gif
http://o.aolcdn.com/aim/img/online.gif
http://o.aolcdn.com/aim/img/idle.gif
http://o.aolcdn.com/aim/img/mobile.gif
etc…
Now if you want to launch an AIM 6.8+ client to send them an IM, you can do the following AIM URL..
aim:goim?screenname=ScreennameToSendTo&message=Hi,yt?
There are some aimurl generator tools on my friend and co-worker, the AIM Architect Gus’s Website to help anyone create AIM URLs for goim, gochat, setstatus and more.
You can get more details on the aim url about page at here.
The pages let you enter the parameters and it generates the URL as you type.
In the AIM client buddy list, you can organize your buddies into Groups. The categories we support in AIM 6.8 and AIM 6.9 are explained here, I am seeing some confusion about this since we do not allow some groups to be deleted in the client, even programatically.
There are two categories of Groups, Private groups and Public Groups or alternatively, one of my blog readers suggested in a comment, Standard vs Auto groups . A Private group would be a group unique to your Buddy List that you created, and you have total control over it. For example, “Work”, “Buddies”, “AIM Dev”, etc. You control who get’s added or removed or even if the group exists.
A Public group is one that is created by other means. This allows you to create or join a group via a webpage and it automatically added a Buddy List Group of all the members to your Buddy List. IM Blast Groups behave this way. You join the Blast Group. It gets added to your Buddy List. When you leave the group, the group is removed from your Buddy List.
“Bebo”, and “My WIMZI” are groups that can not be deleted.
Smart Groups – http://buddyinfo.aim.com/sg to manage them.
Wimzi – http://wimzi.aim.com/ – click on manage.
Bebo – Not currently deletable.
Blast – http://blast.aim.com – you can go to blast.aim.com and unsubscribe from the group which will make the group disappear from your Buddy List.
The Web AIM API lets developers incorporate core AIM functionality into any web page, including the ability to sign on, send and receive IMs, and obtain a user’s Buddy List. The API I am going to provide some detail on allows you to push a simple Buddy Feed Item so that your buddies can view them via the AIM 6.8 and 6.9 beta clients through your buddy info.
The usage of the API is detailed on the AIM Developer Site for the Web AIM Server API Reference.
There are 2 options for how to call this API and I will provide usage examples for both. I am not providing code here, since it is too voluminous for a blog post, but please contact the AIM Developer Forum for API usage and sample code.
The first option uses the aimsid parameter which is obtained by the http://api.oscar.aol.com/aim/startSession API, as a part of the response. You can invoke this API and save the aimsid for use below. I have shown the response below as well.
http://api.oscar.aol.com/buddyfeed/pushFeed?&f=xml&aimsid=051.0352240858.1661937412:mytestsn&feedDesc=Testing.&feedLink=ht
tp://www.aol.com&feedTitle=TestFeedTitle&itemDesc=TestingFeed!&itemGuid=StMsg1236891813000&itemLink=http://www.aol.com&it
emTitle=TestTitleFeed!&k=mo1XK7vb5IyNRmU9&nocache=1236891813000&r=10&ts=1237777627
<response xmlns=”http://developer.aim.com/xsd/buddyfeed.xsd”><statusCode>200</statusCode><statusText></statusText><requ
estId>10</requestId><data></data></response>
The second option uses the a= parameter for passing the token…
http://api.oscar.aol.com/buddyfeed/pushFeed?a=%2FwQAAAAAAABR%2BtiXoKOkbBhKHxjZMSWKiwKS2fvVKaR1fUQQQd12TENtC8bgQko99nIS42
hW98dzNsIQ7FkHmtLOBdrzYY6KWb4LGRblEN4kg6DRIfEEwHlP1CazdmDpK1N38Cu45Vu3EQQzr9hqdZpYMOC1K
59dJBZooqwCZM1CPuoX0tZLao88X5s%3D
&f=xml&feedDesc=TestingFeed.&feedLink=http%3A%2F%2Ffoo.aol.com&feedTitle=TestFeedTitle&itemDesc=TestFeed1&itemGuid=StMsg12368918
13000&itemLink=http%3A%2F%2Fwww.aol.com&itemTitle=TestTitle&k=mo1XK7vb5IyNRmU9&nocache=1236891813000&r=10&ts=1237773442
<response xmlns=”http://developer.aim.com/xsd/buddyfeed.xsd”><statusCode>200</statusCode><statusText></statusText><requ
estId>10</requestId><data></data></response>
Note that you do need to encode the url based parameters that are passed in for the token based request to work.
You can use this… java.net.URLEncoder.encode(“http://foo.aol.com”, “UTF-8″));
Here is some sample C++ and Java code to sign on and set the status text of the logged in user. This is a code snip taken from the C++ and Java samples accsample & accjsample in the Open AIM SDK 1.68 and modified to set the status text for the user.
C++ Code snippet below…
CAccPtr sp;
HRESULT hr;
if (SUCCEEDED(hr = AccCreateSession(IID_IAccSession, (void**)&sp)) && SUCCEEDED(hr = Advise(sp)))
{
CAccPtr spClientInfo;
hr = sp->get_ClientInfo(&spClientInfo);
if (SUCCEEDED(hr))
{
CAccVariant desc(“accsample (key=dummykeyreplacewithrealkey)”);
spClientInfo->put_Property(AccClientInfoProp_Description, desc);
if (SUCCEEDED(hr = sp->put_Identity(CAccBstr(userName))))
hr = sp->SignOn(CAccBstr(password));
sp->put_Property(AccSessionProp_StatusText, CAccVariant(“Testing setting a status”));
Java code below…
try {
// Create main session object
session = new AccSession();
// Add event listener
session.setEventListener(this);
// set key
AccClientInfo info = session.getClientInfo();
info.setDescription(key);
// set screen name
session.setIdentity(username);
session.signOn(password);
session.setProperty(AccSessionProp.StatusText, new AccVariant(“i am trying this out”));
} catch (AccException e) {
log(“Exception: ” + e.errorCode);
e.printStackTrace();
}
If the user does not have a status set, the call will throw an exception and you need to catch it and act on it if you desire.
Here is some sample Java code to get a status of all your buddies on your Buddy list. There is a bug in the current Open AIM SDK 1.68 in which the getStatusText for a user with no status set returns ACC_E_TYPEMISMATCH but in the 1.8 branch, it is failing with ACC_E_NO_DATA, which makes more sense if there is no status set.
Java code below… this assumes you already have a buddy AccUser object called buddy below. For an example on traversing the buddy list, look at my post here.
try {
AccBartItem b = buddy.getStatusText();
String status = b.getDataObject().getString();
System.out.println(” Status Message: “+ status);
// alternatively…
System.out.println(” Status Message: ” + new String(buddy.getStatusText().getData()));
}
catch (AccException e) {
log(“getStatusText failed” + e.errorCode);
e.printStackTrace();
}
We just released a new AIM 6.9 client beta here.
Some of the changes in this release are new theming, changes to the profiles, addition of Bebo profiles integration into the client, status messages in the IM window, and the ability to express emoticons as text.
A cool new feature is AIM Blast, you can use this to IM your friends, coworkers, or customers all at once.
Some under the hood changes are the migration to using the VS2008 compiler and runtime, and some performance optimizations.
March 18th, 2009 in
Uncategorized |
6 Comments
This is asked frequently enough on the AIM Development forums that I decided to post some code for future reference. The Open AIM SDK and the Open AIM SDK Javadocs have all the details of the classes I am referring to below, including AccGroup, AccBuddyList and AccUser, so I will not go into detail explaining what they stand for. The primarysession object is easily available from any part of your application or plugin, including the event callbacks.
Here is some Java code to add a buddy… the same concept applies in C# or C++ too, but the syntax will differ as will the API usage.
AccBuddyList buddyList = primarysession.getBuddyList();
AccUser user;
AccGroup grp = buddyList.getGroupByName(“Family”);
user = grp.insertBuddy(“nameofbuddy”, 0);
And to remove a buddy…
AccUser buddy;
buddy = grp.getBuddyByName(“nameofbuddy”);
int index = grp.getBuddyPosition(buddy);
grp.removeBuddy(index);
Here is sample code for an AIM Module Plugin (AMO) that allows you to add menus to the AIM 6.8 client to add some of your own functionality.
There is some documentation on how to develop AIM Module Plugins on the AIM Developer Site. You can also find some samples as a starting point there. There is also a useful set of posts in Gus’s blog on the topic.
The sample I want to cover in this post is available here.
This sample demonstrates how use the Open AIM SDK to retrieve the primary user’s buddy list and the users primary identity. This Module Plugin adds two menu items, one of them to the Actions menu which can be used to demonstrate the displaying of the BL, and the other on the right mouse click context menu when you select a buddy, so that you can do something custom with that selected buddy in your plugin.
Here is how you get the list of buddies you can multiple select in the AIM 6.8 buddy list…
var jsSelectedBuddies = window.external.client.selectedBuddies.toArray();
Here is how you send IMs programatically to all your selected buddies…
function sendIm(names)
{
var s = client.primarySession;
var im= s.createIm(‘yt?’, ‘text/plain’);
for(var i=0; i
{
var ims= s.createImSession(names[i]);
ims.sendIm(im);
}
}
Here is how you add menu items to the client. In the plugin.xml, the following adds 2 menu items, the first one to the Actions button drop down menu, and the second to the RMC menu on the selected buddy. There is a detailed description of the API and the flag values here.
<commands>
</command id=”1″ text=”[AIMcc Sample] Show Buddy List” flags=”2″>
</command id=”2″ text=”[AIMcc Sample] Send ‘yt?’” flags=”4″>
</commands>
Here is how you respond to menu items in the client…
function onCommandExec(cmd, names)
{
if (cmd == 1)
// act on the Actions menu item
else if (cmd == 2)
// act on the RMC menu item
}
March 12th, 2009 in
Open AIM |
57 Comments
Last year, we developed a feature in the AIM 6.8 client to make AIM more accessible to the deaf community in collaboration to Gallaudet’s Technology Access Program (TAP), more details are found here. The usage of this feature is documented here. This was a way for people to combine the familiarity of messaging on a TTY with the AIM service.
There has been some recent interest in how to make Open AIM clients implement the Real-Time IM feature that is deployed in the AIM 6.8 client. The basic idea is the you establish a direct connection to your buddy and you can both see what the other is typing as they are entering or backspacing or erasing text. For obvious reasons, this feature can be turned on and off and needs permission from your buddy to establish.
We just released a new Open AIM tech note on how to implement Real-Time IM here.

A very cool AIM client for the Android phone developed by Multiple Facets has been released, there is information available on the client here. I found the AIM client remarkably easy to use and very intuitive within the framework of Android to do all the IM functionality that I am used to performing. The design is simple and the flow of control is smooth, navigating from the IM windows to the buddy list and organizing your sessions.
Without going into too much detail since the client is documented on its site above, here are some of the features…
- Adding multiple Screennames to sign on with and the ability to auto save passwords.
- Change your status to away or invisible.
- Add custom status messages and away messages.
- Add and edit groups and users.
- Allows setting of some preferences like sounds, privacy, notifications, icons etc.
- Keeps a list of recent conversations which you can select and navigate to.
- Shows a counter of the number of IMs received against your buddies name, I like this feature.
Here are some code snippets to do some frequently asked about tasks in the AIM Plugins.
The following command can be used from within your C++ AIM plugin to launch an IM Form and populate it for sending to a buddy…
::ShellExecute(NULL, “open”, “aim:goim?screenname=testsn1&message=Testing opening an IM Form”, NULL, NULL, SW_SHOW);
If you want to find and bring the AIM Buddy list window to the foreground, here is how to do it…
HWND blWindow = FindWindow(NULL, “AIM”);
if (blWindow != NULL)
{
MessageBox(NULL, “Got AIM BL window”, “test”, MB_OK);
::ShowWindow(blWindow, SW_RESTORE);
MessageBox(NULL, “Now show minimizing it”, “test”, MB_OK);
::ShowWindow(blWindow, SW_MINIMIZE);
MessageBox(NULL, “Now show restoring it”, “test”, MB_OK);
::ShowWindow(blWindow, SW_RESTORE);
}
If you want to find an IM window, it is somewhat trickier since the title of the window is not fixed.
To check for an imform window, the following with lowercase and spaces stripped are good matches for the window title…
imwith|imswith|ims|newim|away|talkwith|videowith|pictureswith|chatroom
// OX_FRAME_CLASS is the classname that identifies the AIM windows
blWindow = FindWindow(OX_FRAME_CLASS, NULL);
if (blWindow != NULL)
{
MessageBox(NULL, “Got an AIM Window”, “foo”, MB_OK);
::ShowWindow(blWindow, SW_RESTORE);
char title1[1024];
while (blWindow != NULL)
{
blWindow = GetNextWindow(blWindow, GW_HWNDNEXT);
GetWindowText(blWindow, title1, 1024);
// just a hacky example to illustrate one of the matching IM Window title searches
if (!strnicmp(title1, “im with”, 7))
::ShowWindow(blWindow, SW_RESTORE);
}
}
February 28th, 2009 in
Open AIM |
2 Comments
I have had several users ask me this on the Open AIM Forum and am posting a snippet of working Java code that obtains a list of a user’s buddies after they are signed on. The buddies are organized similar to how they are displayed in the AIM 6.8 client, by groups. I tested this in one of our Java samples called accjsample, which is deployed with the Open AIM SDK. Once you have a AccSession object, you should be able to do the following…
AccBuddyList bl = primarysession.getBuddyList();
int ct = bl.getGroupCount();
log(“group count : “+ ct);
for (int i = 0; i < ct; i++)
{
AccGroup group = bl.getGroupByIndex(i);
log("group name: "+ group.getName());
int ct1 = group.getBuddyCount();
for (int j = 0; j < ct1; j++)
{
AccUser buddy = group.getBuddyByIndex(j);
log(" Buddy name: "+ buddy.getName());
}
}
This is one useful diagnostic plugin authored by Gus Verdun that I cannot say enough good things about. It has been covered in Gus and Greg’s blogs and I am reiterating it here, since it is an invaluable tool for all AIM Plugin and AIM Custom client developers. It shows all events sent by the Open AIM API and a lot more, you refer to the link above for details. You can run this plugin with accbuddy or any custom client as well as the AIM 6.8 client.
You can download it here.
I got an Android development phone a few weeks ago and have been experimenting with it. You can order them here. It is a SIM-unlocked and hardware-unlocked device. Debugging on this phone is remarkably easy, just plug the phone into your serial port and the Android Eclipse plugin will detect and use the device instead of the Android emulator. There is a reasonably good introduction and tutorial to developing for the Android. There are several Android forums out there and also one on Google groups, all of which are useful sources of information.
You can use the Android Developer Guide and Web AIM API in order to develop Open AIM applications for this device.
February 21st, 2009 in
Android,
Open AIM | tags:
Android,
google |
34 Comments
An AIM Module Plugin (AMO) is specifically designed to take advantage of the new capabilities of AIM 6.8 clients and above, and will only work within those clients. With a Module Plugin you can enhance the AIM Client by changing UI elements by adding features such as a stock ticker or information from your favorite social networking site. Check out our FAQ for more information. We also have several samples available on our Dev Site at Open AIM Samples and on the AIM Gallery. The AIM Architect, Gus has a good introduction and pointers on his blog here.
An Open AIM Custom Session is covered in detail here, I would recommend referring to it before reading further. The sample I am covering here is about creating a Message mode Custom Session which supports two participants, and allows messages to be sent peer-to-peer to a buddy.
{myGUID} is to be replaced with a valid UUID that is shared by both the sender and recipient and asserted as a capability on both ends for identification purposes.
When you load your AMO, do the following on the sending and receiving ends…
// assert custom capability, this capability is a UUID
window.external.client.primarySession.addCapabilities(“{39BB91C6-5134-4662-AFB3-188D42FD95AC}”);
You can add an HTML button or a menu to trigger starting the Custom session…
// create the custom session
customSession = window.external.client.primarySession.createCustomSession(“{myGUID}”);
customSession.mode = 2; //1 is stream 2 is message
customSession.invite(buddy, “Hello, join me in this session”);
On the recipient side… define the following callback which is invoked when the custom session is created.
function OnSecondarySessionStateChange(session, secondarySession, state, hr)
{
// need to make sure that the secondary session is a
// custom session and that the custom session is ours
// 6 = AccSecondarySessionServiceId_Custom
if (secondarySession.serviceId == 6)
{
// check the UUID
if (secondarySession.uuid == “{myGUID}”)
{
// 50 = AccSecondarySessionState_ReceivedProposal
if (secondarySession.state == 50)
{
secondarySession.accept();
customSession = secondarySession;
}
Then on the sending side once the secondary session is online….
function OnSecondarySessionStateChange(session, secondarySession, state, hr)
{
// 500 = AccSecondarySessionState_Online
if (secondarySession.state == 500)
{
// make the content plain text for now
var im = window.external.client.primarySession.createIm(“Testing sending a message”, “text/plain”);
// send the data to the buddy
customSession.sendData(“”, 0, im);
}
}
Then define 2 more events…
// event to confirm the custom send worked
function OnCustomSendResult(session, customSession, receiver, im, result)
{
// check the result for failure
}
// event for receiving a custom session message
function OnCustomDataReceived(session, customSession, sender, data)
{
// check the data comes from a session that we know about
if (customSession.uuid == “{myGUID}”)
{
var content = data.getConvertedText(“text/plain”);
// do something with the content here, just displaying it for now.
statMessage.innerText = “Received custom data = ” + content;
}
}
Welcome to my blog. I have been wanting to launch a blog to address frequently asked questions from Open AIM users and issues I run into while developing custom clients or plugins.
February 20th, 2009 in
Uncategorized |
36 Comments