Skip to content

Commit edecfae

Browse files
authored
Create real-time-text-web.md
Adding the web rtt page to quickstart
1 parent 8940b20 commit edecfae

File tree

1 file changed

+128
-0
lines changed
  • articles/communication-services/quickstarts/voice-video-calling/includes/real-time-text

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
author: Edward
3+
ms.service: azure-communication-services
4+
ms.subservice: calling
5+
ms.topic: include
6+
ms.date: 12/4/2024
7+
ms.author: edwardlee
8+
---
9+
10+
## Models
11+
| Name | Description |
12+
| ---- | ----------- |
13+
| RealTimeTextFeature | API for RealTimeText |
14+
| RealTimeTextInfo | Data structure received for each RealTimeText event |
15+
| RealTimeTextReceivedEventHandler | Callback definition for handling RealTimeTextReceivedEventType event |
16+
17+
## Get RealTimeText feature
18+
19+
``` typescript
20+
let realTimeTextFeature: SDK.RealTimeTextFeature = call.feature(SDK.Features.RealTimeText);
21+
```
22+
23+
## Subscribe to listeners
24+
25+
### Add a listener for RealTimeText data received
26+
Handle the returned RealTimeTextInfo data object. Ideally, you would have this on handler set once call is connected.
27+
28+
Note: The object contains a resultType prop that indicates whether the data is a partial text or a finalized version of the text. ResultType `Partial` indicates live messages that are subject to change, while `Final` indicates completed messages with no further changes pending.
29+
30+
```typescript
31+
const realTimeTextReceivedHandler: SDK.RealTimeTextReceivedEventHandler = (data: SDK.RealTimeTextInfo) => {
32+
    /** USER CODE HERE - E.G. RENDER TO DOM
33+
     *  data.sequenceId
34+
     *  data.sender
35+
     *  data.text
36+
     *  data.resultType
37+
     *  data.receivedTimestamp
38+
     *  data.updatedTimestamp
39+
     *  data.isLocal
40+
    */
41+
    // Example code:
42+
    // Create a dom element, i.e. div, with id "rttArea" before proceeding with the sample code
43+
    let mri: string = '';
44+
    let displayName: string = '';
45+
    switch (data.sender.identifier.kind) {
46+
        case 'communicationUser': { mri = data.sender.identifier.communicationUserId; displayName = data.sender.displayName; break; }
47+
        case 'microsoftTeamsUser': { mri = data.sender.identifier.microsoftTeamsUserId; displayName = data.sender.displayName; break; }
48+
        case 'phoneNumber': { mri = data.sender.identifier.phoneNumberdisplayName = data.sender.displayName; break; }
49+
    }
50+
51+
    const newClassName = `prefix${mri.replace(/:/g, '').replace(/-/g, '').replace(/\+/g, '')}`;
52+
    const rttText = `${(data.receivedTimestamp).toUTCString()} ${displayName ?? mri}: `;
53+
54+
    let foundRTTContainer = this.elements.rttArea.querySelector(`.${newClassName}[isNotFinal='true']`);
55+
    if (!foundRTTContainer) {
56+
        let rttContainer = document.createElement('div');
57+
        rttContainer.setAttribute('isNotFinal', 'true');
58+
        rttContainer.style['borderBottom'] = '1px solid';
59+
        rttContainer.style['whiteSpace'] = 'pre-line';
60+
        rttContainer.textContent = rttText + data.text;
61+
        rttContainer.classList.add(newClassName);
62+
63+
        this.elements.rttArea.appendChild(rttContainer);
64+
65+
        setTimeout(() => {
66+
            this.elements.rttArea.removeChild(rttContainer);
67+
        }, 40000);
68+
    } else {
69+
        if (data.text === '') {
70+
            this.elements.rttArea.removeChild(foundRTTContainer);
71+
        }
72+
        if (data.resultType === 'Final') {
73+
            foundRTTContainer.setAttribute('isNotFinal', 'false');
74+
            if (data.isLocal) {
75+
                let rttTextField = this.elements.rttMessage;
76+
                rttTextField.value = '';
77+
            }
78+
        } else {
79+
            foundRTTContainer.textContent = rttText + data.text;
80+
        }
81+
    }
82+
};
83+
realTimeTextFeature.on('realTimeTextReceived', realTimeTextReceivedHandler);
84+
```
85+
86+
## Send RealTimeText live handler
87+
In order to simulate live messaging, you will need to set up a live handler to send RealTimeText as the user types.
88+
89+
```typescript
90+
let rttTextField = document.getElementById("rttMessage") as HTMLInputElement;
91+
rttTextField.addEventListener('keyup', (event) => {
92+
    await realTimeTextFeature.sendRealTimeText(rttTextField.value);
93+
});
94+
```
95+
96+
### Send Finalized RealTimeText
97+
Once you are certain that the message has been finalized, for example, the user clicks on send message or presses enter, pass `true` to the sendRealTimeText function.
98+
``` typescript
99+
try {
100+
    let rttTextField = document.getElementById("rttMessage") as HTMLInputElement;
101+
    await realTimeTextFeature.sendRealTimeText(rttTextField.value, true);
102+
    rttTextField.value = '';
103+
} catch (e) {
104+
    console.log('ERROR Send RTT failed', e);
105+
}
106+
```
107+
108+
## Unsubscribe to listeners
109+
```typescript
110+
realTimeTextFeature.off('realTimeTextReceived', realTimeTextReceivedHandler);
111+
```
112+
113+
## RealTimeTextInfo Class
114+
115+
The `RealTimeTextInfo` class provides detailed information about each real-time text message:
116+
117+
- **sender**: Information about who sent the message.
118+
- **sequenceId**: Unique identifier for the message.
119+
- **text**: The content of the message.
120+
- **resultType**: Indicates if the message is partial or finalized.
121+
- **receivedTimestamp**: Timestamp when the message was received.
122+
- **updatedTimestamp**: Timestamp when the message was last updated.
123+
- **isLocal**: Indicates if the message was sent by the local user.
124+
125+
## Other Links
126+
127+
- Learn more about [Closed captions](../../concepts/voice-video-calling/closed-captions.md)
128+
- Get started with RTT in the [UI Library](../ui-library/ui-library-overview.md)

0 commit comments

Comments
 (0)