teams-call
teams-call copied to clipboard
Support for New Teams
Its looks like that the Script not work with the new teams. I checked the logfile wich you like to parse but it is not updated by the new teams version. And i still not find that new teams in a logfile. Any Idea?
Hey, I can't test this at the moment, but I'd be curious if someone found a workaround. If so, we can add support.
Same, it doesn't work for me =(
Looks like it's not possible at the moment. See here.
I was able to hack something together with an applescript:
tell application "System Events"
repeat with TeamsWindow in (every window of process "MSTeams")
-- entire contents of TeamsWindow
-- Examples:
-- group "Elapsed time 02:55" of toolbar 1 of group 1 of group 1 of group 1 of group 1 of group 1 of UI element "Meeting compact view | Fooobar | Microsoft Teams" of group 2 of group 1 of group 1 of group "Meeting compact view | Fooobar | Microsoft Teams - Web content - Profile 2" of window "Meeting compact view | Fooobar | Microsoft Teams" of application process "MSTeams"
-- group "Elapsed time 03:31" of toolbar 1 of group 1 of group 1 of group 3 of group 1 of group 1 of group 1 of UI element "Foobar | Microsoft Teams" of group 2 of group 1 of group 1 of group "Foobar | Microsoft Teams - Web content - Profile 2" of window "Foobar | Microsoft Teams" of application process "MSTeams"
-- Best way I can find to determine a meeting it this nested group item which shows the elapsed time of the meeting
repeat with CurGroup in group of toolbar of group of group of group of group of group of group of UI element of group of UI element of group of group of TeamsWindow
if (name of CurGroup contains "Elapsed time") then
return true
end if
end repeat
end repeat
end tell
And run is osascript:
$ osascript get–teams-call.applescript
true
There's probably a better way to loop through these nested objects, but this works for now.
Oh, that's clever. Would you like to send a pull request? https://stackoverflow.com/a/65016330 Can be behind a check for macOS.
The group stuff would break if Teams changed their UI elements. Have you tried something like this?
tell application "System Events"
-- Check if MSTeams is running
if not (exists process "MSTeams") then
return false
end if
-- Simple approach: look for "Elapsed time" text in any Teams window
tell process "MSTeams"
try
-- Search for any UI element containing "Elapsed time" regardless of hierarchy
set elapsedTimeElements to (get UI elements whose name contains "Elapsed time")
if (count of elapsedTimeElements) > 0 then
return true
end if
end try
end tell
return false
end tell
@mre That doesn't work since the "Elapsed time" is the name of a group, not a UI element itself. I'm not sure if there's a way to get every nested group like this.
I was also able to detect whether I'm in a call based on the the number of Microsoft Teams UDP connections.
Very hacky but it seems to work for me on Microsoft Teams macOS Desktop App macOS Sequoia 15.3.2
@jessejoe, this works for me:
tell application "System Events"
-- Early exit if Teams isn't running
if not (exists process "MSTeams") then
return false
end if
with timeout of 3 seconds
tell process "MSTeams"
try
repeat with w in windows
set winName to name of w
if winName contains "Meeting" or winName contains "Call" then
-- Found a meeting window title
return true
end if
end repeat
on error
return false
end try
end tell
end timeout
return false
end tell
@mre that actually won't always work because a meeting can be named anything and may not have "Meeting" or "Call" in the title. Debugging your script:
tell application "System Events"
exists process "MSTeams"
--> true
count every window of process "MSTeams"
--> 2
get name of item 1 of every window of process "MSTeams"
--> "I named this Foobar | Microsoft Teams"
get name of item 2 of every window of process "MSTeams"
--> "Meet App | Microsoft Teams"
end tell
Result:
false
You're actually going through the same process I went through before I ended up on my first comment, haha. That will probably work most of the time though.
Okay, thanks. 😅 Then I'd accept a PR for your version. We could also port the script to a different language like Rust or Go tbh. A static binary makes the most sense here. But perhaps for now an addition to either the Python or Bash version in the is fine as well. Completely up to you.
I was also able to detect whether I'm in a call based on the the number of Microsoft Teams UDP connections.
Very hacky but it seems to work for me on Microsoft Teams macOS Desktop App
macOS Sequoia 15.3.2
#!/bin/bash
# teams_call_detector.sh
# Script to detect if a Teams call is active
# Prints 1 if in a call, 0 if not
# Function to check if in Teams call
function check_teams_call() {
# Count the number of Teams UDP connections
connection_count=$(lsof -nP -iUDP | grep -c "MSTeams")
# If more than 1 connection, likely in a call
if [ "$connection_count" -gt 1 ]; then
echo "1" # In call
else
echo "0" # Not in call
fi
}
# Make script more robust by handling interruptions
trap "echo -e '\nExiting Teams call detector'; exit" INT TERM
# Print header
echo "Teams Call Status Monitor"
echo "1 = In call, 0 = Not in call"
echo "Press Ctrl+C to exit"
echo "------------------------"
# Main loop - check every second
while true; do
status=$(check_teams_call)
echo -n -e "\r$(date +"%H:%M:%S") - Call status: $status "
sleep 1
done
This worked for me
New and much simpler and faster approach to use the menu status icon:
tell application "System Events"
-- Check if MSTeams is running
if not (exists process "MSTeams") then
return false
end if
tell process "MSTeams"
-- There's multiple menu bar elements, but only one with the description
set menuBar to (first UI element whose description is equal to "menu bar")
set menuStatus to name of first menu item of first menu of first menu bar item of menuBar
-- This can also be "Do not disturb", "Be right back", etc.
-- Could also change to `not equal to "Available"` if preferred
if menuStatus is equal to "Busy" then
return true
end if
end tell
return false
end tell
Does pretty much no extra looping or work:
tell application "System Events"
exists process "MSTeams"
--> true
get UI element 1 of process "MSTeams" whose description = "menu bar"
--> menu bar 2 of application process "MSTeams"
get name of menu item 1 of menu 1 of menu bar item 1 of menu bar 2 of application process "MSTeams"
--> "Busy"
end tell
Result:
true
That's great. Nice find; let's go with that. Would you be able to create a pull request? 😃
I actually don't even use this tool, it was just the first result when searching for a solution, but I can probably throw something together!
Thanks, that would be nice. But no pressure if not. Just let me know and I can also whip something up. In the long run, I kinda would like to rewrite it to Go or so. ¯\_(ツ)_/¯
I'm actually debating the approach because it turns out Teams also marks you as busy for the entire duration of your calendar event, even if you aren't in a call or the call has ended. I don't see any way to turn that off, so I'm not sure if I'm going to stick with method. I'll keep digging.
Yet another approach which will work for all apps by checking the Control Center menu bar for the Microphone in use (could also check for "Camera" or "Camera and Microphone"):
tell application "System Events"
tell process "ControlCenter"
-- There's also the "Audio and Video Controls" menu item which is less descriptive
-- and may not exist, "Control Center" should always be there
set CCMenu to (first menu bar item of menu bar 1 whose description contains "Control Center")
-- Possible values: "Control Center", "Control Center, Microphone is in use"
-- or "Control Center, Camera and Microphone are in use"
if "Microphone" is in description of CCMenu then
return true
end if
end tell
return false
end tell
I like this better for my personal requirements, but probably not a fit for this repo.
Hey @mre, I can put this in as a PR but not sure if you wanna continue supporting old teams, have support for both etc which is more of an architecture question.
Following your current approach of checking logs, I've found this works for me. I've only tested it on Windows and on Teams client build 25212.2204.3869.2204
Also tagging @jessejoe and @adnet-solutions as they might be interested in this approach.
Hope this helps!
import os
from pathlib import Path
def isInCall():
start_call_token = "HfpVoipCallCoordinatorImpl: requestStartCall completed"
end_call_token = "HfpVoipCallCoordinatorImpl: Notifying voipCallCoordinator about ended call callId"
log_paths = Path(os.getenv('LOCALAPPDATA')).glob("Packages/MSTeams_*/LocalCache/Microsoft/MSTeams/Logs/MSTeams_*.log")
with open(max(log_paths)) as latest_log_file:
latest_log = latest_log_file.read()
return latest_log.count(start_call_token) > latest_log.count(end_call_token)
Hey @TheMariday, you're right, the old teams support is probably overkill at this point. Happy to accept a PR which will make it work for the new teams. We can phase out the old version. Alternatively, we keep the logic in there but just on a best-effort basis. No hard feelings either way. 😆