We're going to Medium!

Publicado el 23/11/2016 por Engineering Outreach Committee

We thought why not?... So off we went. From now on, you can follow the adventures of everyone at Tuenti in the development, product and design teams at our brand new Medium profile @tuentimakers.

Of course, we'll keep the entire history of this blog so you can check out what we've written about Activity detector, the Tuenti app for Apple Watch or the write-ups of the Tuenti Challenge 6 whenever you like.

See you on Medium! <3

Activity detector

Publicado el 19/10/2016 por by Abel Toledano, Senior Software Engineer

Sometimes, when you want to do some action in your page using JavaScript it’s very convenient to know whether the user is actually paying attention to your page at that moment, because, as you probably know, the JS in your page can be executing even when it is in background. For example, the user can be reading a different browser tab, or even using a different application and the browser doesn’t have the focus.

In Tuenti we have had to deal with this kind of problems in different situations. One clear example is the Tuenti chat: we want to notify the user about new messages playing a notification sound, but we don’t want to play it when the user is already paying attention to the conversation, we only want to play the notification sound when the page is in background to take the user’s attention.

To achieve this we listen to different browser events to determine whether the user is actually using Tuenti at that moment or not. These are some of the events we listen to:

focus and blur events in window:

When a user enters to your page, the browser fires a focus event in the window object. In the same way, when the user changes to a different tab or application, the browser fires a blur event.

Taking this into account, it’s pretty simple to determine whether the user is in your tab:

var inTab = true;

window.addEventListener('focus', function () {
  inTab = true;

window.addEventListener('blur', function () {
  inTab = false;

Pretty simple, isn’t it?

Well… it depends on what you really need. With this simple code you can know whether the user is in your tab, but what happens if the user is in your tab but he has left the computer and is in the bathroom?

So we don’t only need to know if the user is in our tab but also if he is using it. To solve this problem we could connect the laptop webcam and spy the user, but probably our users wouldn’t like that. So we can use a simpler (and more privacy respectful) solution:

Mouse and keyboard events

We can listen to DOM user interaction events to know if the user is actually using the page, and when we have not heard any event for a given time span (for example 30 seconds) we can assume the user is not active. Some events we can listen to are: click, mousemove, keydown, etc (for desktop devices), or touchstart, touchmove, etc. (for mobile devices).

So we can attach some event listeners to the document and toggle the inTab variable in the previous example to true. But, when we change it to false? when it has elapsed 30 seconds since the last event. This behavior can be implemented with a setTimeout, but we also need to reset that timeout (with a clearTimeout) when we hear a new event.

We can express this solution with a simple state machine:

state machine

Ok, beautiful, let’s implement it. You don’t need to do it! because we have already done it and opensourced a library that you can use: activity-detector:

How to use

First, install it.

We distribute the lib in npm, so you can install it with a simple command:

$ npm install --save activity-detector

Let’s see a basic example

// 1. import the lib:
import createActivityDetector from 'activity-detector';

// 2. create an activity-detector instance:
const activityDetector = createActivityDetector();

// 3. subscribe to events
activityDetector.on('idle', () => {
  console.log('The user is not interacting with the page');

activityDetector.on('active', () => {
  console.log('The user is using the page');

How this work? the library implements the algorithm we have presented in the previous state machine diagram. When you create an instance of activity-detector you can subscribe to the events active and idle. Those events will be triggered when the user becomes ACTIVE or INACTIVE respectively.

And that’s all. Now you can detect when your user is using your page or not.

Ok, but I don’t use npm neither ES6. Can I use activity-detector lib?

Of course, we have a production ready build (UMD format) that you can simply include in your page with a simple <script> tag, or require it with any module loader (like require.js). You can find it here.

For example:

    test activity detector

Advanced options

activity-detector supports different config options to customize its behavior if you have different needs. For example you can decide which user events should be considered, or defer the activity-detector initialization. For example:

const activityDetector = createActivityDetector({
    timeToIdle: 10000, // wait 10s of inactivity to consider the user is idle

You can see the different options reading the docs in the github repo:


If you like it and think it’s useful don’t forget to star it. And if you miss some feature or find a bug please open an issue or, even better, send us a pull request!

HMU30: Innovation in Personal Communications

Publicado el 14/10/2016 por Outreach Committee

For another quarter, we come to the end of our most creative 32 non-stop hours with the thirtieth edition of our Hack Me Up. This time the Product track topic was Innovation in Personal Communications,

As usual, these 32 hours gave complete freedom to its participants to create work groups with colleagues in other areas or teams and develop their own product ideas, apart from their daily jobs.

In this edition there were several projects registered, amongst which there were ideas on voice calls or chat. And the winners of HMU30 were the following:

  • Peek and see was the winning project in the Product category. César, Alejandro, Pablo and Jose made a project using the iOS SDK that transcripts recorded calls as a chat conversation.
  • Aarón, Edu and José Antonio raised the Geek cup thanks to their Foostastic, a project like a comunio but for the internal Tuenti league.

Despite there being only two winning projects, many of those presented were of excellent technical quality and may be implemented at Tuenti for the use of our clients and users. We’ll keep you posted!

Congratulations to the winning teams!

HMU29: and the winners are…

Publicado el 17/6/2016 por Outreach Committee

Another quarter, another Hack Me Up. The 29th edition of our internal programming competition has just finished at the Tuenti office in Madrid. Bots from the sofa was the theme of this edition, which is why projects were focussed on bot technology.

With 13 projects presents, these are the final results:

  • Super Call Saving Player, the winning project in the Product category. Jessica, Manolo and Rayco made a new awesome player for the call saving functionality.
  • Tuenti Core was the project that took home the Geek Cup. Sergio made a multiplatform development in C# to show the posibilites of the .net framework. Very geek, indeed.

Despite there being only two winning projects, many of those presented were of excellent technical quality and may be implemented at Tuenti for the use of our clients and users. We’ll keep you informed ;)

Congratulations to the winning teams!

#TuentiChallenge5, the grand finale

Publicado el 29/5/2015 por Luis Peralta, CTO

All good things must come to an end. The final phase of this edition of our programming contest has finalized today at our Madrid office far exceeding our expectations. But it couldn’t be any other way, considering that this was the most difficult of the five so far.

The 10 Tuenti Challenge 5 finalists came in yesterday to meet the team, so we received them by celebrating with a barbecue at our CTO’s home, as is the Tuenti style.

In spite of not having finished the 20 problems that we initially posed in the first phase, they are the top 10 challengers, those that have solved the largest number of problems and with better code quality. As expected, we were impressed by the technical quality of the workshops and interviews we shared with them all throughout the day. The formative workshops were:

  • Delta, by Luis Peralta, CTO.
  • Building a VoIP Service using mobile WebRTC, by Pedro Álvarez, Lead Software Engineer.
  • Tuenti Architecture, by Jesús Bravo, Lead Software Engineer.
  • RM Cycle in Tuenti, by Jose Plana, Senior SRE Engineer.

As a finishing touch to this meeting with our finalists, they received different prizes. And as of just a few minutes ago, we have announced the final ranking. The podium is taken by:

  • Albert M.
  • Josep R.
  • José C.

The following are the rest of the participants who also reached this second phase:

  • Iván M.
  • Oriol C.
  • David A.
  • Enrique J.
  • Angel P.
  • Sonia M.
  • Carlos B.

Tuenti Challenge 2015 Finalists

We have been left speechless. This edition has been enormous and we are extremely grateful to the more than 2,300 registered participants, the almost 900 participants that solved at least one problem, the top 50, the top 10, and the champions for having made all of this possible. Thank you very much from everybody on the Tuenti engineering team! And to all of those who didn’t make it to our office today, we hope to see you next year. See you at the #TuentiChallenge6, mates!