Set the custom Focusing status in Microsoft Teams from PowerShell using Power Automate

I am a Pomodoro Technique enthusiast. During a Pomodoro sprint it is important to mute distractions. This worked fine with custom presence states in Skype for Business, which is one of my most popular blog posts to date, on a daily basis. With Microsoft Teams, this has been a challenge, until now.

The Focusing custom Teams status can only be set by MyAnalytics via a calendar event called ‘Focus time‘. I have not been able to recreate this calendar event type manually, so it must be something in the header. During a ‘Focus time calendar event, the Teams client sets the status to Do Not Disturb with a custom name called Focusing.

Here is how to get started with Focusing custom Teams status

You can schedule such a calendar event at will using PowerShell and PowerAutomate

Personally, I prefer to manually control when my Teams client gets set to Focusing state. MyAnalytics schedules the calendar event as two hours long when calendar is open and weeks in advance. I needed a way to set this status at the time I am of my choosing when I was actually focusing, to mute distractions and tell my peers that I am in a focus, deep work, flow Pomodoro sprint. I found a way to use Power Automate to control set the Focusing status at will.

The Teams Focusing status fits well with the PowerShell Pomodoro Timer. Update 05.10.20: the status updates instantly after the calendar event is added to your Outlook

Watch the 3 first minutes showing the focusing status in action!

How I solved it

I trigger a Power Automate flow using a HTTP request trigger using Invoke-WebRequest in PowerShell. The flow takes two inputs, duration and a secret. If the secret is correct, to make sure the flow can’t be easily hacked, it gets my calendar and searches for calendar event with subject ‘Focus time’. It takes the first entry and changes start time and stop time for the event using the duration I have set, usually 25 minutes. Now I have a ‘Focus time’ calendar event that is set at the same time as my Pomodoro sprint with the same duration. After 1-3 minutes, my status will be updated to Focusing. After 25 minutes, plus 1-3 minutes, my status will be reset. BOOM, how cool is that!?

Prerequisites

Update 05.10.20: I have created a free way to do this using Microsoft To Do task as a trigger. No need for code adjustment, just download and use it. Read more here! If you want to use premium Power Automate trigger and PowerShell to set the status keep on reading :)

Update 08.01.21: Together with MVPs Dux Raymond Sy and Loryan Strant, I have created a Pomodoro YouTube series where we discuss the Teams custom focusing status and multiple ways to solve this. Check it out!

  • Calendar must be in Exchange Online
  • You must have MyAnalytics as part of your license and enabled
    • Schedule 1 period with MyAnalytics to get the calendar event
    • Available in Enterprise SKU’s
  • You must have Power Automate license and ability to use Premium triggers
    • The trigger used is HTTP request and is a Premium trigger
    • You may find that you can use other free triggers as well
    • Premium triggers are included in Dynamics 365 SKU’s
    • Premium triggers are not included in Microsoft 365 SKU’s
    • The standalone $15 Per User plan can run Premium triggers
  • If you want to use a trigger included in your Office 365 plan, check out my other method, using Microsoft To Do task as trigger

Creating the calendar event and importing the Power Automate flow

  • Create the calendar event in MyAnalytics
  • Import the flow in your Power Automate
    • Watch the full walkthrough of the import of the flow at 3:39 in the YouTube video
    • Download the HTTPSTriggerUniversalPomodoroFocustime.zip file here
    • Navigate to your personal Power Automate dashboard at https://flow.microsoft.com/
    • Go to My flows in the left menu and click Import
    • Click Upload and choose the zip file
    • To be able to complete the import you must click the wrench in the first line and choose Create as new under Setup
    • Next you must create the Outlook connector by clicking on the wrench in the second line for Related resources
      • Click Create new
      • Scroll down to Office 365 Outlook, click Create and authenticate as your user
      • Now you have created the Outlook connector, go back to the flow import website and select you new connector and Save
      • Import the flow by clicking Import
      • The import should be successful, navigate to My flows
    • Edit your new flow called HTTPSTriggerUniversalPomodoroFocustime.
    • Now, let’s go through it and update the flow for your environment

Configuring the Power Automate flow

Click Edit on the flow and expand When a HTTP request is received and copy the HTTP POST URL and save it for later

Expand Condition and change MySecret to your own and take note of it

If no is there to trigger if the secret is wrong, it is a small security measure so that people not easily can steal you flow URL, but they also need the secret, or you can change it if it does get lost

That is the only change you need to make to the flow because the flow will find your default calendar. Since the name of your primary calendar may be different in your language, we are looking for the calendar for your user with isRemovable=False

But there is one more thing, we want to edit one of the calendar ‘Focus Time’ calendar events created by MyAnalytics. We want to set the event to workingElswhere or has priority of low. In this way we have more control over which event we are manipulating.

That’s it! You are now ready to invoke your flow. In PowerShell you need to run the following code

[int]$Minutes = 25 #Duration of your Pomodoro Session, default is 25 minutes
[string]$Secret = "MySecret" #Secret for the flow trigger
[string]$AutomateURI = "YourFlowTriggerURI" #The URI used in the webrequest to your flow


#Invoking PowerAutomate to change set current time on your Focus time calendar event, default length is 25 minutes
    $body = @()
    $body = @"
        { 
            "Duration":$Minutes,
            "Secret":"$Secret"
        }
"@
Invoke-RestMethod -Method Post -Body $Body -Uri $AutomateURI -ContentType "application/json"

Go back to Power Automate and validate that the flow ran, check your Outlook calendar that the ‘Focus time’ event was moved to now the status should change almost instantly. When the calendar time is over, your status will be reset and you are available again.

The practical approach with the Pomodoro PowerShell timer

With the ability to control the status in Teams, I believe the Pomodoro PowerShell timer is feature complete. One thing is to be unavailable and reduce distractions, but it is very important to automatically become available again. The reason for WHY you would use this kind of timer and automation is to avoid getting distracted which breaks your flow and deep work. Research shows that it takes between 7-30 minutes to get back in to flow after you have seen just one email or message. Here is what the script does

  • Starts presentation mode to block popups on your computer
  • Hides badges on taskbar so that you do not get distracted by seeing that you have a new mail, task or chat
  • Opens you favorite flow and deep work Spotify playlist so that you do not spend time figuring out what to listen to
  • Uses IFTTT to mute your phone, works with Android and iOS
  • Finally set your status in Teams to Focusing
  • After the Pomodoro sprint is over, everything will be turned back on again
  • Watch my demo (and live commentary) of the script in the YouTube video :)

Below is a sample code to run the Start-SimplePmodoro.ps1 script which you can download from GitHub

Start-SimplePomodoro `
-SpotifyPlayList spotify:playlist:XXXXXXXXXXXXXXXXXX `
-IFTTTMuteTrigger pomodoro_start `
-IFTTTUnMuteTrigger pomodoro_stop `
-IFTTTWebhookKey XXXXXXXXX `
-Secret YourFlowSecret  `
-AutomateURI YourAutomateURI `

Watch how to get started with the Pomodoro PowerShell script at 3:39 in the YouTube video

Why is it important to automatically become available?

You have been gone for 25 minutes, use the pause to check if anyone has been trying to reach you, re-prioritize your tasks, get more coffee and then dive in to a new Pomodoro sprint. After 25 minutes it is OK to get distracted, but if nothing happens, just stay in the flow you jump started and get stuff done. Download the Pomodoro PowerShell timer from GitHub

8 thoughts on “Set the custom Focusing status in Microsoft Teams from PowerShell using Power Automate

  1. Okay, so I’ve got this all set up and working, with just a couple of problems. I cannot get the spotify playlist to work. The URI that you give is not a web address, so I assume that language is opening the spotify Windows app? I installed the spotify Windows app, created a playlist, and then picked the option to share it to copy it’s URL. Of course, that process gave me a website link, and the syntax you use in the script is not for a website (nor does what pops up when your run the script in the video look like a website). So I copied the playlist number from the end of that URL, and then inserted it into your syntax:

    -SpotifyPlayList spotify:playlist:0S9Gn5eCWc4VBt3EEuEeCU?si=9c91253e9dbc46d5:play

    That failed with this error:

    -SpotifyPlayList : The term ‘-SpotifyPlayList’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

    Finally, the whole Badge thing was doing weird things. My whole screen would go blank, it would close any open Windows Explorer folders, and minimize windows. While I liked it minimizing windows, the other stuff was a bit bothersome. So, I just removed all of that language from the script. I think the only thing that controlled was the little numbers showing new messages on the task bar icons, right?

    And, BTW, thanks for this. I’ve been struggling to find a way to get this all to work without 5 manual steps to start and end each session, so this is amazing. I only wish that Power Automate routine ran faster, as I’m getting a full 3 minute delay, which is 12% of a standard pomo time.

    • Glad it worked out in the end, yes the badge removal process requires restarting explorer.exe to take effect, that is why you get that experience. Nothing I can do with the Power Automate delay though, at the status is on time when your Pomodoro ends. For Spotify, you need to copy the URI, not the URL👍

      • I was not getting either Spotify or the IFTTT to work (I replaced the Mute/Unmute IFTTT with an applet to turn on and off my Hue lights). I got an error at the end of each run saying the command was not valid or recognized.

        The whole trouble ended up being that I had hit Enter between the -ToDoURL and -SpotifyPlayList commands, which I did because it made the whole thing look a lot cleaner in the editor. Turns out that’s a big deal, and you have to put ONLY a space between those.

        So, I’ve got that fixed, it opens Spotify and turns on my Hue lamp. Only thing not working now is that adding :play to the end of my Spotify URI is NOT causing it to play automatically.

  2. To add to that, I discovered that holding Alt when right clicking on the playlist in the desktop app gives you the URI. So now I have the correct link, and I’ve plugged that into the script (with the word “:play” tacked onto the end as you did in the video):
    -SpotifyPlayList spotify:playlist:0S9Gn5eCWc4VBt3EEuEeCU:play
    Once again, Power Shell returns an error saying -SpotifyPlayList is not recognized as the name of a cmdlet, function, script file, or operable program. So, the problem isn’t with the link, it’s with that command that is calling the link.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.