An API for Faking Swedish user details

Lorem Ipsum is great for generating place holder texts, and (and our own Place-A-Pet!) does the same job for images. Sometimes though, you need to create fake Swedish users. Say you want to generate dummy comments or fake forum users. What to do?

I just created a little webservice for this. Get a HTML-table by going here:

…or get a JSON-feed by adding &format=json to the url, like this:

Enjoy :)

Let Slack nag you that it’s time to return that commuter pass

Another week, and yet another Slack integration here at Earth People.

This time we’ve added an integration to the public transport system here in Stockholm.

At Earth People we like to use public transportation when going to meetings with clients. That’s why we have bought a couple of commuter passes that we can use whenever we need to go to a meeting.

It works great. But there is one problem however: we only have a few cards, so when you return from the meeting you must remember to return the card so others can use it. And that’s were our latest integration comes into play:

Screenshot showing a message posted to a slack channel, with the date and time of a journey Yup, shortly after the card has been used, a message from the card will appear in our slack channel. That works pretty good as a reminder.

And as a plus feature it also shows how much cash that is left on the card, so we will also know when it’s time to refill the card.

There you have it: another super useful integration for Slack.

Oh! And thanks to mysl for their API-wrapper for “Mitt SL”, that led us into the right direction when researching the API.

Let Slack tell you what songs are currently playing in the office

At Earth People, there’s always music in the air (and the birds sing a pretty song).
Most of the stuff we play is fairly unknown to most of us, and in many cases only played once, ever.

To get rid of all the “Hey what’s this song”-chatter or Slack, I made a litte script which we run as a Slack Command.
The script just checks all the of the people usually playing music, and returns what’s on.

Screenshot 2014-10-15 16.51.02

By no means magic, but adds another bit of homey feeling to Slack.
Here’s the Gist, be our guest.



require 'vendor/autoload.php';

use GuzzleHttp\Pool;
use GuzzleHttp\Client;

$client = new Client();

$users = array('suprape','musikmarskinen','dafeather','brunobrandstrom','Algoritm','mjelle','hjalle','johannagrip','tumde');

$requests = array();
foreach($users as $user){
	$requests[] = $client->createRequest('GET', '', [
		'query' => array(
			'method' => 'user.getrecenttracks',
			'limit' => '5',
			'api_key' => 'GetThisFromLastFm',
			'format' => 'json',
			'nowplaying' => 'true',
			'user' => $user

$results = Pool::batch($client, $requests);
$nowplaying = array();
foreach ($results->getSuccessful() as $response) {
	$recenttracks = json_decode($response->getBody()->getContents());
		foreach($recenttracks->recenttracks->track as $track){
				$temp = new StdClass();
				$temp->artist = $track->artist->{"#text"};
				$temp->title = $track->name;
				$temp->album = $track->album->{"#text"};
				$temp->image = $track->image[3]->{"#text"};
				$nowplaying[] = $temp;

header('Content-type: text/plain;charset=utf-8');
echo "Verkar som att ".count($nowplaying)." låtar spelas på kontoret just nu:\n";
foreach($nowplaying as $track){
	echo '- "'.$track->artist.' - '. $track->title.'"';
		echo ' från skivan "'.$track->album.'"';
	echo "\n";

Making headless screengrabs without PhantomJS

Ok this can be done with PhantomJS and it is probably better/simpler/etc. But if you, for any reason, can’t use PhantomJS to make screengrabs, here’s an over complicated alternative we came up with.

wkhtmltopdf is an easy way of making screengrabs of webpage:
$ wkhtmltopdf “” googlescreendump.pdf
Most package managers (at least Rpm and Aptitude) has it, and it just works. Some arguments may or may not work, depending on version number, and this example is based on the 0.9.9 which Aptitude offers right now.

While this works fine on your local machine, it won’t on a headless server, so we install Xvfb which acts a virtual X-server.
$ xvfb-run –server-args=”-screen 0, 1024x768x24″ wkhtmltopdf googlescreendump.pdf

This will give you a pdf, probably with the webpage not filling the entire page. To get a usable image file, you need to run it through some Image Magick:
$ convert googlescreengrab.pdf -trim -gravity southeast -background none -splice 50×150 googlescreengrab.png
The arguments need to be tweaked for your setup, so you get the entire screengrab and nothing else.

In total, this is what the command looks like:
xvfb-run –server-args=”-screen 0, 1024x768x24″ wkhtmltopdf -s A1 -B 0 -L 0 -R 0 -T 0 –redirect-delay 3000 “” googlescreengrab.pdf && convert googlescreengrab.pdf -trim -gravity southeast -background none -splice 50×150 googlescreengrab.png

So in short. Run PhantomJS if you can.
If not, this will make your client happy.
And make you feel dirty.




Slack integrations so far; deploys, doorbells, reddit and lunch menus

On Earth People, we recently fell in love with Slack (Oh yes that’s an affiliate link that will give us both 100 dollar credit). It got us off Skype (which we didn’t really love anyway) and on to something that felt fresh. What really got us hooked was all the integrations we could do. Here’s a couple we’ve done so far:

1. When the doorbell rings, an Arduino triggers a HTTP request to some shitty PHP script we’ve written, which checks GoogleCal for meetings and pings the chatroom with what’s at the door.

Hey open the door, says Slack

2. Lunch is obviously a big thing for us hoomans. We’ve made a little Curl based bot which checks what the nearby restaurants serve for lunch by typing /zum or /stadsmissionen.

Slackbot responds to /stadsmissionen

3. Whenever someone deploys to a production server, Slack will let everyone know.

Slackbot lets everyone know when we have a deploy to production

4. /reddit <any word> will try to fetch an image from a corresponding subreddit. And post it to everyone… yeah, we’ll see how long this one gets to live. Depends on when someone starts fetching NSFW stuff I guess…

Screen Shot 2014-03-20 at 21.35.36

Right now we’re working on a crappy little Raspberry-integration for our Moccamaster. Wouldn’t it just be great to be able to ask Slack if there’s any coffee…

Relaying push notifications to your own API

We recently made a campaign for Loka mineral water, where users together reveal the new flavors. This is done by using Snapchat. We send users snaps containing puzzle pieces, and when they make a screen grab of a specific piece – we put that piece in the puzzle on the website.

Because of legal reasons we aren’t allowed to use the Snapchat API, but we still need to have some automation. For example we wanted to know immediately when a user made a screen grab of our puzzle piece snap, so we got around the problem by building an Android application.

In the latest Android SDK 4.4 (API 19) the “NotificationListenerService” was released. Using it, we can listen for incoming push notifications on our Nexus tablet. In the app, we’re just checking if the package name from the StatusBarNotification equals “” and if the notification ID matches the ID you get when someone is screenshoting your snap.

Then we post the username to our API, and cancel the notification from the NotificationListenerService.

code example:

   public void onNotificationPosted(StatusBarNotification statusBarNotif) {

       Notification notif = statusBarNotif.getNotification();

       if (notif != null){

           Bundle extras = notif.extras;
           Intent intent = new Intent(MainActivity.INTENT_NOTIFICATION);

           Bundle intentExtras = intent.getExtras();
           String notifTitle = intentExtras.getString(Notification.EXTRA_TITLE);
           CharSequence notifText = intentExtras.getCharSequence(Notification.EXTRA_TEXT);

           int notificationId = statusBarNotif.getId();

           //Check if the notification is from snapchat, and the id matches the printscreen id from notification.
               if(notificationId == printScreenId){
                   //Split the String to get the username. 
                   String arr[] = notifText.toString().split(" ", 2);
                   String userName = arr[0];
                   //Send to api.
                   //Cancel all notifications.
               Log.i("Other", "Another type of notification.");


Making car sound with web audio synthesis

We’ve fooled around with web audio synthesizers before, but never in a situation where mp3s would not also do the job. But in our recent Red Bull Racing game it really made sense to use a synth. The throttling sound is of course what it’s about. You want the speed of the car to control the pitch of the sound, so a generated sound is the way to go.

The amazingly realistic car sound is made out of 7 oscillators, three of them making sound (square, triangle and noise), and three of them acting as low frequency oscillators, modulating stuff. The last one is doing frequency modulation on oscillator 1. All this goes through four different filters plus pan and delay.

Frequency modulation can be described as changing the pitch of a sound back and forth so fast that the movement itself starts to make sound. When throttling the car affects both the pitch of the audible oscillator and the one doing the frequency modulation it starts to sound a bit interesting.

Try some FM in this jsfiddle:
You first hear the clean sinus wave, and as you turn up FM the character of the sound changes. Turn the frequency of the LFO all the way down to get a glimse of what’s going on.

Frequency modulation is the synthesis method of the famous 80s Yamaha DX7 synth, which had 6 of these oscillators or operators modulating each other.

Our next project gotta be to reproduce the DX7 in the browser.

The game (use your phone):

Chrome extension based campaign

Last year, our friends at TBWA\ asked us to create a Chrome extension for their client Adressändring. Adressändring’s services are normally used to forward mail when moving to a new place, and now they wanted to reach a younger demographic. This Chrome extension forwards a user’s social life by taking over banner space, much like Adblock. Instead of removing the banners, as Adblock does, it swaps them for feeds from Facebook, Twitter and Instagram.

Technically this meant alot of black magic and unconventional methods. Serverside we didn’t want to make lookups in a database, or fetch data from an API, for every banner rendered. If a user enters, we have to render at least 15 content areas from our servers, so these servers need to serve only static content to keep up with even a small load.

We decided to store all data in static json files on the server, serving them via Nginx. When the user installs the extension, we make a request to the server to create a new user (= a new json-file). As a response to the request, the server returns the identifier and stores it in localStorage. Access tokens from the various social media sites are then stored in this file.

When a user browses the web, the extensions makes a timed request to update the users feeds (= json files). This way the user will always get semi fresh social feeds from the server, and can request static files from Nginx. We had to set up both http and https so the security zones wouldn’t get mixed.

Two things we wish we would have had time to do:
- offload all json files to S3.
- instead of having the extension tell the server when to update a users feeds, we first planned on tailing the Nginx access log with a go or python script. Then we would have grep’d the user identifier, and depending on server load the script would decide if a user’s feeds should be updated or not.

The Chrome extension itself may get a separate blog post eventually. This got way too long anyway.
Oh, feel free to try out the extension!

Asynchronous game in real time

We made a game, a mobile racing game for Red Bull. Sort of in the trails of Chrome Racer, but even more fun we think. We used some cool stuff that we’ve written about here before – html5 audio, multiplayer gaming with websockets and node.js, but also stuff that was new to us, the vector scripting library paper.js, canvas animation and angular.js.

The first mindboggle was the question of where the race actually is taking place. The game is multiplayer and also a competition, so we needed to make sure the race synced well across multiple devices, but also that the game was correct in deciding who’s winning and what time you get. We started out with presuming that the game had to take place in real time on the server, and the server could push your car or hold it back when you got out of sync with the server, or crash it when you took a curve too fast, but in bad conditions with network latency the racing got twitchy. So the gaming experience hurt – no good.

Blue car is weirding out.

It was best to leave your car be. If your opponents get jittery on bad reception it’s ok, as long as your own car moves smoothly. So if the client is controlling the race, how do we know it’s not spoofing a killer race time? The conclusion was that the race must take place both in your browser and on the server, and the server rules when it comes to the actual result.

If the server doesn’t interfere with your driving it doesn’t have to work in real time either. There’s no clock running on the server so to speak. The server sets a start time, you tell the server when you’re throttling and when you’re not (or actually when you did throttle, due to latency we work with past tense data – the player throttled 0.2 seconds ago), and the server calculates the race, and where it thinks you should have crashed. Does nothing with this data, just quietly executes the race in an asynchronous manner. Since it just waits for events to come in it doesn’t really know or care where you are at this exact moment, not even at the finish line. Your race time is calculated when the server simulates your final run towards goal and sees that this gal was over the finish line at 16.34.

The server basically take your actions and recreates your race on the server piece by piece, while simultaneously sending out the same data to your opponents, and finally sets your race time with no consideration of the time you said you finished at. Latency matters at race start, if you’re on a bad connection you get a late start, but at the end and during the race it doesn’t matter at all. Your opponents will just look like drunk chinchillas on the race track.

Play the game on your phone:

SXSW lineup helper

We’re going to Austin again in March, for SXSW. It’s beyond great when it comes to live music. And tacos. But their official schedule is impossible to use due to the shear amount of gigs.

Two years ago we created a little tool for ourselves and our friends called LASTSX.WS which mashed the lineup with their account. This got shut down by the SXSW lawyers due to brand infringement in the URL. So when setting it up this year we removed any references to SXSW in the URL.

The end product is far from perfect, but it was a quick hack and it works on our machines™. Enjoy!

(Ok this is a tech blog so here’s what we used: PHP5.5, Nginx, Memcached, Curl.)