Thursday, April 06, 2006

Sending an Instant Message via Script using LCS and Communicator Web Access (Ajax)

Its been some time since I had a chance to play around with any LCS code I saw the release of the AJAX SDK so I decided to have a bit of read and see if I could put together a few bits of code. If you’re comfortable writing WebDAV code you’ll feel at home with Ajax its just a matter of posting and getting data via a Http control. Starting real easy I thought I’d try a simple VBS script to send a message from the command line.

The script itself is fairly basic it uses NTLM authentication to first logon to a LCS server using the Logon URL. After it logs on successfully you need to get the cookie for the session which is used when calling any further functions. To send a message the StartIm method is used which basically tries to start an IMSession along with sending a message. The last section of code then calls the logoff URL. Before you run the script you need to configure the hardcoded variables in the config section basically you need to put in the name of the LCS CWA server
Servername = ""

The Sip address of the user that is going to send the message
LogonSipAddress =
The username and password of a user that has rights to logon on to the sending SIP Adreess
Username = "domain\username"
password = "password"

The script is designed to be run from the command-line with 2 command line parameters the first is the user’s address you want to send to and the second is the message you want to send so to run the script use something like

cscript lcsSendmsg.vbs "Hello world how are you doing”

I’ve put a download of the script here the script itself look like

' ----Config----
Toaddress = wscript.arguments(0)
Message = wscript.arguments(1)
Servername = ""
LogonSipAddress = ""
Username = "domain\username"
password = "password"
' ----End Config----
set req = createobject("microsoft.xmlhttp")
' ----Logon
Logonstr = "https://" & Servername & "/iwa/logon.html?uri=" & LogonSipAddress & "&signinas=1&language=en&epid="
req.Open "GET",Logonstr , False, Username ,password
wscript.echo req.status
reqhedrarry = split(req.GetAllResponseHeaders(), vbCrLf,-1,1)
for c = lbound(reqhedrarry) to ubound(reqhedrarry)
if instr(lcase(reqhedrarry(c)),"set-cookie:") then reqsessionID = right(reqhedrarry(c),len(reqhedrarry(c))-12)
chk = left(reqsessionID,36)
' ---Send Message---
Sendmsgcmd = "https://" & Servername & "/cwa/MainCommandHandler.ashx?Ck=" & chk
Messagestr = "cmdPkg=1,LcwStartImRequest,sip:" & ToAddress & "," & Message & ",X-MMS-IM-Format: FN=Arial%253B EF=%253B CO=000000%253B CS=1%253B PF=00" "POST", Sendmsgcmd, False, Username ,password
req.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
req.setRequestHeader "Cookie:", reqsessionID
req.send Messagestr
wscript.echo req.status
' ---Logoff---
logoffstr = "https://" & Servername &"/cwa/SignoutHandler.ashx?Ck=" & chk
req.Open "GET",logoffstr , False, Username ,password
req.setRequestHeader "Cookie:", reqsessionID
wscript.echo req.status


Robert Hupf said...

Is it possible to have this script use the default credentials of whoever is logged on instead of having to hard code them in the script?

Glen said...

Yes if you set the username and password to blank eg "" then when the browser control tries to connect it will attempt to negotiate authentication using the currently logged on users credentials. This will only work if your using NTLM authentication.

edgecrush3r said...

GREAT piece of work!!

1) Is there any reason why you didnt use JSON Methods to Send the IM message instead of sending the 'LcwStartImRequest' command to the MainCommandHandler.ashx page?

2) Where did you find the information about the 'MainCommandHandler.ashx' handler ?? Are there any similar commands to set the presence note, and PresenceStatus ??

Glen said...

My Ajax skills where pretty basic when i wrote this so i stuck to what i new. Using JSON would be a much better method at the time there was very little around about using this stuff.

2. Some of the information i used came from the SDK most of it was reverse engineered using Packet captures from Etheral because the SDK at that time didn't document everything :(. It you can do it in the web client then you can simulate this with a script it just a matter of spending the time to work it out

Richie Rich said...

I would love to see an example bot, that can receive an IM message and then do a SENDMESSAGE to an Active Directory Group, enumerating the sip addresses of each member and looping through it. Microsoft currently has a rolebot sample in C#, but it will only send out a single IM to the first available member of the group. A vbs script such as this, I think would fill a big void

Glen said...

I've got a simple bot as a starting point. The rest of what you described is just some real simple ADSI code to do directory lookups


Anonymous said...

I get an error :The host name in the certificate is invalid or does not match, can you maybe help

Glen said...

This usually means you'll client doesn't trust the SSL certificate you using. Eg when you use a browser normally against the CWA you get security popups about the certificate not being trusted. Because the code cant deal with these errors you need to make sure that you import the certificate your using so its trusted on the machine your running the code on

Patrick said...

Thank you for the great examples. I have learned a lot.

My question is this: How does one go about sending the JSON commands to LCS? Will they continue to support the LCW type commands in the future?

Flaphead said...

Dude have you managed to get this to work with OCS 2007?

upperwall1 said...

hi i got an error 484 login required, please help