Integrating Toggl Track with Tape for Project Time tracking

A little warning this is quite long! It is a more in-depth write-up based on a blog post and also a Video demonstration - which you can check out here if easier:

This came about as the question was asked if a Time Recording system could be built into Tape so that an organisation already using Tape for Project Management could track time spent against projects. However following further investigation this was unsurprisingly a bit of an XY Problem.
The organisation didnā€™t need to track time in Tape they needed to include time information with the rest of their Project data.

In a world with numerous time-tracking tools, we chose Toggl for several reasons including: Togglā€™s API is robust, Togglā€™s clients are cross-platform and continually improving, and excellent third-party tools like Timery enhance the experience.

Through this showcase, I will demonstrate a few key functionalities:

  1. Create a Client in Toggl from Tape
  2. Create a Project in Toggl from Tape and Link it to the Client
  3. Create a Time Record from Tape
  4. Display Time Records from Other Toggl Clients in Tape, Linked to the Relevant Project
  5. Show Project Time on the Tape Project Record
  6. Show Time Spent on All Related Projects on the Tape Client Record
  7. Automate Weekly PDF Reports

In working through these seven items it will also demonstrate a few nice aspects of Tape which are fully transferable to other projects. I will try and highlight key calculations, scripts and automations and use code blocks were possible but please do reach out if there are areas I have missed or are not clear.

The workspace

To demonstrate this integration, we use a workspace with three applications: Clients, Projects, and Time Records. In a real environment, additional elements like Contacts, Meetings, Tasks, and Milestones would likely be present. Some manual processes might be automated in a live scenario, such as triggering Toggl project creation when a project hits a certain stage in its life cycle.

Creating a client in Toggl

This is a relatively simple stage it requires one automation-triggered at the time and method of choosing and all you need to send to Toggl is the client name and the Toggl Workspace ID that it needs to go into. We get back a Toggl client ID which we need and store it in a hidden field within the client record.
Once we have the ID back we post a comment on the record and trigger a flag that the Client is in Toggl.

Create a Project in Toggl from Tape

This is slightly more complex than client creation but follows the same principle. Having a client associated with the project is essential so when the ā€˜create Toggl projectā€™ automation is triggered the first thing it does is check for a related client record if there isnā€™t one it posts a warning comment and stops the automation.

If there is an associated client then it sends the request to Toggl for a project creation the request includes four pieces of information:

  1. The project name
  2. The Client Toggl reference (must be a number)
  3. The project status ā€˜activeā€™
  4. The colour to be used for the project (this is optional)

One thing that is worth mentioning about this is that as the client Toggl reference must be a number to work we do a little calculation to make sure it is:

parseInt(collected_client_field_toggle_ref_decimal_value, 10)

When all this is sent to Toggl a new project will be created in Toggl and linked to the client. Toggl will then send back some information there is one part of this response that we are interested in and that is the ā€˜project IDā€™ so we run a quick check on the response to make sure it is there:

jsonata('id').evaluate(var_http_response) > 0

A comment is then posted either with a success message or a failure warning.

Create a time record from Tape

Up to now, things have been fairly simple but the fun begins. We need to build a request to send to Toggl and this needs to have:

  1. created with - Toggl likes to have a method of creation for each time record so we just say ā€˜Tapeā€™
  2. description - you need a description for the time record so for ones created directly from the project we just use ā€˜General work on [Project Name]ā€™ if you were recording from a task then this could be the task name.
  3. project_id - this is the number we got from the response when we created the project.
  4. start - we need a start date and time for the recording needs to be formatted in a certain way:
date_fns.format(date_fns_tz.zonedTimeToUtc(new Date(), 'UTC'), 'yyyy-MM-dd\'T\'HH:mm:ssXXX', { timeZone: 'UTC' })
  1. workspace_id - we have been using this all along but only in the URL this time we have to add it to the request
  2. duration - We have to give the time recording a duration as we are making an ongoing record we set it to -1 this tells Toggl that the record started at the start date but is still ongoing.

When we send all this information to Toggl it will start a timer running and send back a lot of information in its response we are only interested in one thing though and that is that a valid ID has been returned and we only want this as a check for success if it is not there we post a warning message in comments if it is we post a comment saying that a timer has been started and who by.

Have time records created from other Toggl clients appear in Tape against the relevant project

The follow-up step from starting a time record from within Tape is actually the same as when a time record is started from outside of Tape using any of the many available tools, this is one of the advantages of using Toggl they have multi-platform apps of there own including iOS in addition to a Web app. Certainly, a few years ago the Toggl Mac app and iOS apps were fairly poor but Toggl have done a lot of work on them now and are way better.
The other option is to use a third-party app that ties into Toggl the best one that I know of is Timery for Toggl this is an excellent iOS and MacOS app that looks good and has great Apple Shortcuts integration bringing in more options for automating time recording.

When a time record is created (or modified) in Toggl through whatever method it can send out the details via a webhook, we use it to assign time against a project/determine if there is a running timer, etc.

When this information comes in from Toggl we run a couple of checks:

  1. Is the time record associated with a valid Tape project (Time records can be created in Toggl without any project associated.)
  2. Is there already a time record in Tape - In other words is this an update to a preexisting record or a new one.

This information will be used later in the flow along with the start and stop time which we grab from the payload now to use later.

The final thing we need to check before we start performing actions is if itā€™s a running timer, we do this by checking if the duration is a negative number if it is then the timer is running if it is a positive number then the timer is stopped.

If it is a negative number then we update the project record (if it exists) by setting a hidden field to 1 this then triggers a calculation on the project record and displays a banner:


The calculation for this is:

const r = @running ;
let d = "";
if (r === 1) {
d = `<p style="background-color:#D97F30;color:#EFEFEF;text-align:center; padding:20px; margin:0;border-radius: 30px;font-size:160%;">
<strong>Time Recording Active</strong>
</p>`;}
d;

Once we have that out of the way we need to either update a time record or create one so do a quick search for a time record with the relevant ID and create or update accordingly most likely as the timer is running it will be a new record. At this time we link the Time record to the related Project and Client. If the duration is not a negative we set that special field in the Project record to 0 which removes the notification and we generate or update the Time record with the information coming in from Toggl the same as we did previously.

Have Recorded Project time displayed on the Tape record.

To do this we want to trigger an automation on the relevant Project record there are a few ways to do this but in this instance, we do it when the time record is updated finding the related project (if there is one) and updating a field this will trigger an ā€˜on changeā€™ automation.

I think there are possibly more elegant ways of doing this but it is how we built it and it works.

Now we have triggered the automation on our Project record and the first thing it does is find the related Client as we are going to update both the Project and Client Record in this automation.
Following this we need to find all the Time Lines that relate to the project which we can do via ā€˜get related itemsā€™:

We need the Total Project time and this is what all these records will give us so we ā€˜roll upā€™ and sum the durations.

Next, we want the time spent this week so we need the date for the first day of this week:

date_fns.startOfWeek(new Date())

This next step could be done in principle by filtering the already collected Time records however for the demo we opted to clear the previous collection and create a new one filtering the ā€˜get relatedā€™ in one go:

We sum up the durations on those records and this gives us the time spent this week, the problem is that the durations are in seconds and that doesnā€™t help anyone, we want them in hours so we run through a script giving us the duration in decimal hours.

function secondsToDecimalHours(seconds) {
    return seconds / 3600;
}

var_totalhours = secondsToDecimalHours(var_total_time);
var_totalweek = secondsToDecimalHours(var_this_week);

This gives us all we need for the Project record so we update the record by putting our hours into the relevant number fields which are hidden fields, however, we have a calculation field that references those hidden fields and pulls the information from them this means we can format the information how we want and also it takes less screen space:

instead of:

melotte.consulting 2023-12-05 at 13.39.04@2x

For the client time, we follow the same process however we search for any time records with the related client and then do a total and a monthly total and drop those into the relevant fields on the client record.

So this covers off 5 and 6 on our criteria list with just the pdf report left however before we move on to that a little extra is that we have also included the total time on our project title:

melotte.consulting 2023-12-07 at 16.31.56

This makes it handy to see all the important information about the project at a glance and it is done in a calculation field:

`${ļ»æ@Project Statusļ»æ.split(" ")[0]} ${ļ»æ@Nameļ»æ} - ${ļ»æ@Total Project Hoursļ»æ}`

Have a time spent report created automatically at set intervals (weekly)

Every Monday morning, an automation runs to collect data on active projects from the previous week and generates PDF reports using Tapeā€™s ā€˜Create PDFā€™ function.

The automation finally adds the report to the Project record, in a non-demo situation I would be tempted to store the PDF in a document store depending on how documents were managed and also attach it to an email and send it to the project owner.

And thatā€™s the end we have covered all of our list. Hopefully, you can see how this integration showcases the best of both worlds, combining the specialist capabilities of Toggl with Tapeā€™s versatility.

9 Likes

Very, very, very big WOW @Jason! :100: :rocket:

This is a real masterpiece! Simply awesome from the idea to the integration in Tape and the great presentation with the detailed explanations!
1000 thanks for this outstanding showcase. Time tracking is a huge thing and this will help and inspire many users!

Thanks again for the energy and effort you have put into making this brilliant showcase available to the whole community

Cheers
Leo

1 Like

Another maginficent use case and guide - respect @Jason, this looks like a lot of work. :pray:

Really much appreciate you sharing it here - I am certain this will be useful for others. :100:

1 Like