Saif Alshawabkeh

Look at me!

"yeh"

Automatically Join Teams Meetings

I’m doing two summer courses just because, and one of them is online. God forbid I actually wake up at 8:30 AM to attend a computer structures class. My idea is to write a script that runs every morning, automatically joins a Teams meeting muted, then leaves. Maybe also record the screen if the prof is one of those people who don’t like to have happy students and don’t share recordings. We’ll see, summer didn’t begin yet.

Here’s the plan:

  • Figure out a way to read email
    • No way I’m putting my password as plaintext in a python script. I’d either go the roundabout way with CredReadW on C++ side, or mess around with windll bindings.
    • Then maybe pull the meeting link from the email server. Simple IMAP calls get me what I want.
  • Figure out a way to control Edge
    • Selenium Webdriver, because I do need two-way communication.
    • A way to open the link, then click on the join button.
    • Don’t join in too early, don’t want to have the prof chatting with the machine
    • A way to find when the meeting’s done, and leave before anyone suspects anything

Maybe powershell isn’t so bad after all

Here’s the powershell script I’m using, copy pasted as-is:

# Make sure it's on
if ((get-process -Name Outlook -ErrorAction SilentlyContinue).Count -le 0) {
    Start-Process "C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.EXE" -WindowStyle Hidden
}

# Unneeded i think, assembly should be global
# Add-Type -assembly "Microsoft.Office.Interop.Outlook"
$Outlook = New-Object -comobject Outlook.Application
$namespace = $Outlook.GetNameSpace("MAPI")

# https://stackoverflow.com/a/57027986/11367507
# blocking sync folders
for($i = 1; $i -le $namespace.SyncObjects.Count; $i += 1) {
    $sync = $namespace.SyncObjects.Item($i) # one-based ffs
    $sync.Start()
}

# Replace this with a special meeting inbox and setup a filter rule to route all to that
$Inbox_Folder = $namespace.Folders.Item('[email protected]').Folders.Item('Inbox')
# https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem
#$Latest_mail = $MyFolder1.Items | Sort-Object -Property ReceivedTime -Descending | Select-Object -First 1
$sorted_mail = $Inbox_Folder.Items
# COM side is much faster than powershell side. Shame on microsoft.
# https://learn.microsoft.com/en-us/office/vba/api/outlook.items.sort
$sorted_mail.Sort('[ReceivedTime]',$true)
$Latest_mail = $sorted_mail.GetFirst()
$Latest_mail.Body
#$sorted_mail.GetNext().Body
# 1 based indices eww
# set .UnRead as false to mark as read
# https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem.unread
# $MyFolder1.Items.item(1).UnRead = $true # VBA style accessing

It’s very obviously an API designed for VBA, but the core idea is to start syncing each SyncObject with a blocking loop instead of an async call to SendAndReceive(), to make sure we actually have all mail fetched before continuing script execution. The docs state that mail items aren’t stored in a particular order, so we sort by descending received date.