My family uses Slack. It’s pretty interesting.

Everything changed for the better when we started using slack at work. We’ve made countless custom integrations; doorbells, intercoms, travel cards, reddit, lunch menues, git hooks, server monitoring, you name it – we haz it.

My family has been using Google Calendar for a few years. Me and my wife used to think that we we’re busy every night and that there was no room for improvisation. Google Calendar showed us that we had lots of free evenings and weekends, which has been great.

When it was time to evaluate a group chat app, I saw no reason to use HipChat, Skype or anything like that. Slack to the rescue!

Slack’s free tier gives us 10 integrations, search for the latest 10 000 messages and 5GB storage. This is plenty for a family of 4. In this blog post I’ll go through how we use it and the integrations we have made to aid us.

Screen Shot 2016-02-01 at 15.15.44

We use channels just the same way we use them at work. “fixahuset” is a channel for stuff that needs to be fixed around the house, “general” is important stuff, “handla” is for picking up milk on the way home, “mathem” is an integration i’ll get to in a bit, and “random” is the usual cat gif mayhem we’ve all learned to love/hate. “pedertest” is where i test new integrations.

Integration no 1: Where are the kids?

We, as most parents to 10yo kids, ask this question daily. Picking them up at school, but they’re at a friend’s house, etc. Gah. This is a custom Slackbot command, which calls out to my server and returns the result.

My server runs a little curl script that calls out to Find My iPhone and returns a static GoogleMap image. The kids will probably start to question this thingie eventually, but works for now.

whereis

Integration no 2: Google Calendar

Our old Google Calendar integrates very smoothly, just hook it up and let Slack know when you want the notifications.

Screen Shot 2016-02-01 at 15.27.16

Integration no 3: School information

It turns out our school is living in the future, providing a RSS-feed per child. I had no idea. RSS works very well with this setup.

Screen Shot 2016-02-01 at 15.32.12

Integration no 4: Online food shopping

In Sweden, MatHem is one of the biggest e-commerce sites for groceries. We use them for a weekly delivery, and it works great. The night before delivery we generally take 10 minutes and cram everything we can come up with into our cart, which means that we miss a lot of essentials. What if we could add uhm… juice to our cart throughout the week, the moment when someone realise that we’re out of uhm… juice (“sök” means search, “köp” means buy).

mathem-animation

This integration is not kosher at all, and I’m probably breaking some terms and conditions. But we need this, and it could be done, so hey. If you work at MatHem or is offended by this in any way – please let me know and I’ll cease and desist.

That’s all the stuff we’ve got now, but more to come. Applying tactics from work to family life may seem cold, but I see this as a way to make the most out of our time. It’s not like we’re writing Jira stories or planning our vacation in Trello. Yet.

UPDATE

Lots of people wrote and talked about this, like Qz.com, ForbesNyTeknik (Swedish) and Apparat (Russian). And on Twitter (1) (2) (3) (4), Hackernews and Fatherly.com. CBC Spark also made an interview, which was great fun.

How to make a wind chime door bell

Our doorbell was already connected to the Internet via an Arduino, but we couldn’t stand the sound it made. We needed a warmer sound, a sound that didn’t make us want to kill the doorbell users (mostly clients).

Step 1:
Buy an old Wind Chime, preferably with a coconut base (because awesome).
2015-01-22 14.34.26

Step 2:
Pick up a few Littlebit modules (Cloudbit, servo motor and power supply).
2015-01-22 15.41.33

Step 3:
Drill, glue and duct tape a bambu stick to the servo motor. Hide all the crap in a classy box.
download_20150122_143926

Step 4:
Make the old Slack door bell script also make a little curl post to the Cloudbit.

<?php
$data = array(
	"percent" => "100",
	"duration_ms" => "10000"
);
$url_send = "https://api-http.littlebitscloud.cc/devices/XXX/output";
$str_data = http_build_query($data);
$ch = curl_init($url_send);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer XXX','Accept: application/vnd.littlebits.v2+json'));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $str_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
echo curl_exec($ch);
curl_close($ch);

Step 5:
Ring the door bell. Voila!
doorbell

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.

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 “com.snapchat.android” 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:

@Override
   public void onNotificationPosted(StatusBarNotification statusBarNotif) {

       Notification notif = statusBarNotif.getNotification();

       if (notif != null){

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

           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(statusBarNotif.getPackageName().equals(snapchatPackageName)){
               if(notificationId == printScreenId){
                  
                   //Split the String to get the username. 
                   String arr[] = notifText.toString().split(" ", 2);
                   String userName = arr[0];
                   
                   //Send to api.
                   runHttpPost(userName);
                  
                   //Cancel all notifications.
                   NLService.this.cancelAllNotifications();
               }
           }
           else{
               Log.i("Other", "Another type of notification.");
           }

       }
   }

automated screendump creation

i recently had to create jpg thumbs of the first frame from a bunch of videos. doing this manually is not really an option if you have 100 files or more, so commandline to the rescue. i had an ubuntu box, on which i installed ffmpeg:

sudo apt-get install ffmpeg

then cd into the directory containing your video files and run this oneliner:

ls | xargs -i ffmpeg -i {} -vcodec mjpeg -vframes 1 -an -f rawvideo -s 114x64 {}.jpg

in the same directory, i now have a jpg screendump of each video file.
ffmpeg can decode a bunch of formats, should you need support for some other weird format you may need to compile your own version of ffmpeg. good luck!

html5 validation with(!) facebook opengraph

html5 is that new, cool(?) technology which you should(?) be using when making new sites. but, being the thorough developer you are – it just eats you up from the inside when your brand new html5 website won’t validate because your client decided to add a facebook like button.

the facebook open graph protocol/namespace/api/whatever which was released in spring 2010 will only validate with an xhtml doctype. if you want to work in a html5 doctype and use opengraph, you need to apply a little bit of server logic. have a look at this, i won’t bother explaining the source code, i think you’ll get it.

<?php
function is_facebook(){
if(!(stristr($_SERVER[“HTTP_USER_AGENT”],’facebook’) === FALSE))
return true;
}
}
?><!DOCTYPE html>
<html dir=”ltr” lang=”en-US”<?php if(is_facebook()){echo ‘ xmlns:fb=”http://www.facebook.com/2008/fbml” xmlns:og=”http://opengraphprotocol.org/schema/”‘;}?>>
<head>
<title><?php bloginfo(‘name’); ?></title>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />

<?php if(is_facebook()){?>
<meta property=”og:title” content=”<?php echo $title;?>”/>
<meta property=”og:description” content=”<?php echo $description;?>”/>
<meta property=”og:type” content=”article”/>
<meta property=”og:image” content=”<?=$path_to_page_thumbnail?>”/>
<meta property=”og:url” content=”http://<?php echo $_SERVER[“HTTP_HOST”].$_SERVER[“REQUEST_URI”];?>”/>
<meta property=”og:site_name” content=”<?=$the_name_of_the_site?>”/>
<meta property=”fb:appid” content=”<?=$your_fb_app_id?>”/>
<?php }?>

one thing to have in mind is that page level caching is a no go if you apply this tactic. if your cache is clever, you could possibly make an exception for the facebook user agent, delivering fresh content to facebook on all requests.

oh well, it’s just a thought. let me know if i missed something.

Getting stats from the Facebook Like button your way

So you’ve implemented the Facebook Like button, and you’d like to know – programmatically – what your users Like on your site. This is a bit of a pain, since there’s nothing in the Facebook Open Graph for this. There’s some stuff in the insights api, but it’s not really usable if you’d like to do anything fun with your data.

I’ve written a PHP class which you can download and use anyway you see fit. It’s kind of simple, but will get the job done. You probably want to add some caching to it, since the old REST-api we’re querying isn’t very responsive.

Use it like this:

# create new instance of like class
$FbLikes = new FbLikes();

# add all the urls you want to measure
$FbLikes->addUrl('http://earthpeople.se/labs/');
$FbLikes->addUrl('http://wplove.se/kom-pa-wpbar/');
$FbLikes->addUrl('http://debaser.se/');

# set the sort order, either 'likes' or 'untouched'
$FbLikes->order_by = 'likes';

# get all the fb like data
$likes = $FbLikes->getLikes();

# echo the results
if($likes){
  foreach($likes as $row){
    echo $row->normalized_url . ': ' . $row->like_count . " facebook likesn";
  }
}

Enjoy – or fork!

php class for ffmpeg

i’ve had a few projects over the last years where i’ve needed to convert some video file to flv, generate a thumbnail and get the video’s duration. i’ve never really got around to wrapping this into something reusable. but here it is, get it if you need it.

you’ll also need a non-windows server with ffmpeg installed, and if you need compability with any non-standard formats (3gp/mp3/etc) you need to install these as well. i won”t go into detail about how this is done, just google it.

when ffmpeg is correctly installed on your box, use this class like this:

$encoder = new videoencoder();
$thumbnail = $encoder->export_thumb("yourfile.mp4");
$duration = $encoder->get_duration("yourfile.mp4");
$videofile = $encoder->export_video("yourfile.mp4");

ok i know it’s better to use a service for this, like the excellent encoding.com – but hey, this is more fun – and really fast! also, worth noting is that while ffmpeg happily converts your files to flv, it will use the old “spark” codec for flash videos, instead of the newer and slightly better codec “on2” due to licensing issues. you can however use mp4 files with recent versions of flash player, which ffmpeg can convert to. use mp4 instead if you worry about video quality (which i guess you should…).

download my php class here.

search for artist from iTunes

So, say you got this one great track in iTunes, and you want to look for more music from the same artist. Here’s a simple little script that can ease things up a bit.

Download it

This script makes a Amazon search in Firefox for the artist, but as you’re guessing you can make it go to what-ever site you like and search for content. Open the script and replace the url with a new url and save. You can also make it use Safari instead of Firefox.

To install it, place it in your home folder/Library/iTunes/Scripts
If that folder doesn’t exist – make a new one and call it Scripts.
Quit iTunes, restart and an applescript icon should appear in the iTunes menu bar, with your script ready to be clicked on.