Quite often I find services I’m using inadequate. Something is missing, or not working the way I hope, I wish it could be changed. In a fraction of the cases it can actually be changed, and an even smaller fraction I go and change it myself.
This time it was bugging me that while I am always aware if I have new contact established on Facebook (or colloquially “friended someone”), but there’s just no way to know if someone cut ties (“defriended”) me. In some ways that knowledge is just as important, since the first means I succeeded in being interesting to another person in some way, the second means I was actually annoyance – not just being ignored and never talked to but people took the effort to never hear about me again. Recently quite a few people did that to me, or at least it’s only now that I try to find them for this or that but I can’t. I never want to be caught off-guard like this again, so I made Friendcare.
It was mostly an exercise in web app building, since if it was only for me, I could have just set up a script on my server that monitors things. It’s more fun as well. First I started it a long time ago, tried to work on it and rewrote from scratch a couple of times until getting here.
What does it do?
In this one the site just gets the user’s friendlist (a list of IDs) from Facebook and compares it with the last known friendlist. If there are new IDs, they are considered friend gains, if there are missing ones, those are friend losses.
Actually it got pretty complicated logic (for my usual thinking) inside because of the asynchronous management of good NodeJS apps, had to think a lot about what information is available at what step and what time of the usage. It also didn’t help that I haven’t really planed the user experience (UX) first, just started to code. Some of the things are surely pretty terribly done because of premature optimization and scaling I was doing while only havng a single user of the site. All in all, it’s an absolutely horrendous mess in the inside that still seems to implement a suitably close approximation of what I wanted. Surly will need some refractoring sooner rather than later.
It’s amazing how many different parts I need to use to make one complete site work, a total web-tech-soup. Everything is in a library or in an external service. It’s good and bad – good because other people did the heavy lifting for me already, bad because every one of them needs a non-trivial effort to learn and all of them different. Nevertheless, trying to keep things minimal. At the moment it’s NodeJS on Heroku, with MongoDB and using Heroku Scheduler to trigger the update service. The other modules and parts are:
Without Everyauth nothing would work, it handles the Facebook authentication on the backend. Also, it gave me ideas how the site can be extended to multiple services / multiple social networks.
There are so many interfaces to talk to Facebook, and the heroku-nodejs app I started off from uses one of them as well. That just seems to be too specialized for an example app, not in functionality but in implementation. Instead I found myself another library, fbgraph, and so far so good. If I really wanted to, I could even easier interface just the Graph API, but no need to do that at the moment.
I choose Mongoose/MongoDB to store the associated data, well, basically because MongoLab had the largest free database offering of all the databases I have checked. So far so good. I like the schemaless database, though already run into problems when I was updating wrong fields in the dataset I was surprised that the results didn’t show up at the right place. I guess that’s a danger I can live with at the moment. Will have to learn more about it, how to back things up, how to maintain it well, and about mongoose and it’s schemas.
The core functionality is basically taking the difference of two sets, and in general there is quite a bit of set manipulation, so Underscore works very well, I used for a couple of other parts as well (reduce, groupBy), and it works well. The whole thing feels like it should be part of the base library.
While risking that I’ll look exactly the same as many others, Bootstrap does give some good-looking results with moderate effort. Will have to do some tweaking because I know so little about making good UIs, but it’s a start.
Used EJS for templating, and it’s great. Fast, flexible, and it’s not too bad that I have to fill in most of the HTML manually. I will know more about the structure of the client facing side of the page more than I would otherwise.
There are things that went well and not so well.
- Maybe the most important: Facebook is unreliable. Sometimes I got missing people in the list that appear in the next update again. This happened when using Graph API, will have to see if FQL is any better. From my experience: not, it just has different problems.
- From the app’s point of view, some simplification needed. Too many middleware and helpers, this I quite often not sure about what is the state of my data, what variables were available and what are not.
- Forums are not always helpful, quite often people have really dumb answers to questions, so have to figure things out myself.
- Too many successful libraries mean that the library-soup will inevitably cause problems, and people start writing new libraries that connect and unify the old ones: mongoose & backbone, mongodb & everyauth, so much magic (ie. behind the scenes stuff) happens.
- I still like to make logos and facicons, though I’m sure they are terrible, it makes good playtime in Inkscape and Gimp. Might have to change the colours, it does remind me of a strange toilet logo…
In the end, I’m solving a very narrow problem at the moment, a problem that so rarely arises, that I don’t even know if it will happen again. But if it does happen, without this I wouldn’t know about it, so still worth it.
Might extend it later to count Twitter followers, Google+ circles, Github watch/fork, whatnot… But that’s later when I see how does this work, I care much less about those than my “friends” because of the symmetricity of it .
The good thing is that currently it works well enough that I kinda got this off my chest and can back to making a FUSE module for Ge.tt, a group based location sharing mobile app, an app to connect my Goodreads to-read list and bookstore databases, adding Open Graph and Rich Objects to Octopress, getting out an update for WatchDoc, or even check out the games I just got from HumbleBundle. But will come back to this, will have to make it better (it’s a compulsion).
Finally, if you the site, let me know your suggestions, I’m eager to learn. The source is up on Github.