Using the JAWS Scripts For Microsoft Teams
Doug Lee
Last Revised April, 2025

This Guide provides tips for using Microsoft Teams (Teams) with JAWS For Windows and these scripts. "Teams" here includes both stand-alone desktop Teams installations and web / web portal instances. When the scripts are installed and Teams is open and focused, this document can be opened via a double press of JAWSKey+F1 (or Insert+F1). For more general information about using Teams with a screen reader, consult Using Microsoft Teams With a Screen Reader.

Note that these scripts enhance, but do not replace, the native JAWS scripts for Teams that ship with JAWS 2019 and later. This document does not describe those scripts specifically. The standard JAWS help commands Insert+H and Insert+W are handled by those scripts and thus do provide documentation for them.

Warning: Microsoft Teams instances can vary widely in content for several reasons. Correspondingly, behaviors, screen appearance, specific dialog text, etc., may not be identical from one Teams instance to another. Of course, these differences can affect script performance and feature availability. Reasons for these differences among Teams instances include

Table of Contents

System Requirements For JAWS Users

These scripts require JAWS 2019 or later. Older JAWS versions do not include native Teams scripts, which these scripts load in order to avoid blocking JAWS native support. If you use JAWS 2019 and run into script load errors, be sure that your JAWS 2019 installation includes all updates to that JAWS version.

Script Installation Instructions

To install these scripts on a new system:

  1. Load JAWS if this has not already been done. This will require administrative privileges on the computer.
  2. Run JAWS as the user for whom the scripts are to be installed. This and the following steps must be performed for each user of the computer who will be using JAWS with these scripts.
  3. Download and run, or run directly, the installer for these scripts; and follow the on-screen directions. Be sure to install the scripts in the currently running JAWS version if a JAWS version list is presented.
  4. To verify successful installation, type Insert+Q while Teams is in focus. Part of the JAWS spoken response should be a revision number. If you do not hear a revision number, the scripts are not correctly loaded.

Key Sequences

These scripts incorporate commands that consist of sequences of keystrokes, all beginning with a common prefix, or "command keystroke." This approach allows many script commands without the risk of conflicting with application keystrokes. See the "Multi-Key Command Sequences" section of the "Common Script Elements" document for further details, including how to explore the available script commands (similar to exploring a menu system), and how to change the Command keystroke if necessary.

By default, the Command keystroke for these scripts is [. This document may refer to this keystroke as [ or Command; so, for example, [ Tab and Command Tab both refer to typing the prefix keystroke, then separately the Tab key. Some sequences may consist of more than two keystrokes, or "levels"; for example, [ d r would refer to typing [, then d, then finally r.

Using Teams With JAWS and the Scripts

Optimal Teams Configuration

In some cases, maximizing the currently focused Teams window, be it a main window, a chat, or another type, may cause more controls to appear. This can affect script behavior. For example, a main window that is too small may omit the tree of available chats until maximized.

Stand-Alone Application Versus Browser Teams Instance

Teams can be run as a stand-alone application or as a web page inside a browser. When practical, the stand-alone application is recommended; but this is not always possible in corporate environments. This document assumes that the stand-alone application is in use but also documents variations in the browser environment in some cases. Readers may sometimes need to translate given keystrokes to the browser equivalents.

One important variation is in how to jump among "apps" in Teams (e.g., Activities, Chats, Calendar, etc.). Ctrl with numbers accomplishes this in the stand-alone application. In the browser instance, Ctrl+Shift with numbers do this; however, starting in JAWS 2024, the native JAWS scripts use Ctrl+Shift with numbers to read recent chat messages. To switch to the Activities app in a browser instance of Teams when running JAWS 2024 or later, use the JAWS "pass next key" command, Insert+3, followed by Ctrl+Shift+1. The same approach works for all other similar commands for switching among Teams apps.

Script Commands and Features

The scripts provide the following features, commands, and command modifications:

[ C
Moves focus to a tree control, which one depending on the active screen: As of Teams 2, this command is equivalent to the native Teams Ctrl+L command, which moves focus to an item in the "left rail" list control. The equivalent native command in a web instance of Teams is Alt+Shift+L.
[ Shift+T
Announces who is typing in the displayed conversation. Due to frequent changes in the Teams interface, this command sometimes stops working.
Quick Settings (JAWSKey+V) additions
[ N and [ Shift+N
Move focus to the next and prior areas of the screen, respectively. These command sequences are duplicates of the native Ctrl+F6 and Ctrl+Shift+F6 commands and are included for those who prefer to avoid key combinations that require moving the hands away from the home row on the keyboard. They may also be useful to users of Bluetooth keyboards that require an extra Fn key for function keys.
` (the grave accent key)
Moves focus to the next control that allows it. This key acts like Tab but is capable of reaching some controls that Tab may skip. As the Teams interface matures, this command should become less often necessary, and by this writing (September, 2024) may no longer be required.
[ B
Bring up a list of buttons for selection. Press Enter on a button's name to click the button, or press Esc to close the list without activating any buttons. This command can be especially useful for finding "Hang up" and other call management buttons quickly. Note that the exact list of buttons produced by this command, and the list produced by the native JAWS script Ctrl+Shift+JAWSKey+B command available beginning in JAWS 2024, may differ on some screens.
[ L followed by a digit
Focuses a list by its position among displayed lists. [ L 1 focuses the first list, [ L 2 the second, etc. [ L 0 will focus the tenth list, if that many exist. The order of lists may not correspond to screen order. This command may not work under Teams 2.
[ S
Announce who is currently speaking in a call or meeting. Only tested in separate meeting windows but may work when the meeting is part of the main Teams window. This command has not yet been tested under Teams 2.
[ V
Announce who is currently sending video in a call or meeting. Only tested in separate meeting windows but may work when the meeting is part of the main Teams window. This command has not yet been tested under Teams 2.
[ T
Move focus to the first tab control on the screen, or the next one if more than one are available and one already has focus.
JAWSKey+F1 typed twice quickly
Opens this document in the default browser.
Insert+T
Says and Brailles, after the title, as many of the following as are applicable: If, in a one-on-one chat, the status appears as "Status unknown," it may be necessary to wait for Teams to update the status. If this condition persists for more than a minute, it may be necessary to sign into Teams.
Ctrl+JAWSKey+V typed three times quickly
Brings up, in a JAWS virtual viewer, a list of the Teams versions so far seen. Each version will be shown with the date on which it was first run with JAWS and these scripts. This is meant to simplify identification of problems arising from Teams updates, although the Teams HTML code can change without a corresponding change to the version number.

The scripts also provide the following features:

Tips and Tricks

These are tips and tricks for getting specific things done in Teams while running these scripts. To expand a tip of interest, press its associated button. Each tip includes the date on which it was last tested by this script author or by one of his assistants or clients.

Known Issues

Issues shown in this section may be fixed in future script and/or application or JAWS updates but are not addressed as of this writing. Note that specific issues may and may not be present depending on the exact version of Teams HTML or application code running.

Reactions to a channel message reply may not speak. This is a Teams accessibility shortcoming, noted and reported to Microsoft in April, 2025.

The JAWS Insert+T command may include extra words like "Blocked" or "Away" in some chat screens. This happens when a message is displayed that was sent by a person who is blocked, away, etc. This should be fixed in an upcoming script revision.

Messages in a meeting chat that is part of a separate meeting screen may not read in exactly the same way as messages in a meeting chat that is part of the main Teams screen.

The JAWS virtual and touch cursors may sometimes provide more information than the PC cursor, especially in Settings pages where they can find hints for fields, group headings, etc.

Although sharing control from a JAWS machine works well, controlling another machine from a JAWS machine via Teams does not. Use the JAWS Tandem feature for this purpose. Problems with using Teams' control support instead include

When focus switches from outside of Teams directly into a chat message list, Braille may not necessarily mirror speech for the focused chat message until the user tabs away from and back to the list once. This is due to JAWS not calling the BrailleCallbackObjectIdentify function until the user first moves among controls in Teams.

Some list controls may allow navigation with up and down arrows to move out of the list, or to wrap from one end of the list to the other.

Revision History

This is the revision history of these scripts, most recent revision first:

Revision 290, April 25, 2025, tested in Teams current as of April 23, 2025 (5072.1611.3570.1995)

Translators: There are substantial removals from one message file, and small changes/additions to that and one other.

Diff showing message file changes Lines starting with a dash are old, with a plus are new, and with a space are for context. This material is offered experimentally to see if it helps translators keep up with project changes.
=== modified file 'teams_dgl_lang.xml' (properties changed: +x to -x)
--- old/teams_dgl_lang.xml	2021-10-18 16:25:39 +0000
+++ new/teams_dgl_lang.xml	2025-04-25 21:41:07 +0000
@@ -27,16 +27,6 @@
 v=Identify participants who are sending video
 t=Move to tab control
 Shift+T=@
-u=Say User Principal Name or names
-Shift+u=Copy User Principal Name or names to clipboard
-f=Cycle through available message reading formats
-1=Read the date of the current message.
-2=Read the time of the current message
-3=Read the sender for the current message
-4=Read the content of the current message
-5=Read any flags for the current message, such as reply count, edited, etc.
-6=Read attachment information if any for the current message
-7=Read reaction types and counts for the current message
 8=Read the help text associated with the current message
 l=List focusing subcommands|List
 l&1 through 9 and 0=Move to a list by index
@@ -49,13 +39,6 @@
 <message name="msgFixingStructure">
 Fixing Teams window structure
 </message>
-<!-- For success and failure of the PressBack script. -->
-<message name="msgBack">
-Back
-</message>
-<message name="msgNoBack">
-Unable to find the Back button
-</message>
 <!-- UIA name trailers for items in the Activities/Chat/Teams etc. toolbar. -->
 <message name="scToolBarEnds">
 Toolbar|Toolbar more options|more options
@@ -91,10 +74,6 @@
 <message name="scMoreParticipants">
 more participants
 </message>
-<!-- Participant count for Insert+T. -->
-<message name="msgParticipantCount">
-%1 participants
-</message>
 <!-- Generic "not found" message. -->
 <message name="msgNotFound">
 Not found
@@ -154,52 +133,17 @@
 <message name="lbl___scProfilePicturePrefix">
 Profile picture of
 </message>
-
-<!-- Messages for the msg module. -->
-<!-- Default formats for messages. Field names are in {braces} and text blocks that appear only when fields produce text are in [square brackets]. -->
-<!-- Surrounding format: <sep><name>: <format>[<sep><name>: <format>...], where <sep> is usually |, <format> is as described above, and <name> is a user-visible name for the format. -->
-<!-- Only translate the text to the left of each colon; those are the format names presented to the user. -->
-<message name="msg___defaultMessageFormats">
-|Default custom: [{flags} ]{time} {sender}: {content}|Native:
-</message>
-<!-- How to report the format in effect when the user cycles among options. -->
-<!-- %1 is a format name from the format list; e.g., Native. -->
-<message name="msg___msgEffectiveFormat">
-Message format %1
-</message>
-<!-- Regular expression system for parsing messages, based on observations in Teams 1.3.00.4461. [DGL, 2020-03-24] -->
-<!-- System messages, like channel joins, don't match any of this and are handled natively. -->
-<!-- This is also true of inside-thread system messages like "2 replies from you and Kevin . Press Enter to expand replies." -->
-<!-- Fields generated (question mark means not always): -->
-<!-- 	dt: Date and time of message. -->
-<!-- 	date, time: Date and time split up from dt. -->
-<!-- 	sender: Sender of message. -->
-<!-- 	lastReplyDt?, lastReplyBy?: Date and time, and sender, of last reply in this message thread (seen at thread level, not inside a thread). -->
-<!-- 	lastReplyDate?, lastReplyTime?: Last reply date and time split out (present if lastReplyDt is present). -->
-<!-- 	flags: Any of several flags; e.g., edited, has attachments, has n replies, has reactions. -->
-<!-- 	replies?, newReplies?: Strings of integer reply and new-reply counts. -->
-<!-- 	content: Message content. -->
-<!-- 	help: Help text included in the MSAA AccName for the message. This can be long. -->
-<!-- Note to translators: Translate nothing left of the colon on any line; just translate text to the right of the colons. -->
-<!-- "Translate" here though means figure out what text appears in the application corresponding to the various lines. -->
-<!-- Case is significant on any line that does not include (?i). -->
-<message name="msg___parser">
-?_,_,sender,content,dt: ^(Message|Reply) from (.*?)\.\s+(.*)\.\s+Sent (.+?)\.\s+
-?_,sender,content,dt: ^Threaded conversation with 0 replies,\s+from ([^,]+),\s+(.*?)\s*, started ([^\.]+)\.\s+
-?_,_,sender,content,dt,+flags,replies,_,newReplies,lastReplyBy,lastReplyDt: ^Threaded conversation with \d+ (reply|replies),\s+from ([^,]+),\s+(.*?)\s*, started ([^\.]+)\.\s+((\d+) (reply|replies), (\d+) new)\. Last reply by (.*?) on ([^\.]+)\.\s+
-/dt/!dt: .+
-?/dt/_: ^on\s+
-?_,+flags: (Edited)\.\s+
-?_,+flags: (Message has reactions)\s+
-?_,+flags: (The message has an attachment)\.\s+
-_,_,+flags,help: ^((?!Press )(.*?)\s+)?(Press .*)$
-?+flags: .*
-/dt/!dt,date,time,_: ^(.*?)\s+(\d+:.*(\s+AM|\s+PM)?)
-?/lastReplyDt/!lastReplyDt,lastReplyDate,lastReplyTime,_: ^(.*?)\s+(\d+:.*(\s+AM|\s+PM)?)
-?/flags/_: , 0 new
-?/flags/_: ,(?= \d+ new)
-?/date/_: \s+at\s*$
-?/lastReplyDate/_: \s+at\s*$
+<!-- Case-insensitive names of list/tree controls from various apps. -->
+<message name="lbl___scChats">
+Chats
+</message>
+<message name="lbl___scFeed">
+Feed
+</message>
+<!-- Case-sensitive text appearing in GetObjectName() for a chat message containing one or more links. -->
+<!-- This must be preceded and followed by a space. -->
+<message name="lbl___scLink">
+Link
 </message>

 <!-- Messages for the tabs module. -->
@@ -212,6 +156,13 @@
 Tab control %1 of %2
 </message>

+<!-- Messages for the tutil module. -->
+<!-- The string in the browser title bar that indicates Teams Classic. -->
+<!-- Punctuation and spacing matter here, but letter casing does not. -->
+<message name="tutil___scClassicTitle">
+| Microsoft Teams classic
+</message>
+
 <!-- Messages for the Electron module. -->
 <!-- The names of the normal buttons found in an application title bar or dialog. Case sensitive. -->
 <message name="electron___scTitleButtonNames">
@@ -408,32 +359,6 @@
 <message name="re___msgNoREObject">
 Unable to create a VBScript.RegExp object
 </message>
-<!-- Format of an error message that has a line number to include. %1 is the line number and %2 is the error message. %3 is the parser line that generated the error. -->
-<!-- %4 is the name of the results member used as source material, and %5 is the source string at the time. -->
-<message name="re___msgErrorFormat1">
-Error at parser line %1: %2
-Parser line: %3
-Value of %4 at the time: '%5'
-</message>
-<!-- Various error messages. -->
-<message name="re___msgParserFormatError">
-Syntax error; line not understood
-</message>
-<!-- %1 is the number of names to catch matches/submatches from a parser line, and %2 is the number of submatches (which should be one less than the name count so the full match can take the first name). -->
-<message name="re___msgMatchCountMismatch">
-%1 names available but found a full match and %1 submatches
-</message>
-<message name="re___msgMatchFail">
-Match failed and is not optional
-</message>
-<!-- %1 is the name of a result which is not permitted. -->
-<message name="re___msgBadName">
-Results name %1 is not allowed (names that begin and end with an underscore are reserved)
-</message>
-<!-- %1 is the name of a result which is being assigned to twice without a + or ! indicating that this is allowed. -->
-<message name="re___msgDupName">
-Results name %1 is being assigned to twice without a + or ! indicator
-</message>

 </language>
 <!-- New languages go just above this line. -->

=== modified file 'teams_jcpdict_lang.xml' (properties changed: +x to -x)
--- old/teams_jcpdict_lang.xml	2021-08-06 15:50:20 +0000
+++ new/teams_jcpdict_lang.xml	2025-04-25 21:41:07 +0000
@@ -30,7 +30,7 @@
 <message name="jcp___typeReadOnlyEdit">
 read only edit
 </message>
-<!-- This is what JAWS calls a graphic, but there seems not to be a WT_* constant for this one, at least for which getControlTypeName returns this string. -->
+<!-- This should match WT_Bitmap. -->
 <message name="jcp___typeGraphic">
 Graphic
 </message>

Revision 223, October 18, 2021, tested in Teams app version 1.4.00.26376

This revision splits off from revisions that supported Teams versions older than 1.4.00.11161. This revision may support a few older Teams versions but not many.

This is also the final script revision that received partial corporate funding, by way of this author's then current employer. This consisted of payment for this author's company-internal script support time and for some features developed by coworker request between 2018 and 2021.

Revision 208, June 9, 2021, tested in Teams app version 1.4.00.11161

This revision is the last revision supporting Teams versions 1.4.00.11161 and older. This revision may support some newer versions but not all. Download this revision if you use Teams 1.4.00.11161 or older.

Revision 204, May 7, 2021, tested in Teams app version 1.4.00.11161

11 older revisions back through March 4, 2020

Revision 202, April 29, 2021, tested in Teams app version 1.4.00.8872

Warning: This revision marks the end of support for JAWS versions 17.0, 18.0, and 2018. This is because this revision starts cooperating with Teams scripts that are included in JAWS itself starting in JAWS 2019, but these can't be loaded in 2018 and older because they don't exist there. If you need Teams scripts in JAWS 17, 18, or 2018, use the revision 193 installer for JAWS 17, 18, and 2018 instead of the current revision. There are no plans to continue updating that revision, though some of the below enhancements are included there.

Important: The BX Update feature for updating scripts will not work as a means of updating to revision 193 or later from an older revision. It is necessary to run the appropriate script installer.

The following changes apply to both the current revision and revision 193:

The following changes are available in this revision but not in revision 193:

Revision 173, October 07, 2020, tested in Teams app version 1.3.00.21759

Revision 162, September 01, 2020, tested in Teams app version 1.3.00.21759

Revision 150, August 18, 2020

Revision 139, July 01, 2020

Revision 116, April 19, 2020

Revision 108, April 15, 2020

Revision 99, April 14, 2020

Revision 98, April 07, 2020

Revision 71, March 10, 2020

Revision 62, March 4, 2020