Everyone who's tried to find a decent MSN Messenger client for the Mac knows it's no easy task. There are a number of contenders:
Adium,
aMSN,
Fire,
Mercury Messenger,
Proteus, and of course -
Microsoft Messenger for the Mac. No client is perfect. Actually - most are terrible (if you ask for a decent interface at least). Adium and Proteus are good but both use libpurple. libpurple is a great library although sadly enough it still doesn't cut with personal messages, voice clips, AV conversations and handwriting for MSNP.
After Adium started giving me loads of disconnection errors lately (which stopped after recompiling with an older version of libpurple, but then started again), and after upgrading the RAM on my MacBook to 4GB - I decided I can now keep VMWare on all day long in Unity Mode and just use the original client.
I love my Mac, but there are still some programs with no equivalent in the Mac world. One is WLM, for the reasons I counted, and some more are Microsoft Office and Subtitle Workshop (if anyone finds a decent alternative, please let me know!). Internet Explorer used to be on that list as well - for using older websites that don't work with Firefox, but with today's Greasemonkey scripts - almost everything works.
Anyway - to business: after a few days of use I found that my solution has a serious flaw. When someone sends you a message on Windows, the conversation window appears minimized on the taskbar and blinks until you've opened it. In Unity Mode, with the taskbar hidden (it looks just awful when it is not), you cannot see if someone sent you a new message, and you also can't see if someone with a hidden or minimized conversation window has sent another message.
The first problem (minimized new conversation windows) was easy to solve: you just need to write a Messenger Plus! script to shoot up on the event of conversation window creation and send a message to that HWND to restore from the taskbar.
For those who aren't familiar -
Messenger Plus! is a wonderful addon (along with the
mess.be patch) to MSN (now Windows Live) Messenger. It adds a lot of great functionality, including the long-anticipated tabbed chat windows (which sadly enough do not work well in Unity Mode - they leave tracing borders and background when moved around) and a whole-lot-better logging system. Messenger Plus! let's you enhance it even more by writing JScript scripts that perform all kinds of stuff.
Anyway - so now new conversation windows were popping up with new messages and all. I'd prefer them to silently appear minimized on the Dock, but I could not think of a better approach than restoring-and-then-minimizing, which keeps the annoying effect.
I gave it another day to see if I could cope with the second problem of no-notification-on-new-message. Very quickly I found out that - no. If you tend to do other things while IM-ing, you'll quickly leave people hanging for half-an-hour because you started doing other things and forgot.
I decided the best way to keep track of new messages is Growl notifications. I'd have to write another MSNP! script that will send Growl notifications upon new messages arrival. A little Googling revealed that Growl already has networking capabilities over TCP or UDP with their own protocol. After some trial and error with the Terminal I figured out that the network notifications protocol did not by any means support custom application icons. And that generic network-notification icon did not shine.
So - I wrote a Python SOAP server that sat on the Mac side, and recieved notifications from a Python client on the Windows side (which included a title, a message and a Base-64 encoded PNG icon) forwarding them to Growl itself, using their command-line utility. No authentication and encryption were used because the SOAP library I found did not support any HTTP authentication schemes. If someone would like to convert the server to use a different library and incorporate Basic authentication or something, I'll be more than glad.
Anyway - the last brick was the MSNP! script which listens to new message events and calls the client Python script with the contact name, shortened message and the file name of the contact image. A little problem I ran into was converting the Windows Hebrew encoding (
cp1255) to
UTF-8 for the SOAP request. It turned out to be a matter of adding another parameter to the
unicode() method, but I couldn't find it documented anywhere.
Out of there, everything was working great. People were messaging and the notifications were showing, up until some girl with a '<3' in her nickname decided to send a message and then I found out I've forgotten to escape the XML-important characters (and quotes - which caused another problem when passing the message across command-line calls).
So that is it. Here's a screenshot showing how it looks:
Here are the links to the Python
server and
client (the client is included in the relevant MSNP! script as well), the
launch-daemon plist file for the server (which goes into
~/Library/LaunchAgents/), the MSNP! script for the
Growl notifications, and the MSNP! script for the
automatic restoring.
A zip of all the files is also available
here.
I hope someone else out there who is pissed because of the lack of a decent Messenger client for the mac will be able to put this code into good use!
Notes:1. You need to install Python on your virtual Windows machine.
2. If you use a different windows character encoding than I, you can look for it
here and replace the instances of
cp1255 in the client script with it.
3. I did not use relative paths in the code, because I was not familiar with which is the current-working-directory when launching Python scripts with
launchctl and such, so the paths you may have to change in the code are:
- The growlnotify tool - it comes in the DMG with Growl, and lets you send notifications from the command-line. You should put it in /usr/local/bin/ or change the path in the server code to where it is.
- As an alternative icon (if none was sent from the client) I've decided to use the icon for the Microsoft Messenger for the Mac. I will not include it here because it is probably under copyrights and such, but for you personal use I think you can copy it (Cmd+I on the application; click the icon; Cmd+C), create a new image from clipboard (Cmd+N) in Preview, and save it as a PNG somewhere. You should then change the /Users/tomer/Development/MessengerGrowl/Notifier/msn-icon.png path in the server code to yours.
- The Growl MSNP! script assumes MSNP! is installed in C:\Program Files\Messenger Plus! Live. If you have it installed in a different location you'll have to open up the Growl Notifier.js file from Scripts\Growl Notifier down the MSNP! directory and change the path to the client.py on line 21.
- Also, the Growl MSNP! script assumes Python is installed in C:\Python25. If it is installed elsewhere, you'll have to change the path to the Python executable in the JScript file (same place as the last one - only line 22).
- You have to change the path in the launch-daemon plist file to where you placed your server script
4. I told Growl to require a password for networked-notifications. The password is set in the server script in line 31. You can also set it to an empty string if you've set Growl not to ask for a password.
5. The server.py and client.py contain the local IP address of the Mac network interface (and VMWare's network device must be set as
Bridged and not
NAT, too). In my case it was 192.168.1.12, and you should change it to your static or statically-leased IP address.
6. The server script uses the SOAPPy lib, so you'll have use MacPorts (
port install py-soappy) to get it and all it's dependencies. I can't remember, but I don't think there were any other dependencies. If you'll run into any problems, please let me know and I'll look it up.
7. As the current port for SOAPPy is only for Python 2.4, the server script's shebang is followed by
/opt/local/bin/python2.4. If you've installed your MacPorts elsewhere, or you are using SOAPPy with a later version of Python, you'll probably want to change that.
Cheers,
Tomer