Raise hand states
Important
Functionality described in this document is currently in public preview. This preview version is provided without a service-level agreement, and we don't recommend it for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
Important
Functionality described in this document is currently in public preview. This preview version is provided without a service-level agreement, and we don't recommend it for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
Important
Functionality described in this document is currently in public preview. This preview version is provided without a service-level agreement, and we don't recommend it for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
During an active call, you may want to send or receive states from other users. Let's learn how.
Prerequisites
- An Azure account with an active subscription. Create an account for free.
- A deployed Communication Services resource. Create a Communication Services resource.
- A user access token to enable the calling client. For more information, see Create and manage access tokens.
- Optional: Complete the quickstart to add voice calling to your application
Install the SDK
Use the npm install
command to install the Azure Communication Services calling and common SDKs for JavaScript.
npm install @azure/communication-common --save
npm install @azure/communication-calling --save
Initialize required objects
A CallClient, instance is required for most call operations. Let's create a new CallClient
instance. You can configure it with custom options like a Logger instance.
When you have a CallClient
instance, you can create a CallAgent
instance by calling the createCallAgent
method on the CallClient
instance. This method asynchronously returns a CallAgent
instance object.
The createCallAgent
method uses CommunicationTokenCredential
as an argument. It accepts a user access token.
You can use the getDeviceManager
method on the CallClient
instance to access deviceManager
.
const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");
// Set the logger's log level
setLogLevel('verbose');
// Redirect log output to wherever desired. To console, file, buffer, REST API, etc...
AzureLogger.log = (...args) => {
console.log(...args); // Redirect log output to console
};
const userToken = '<USER_TOKEN>';
callClient = new CallClient(options);
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const callAgent = await callClient.createCallAgent(tokenCredential, {displayName: 'optional Azure Communication Services user name'});
const deviceManager = await callClient.getDeviceManager()
The Raise Hand feature allows participants in a call to indicate that they have a question, comment, or concern without interrupting the speaker or other participants. This feature can be used in any call type, including 1:1 calls and calls with many participants, in Azure Communication Service and in Teams calls. You first need to import calling Features from the Calling SDK:
import { Features} from "@azure/communication-calling";
Then you can get the feature API object from the call instance:
const raiseHandFeature = call.feature(Features.RaiseHand );
Raise and lower hand for current participant:
To change the Raise Hand state for the current participant, you can use the raiseHand()
and lowerHand()
methods.
This is async methods, to verify results can be used raisedHandChanged
and loweredHandChanged
listeners.
const raiseHandFeature = call.feature(Features.RaiseHand );
//raise
raiseHandFeature.raiseHand();
//lower
raiseHandFeature.lowerHand();
Lower hands for other participants
This feature allows users with the Organizer and Presenter roles to lower all hands for other participants on Teams calls. In Azure Communication calls, changing the state of other participants is not allowed unless roles have been added.
To use this feature, you can use the following code:
const raiseHandFeature = call.feature(Features.RaiseHand );
//lower all hands on the call
raiseHandFeature.lowerAllHands();
//or we can provide array of CommunicationIdentifier to specify list of participants
CommunicationUserIdentifier acsUser = new CommunicationUserIdentifier(<USER_ID>);
MicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier(<USER_ID>)
CommunicationIdentifier participants[] = new CommunicationIdentifier[]{ acsUser, teamsUser };
raiseHandFeature.lowerHands(participants);
Handle changed states
With the Raise Hand API, you can subscribe to the raisedHandChanged
and loweredHandChanged
events to handle changes in the state of participants on a call. These events are triggered by a call instance and provide information about the participant whose state has changed.
To subscribe to these events, you can use the following code:
const raiseHandFeature = call.feature(Features.RaiseHand );
// event : {identifier: CommunicationIdentifier}
const raisedHandChangedHandler = (event) => {
console.log(`Participant ${event.identifier} raised hand`);
};
const loweredHandChangedHandler = (event) => {
console.log(`Participant ${event.identifier} lowered hand`);
};
raiseHandFeature.on('raisedHandChanged', raisedHandChangedHandler):
raiseHandFeature.on('loweredHandChanged', loweredHandChangedHandler):
The raisedHandChanged
and loweredHandChanged
events contain an object with the identifier
property, which represents the participant's communication identifier. In the example above, we log a message to the console indicating that a participant has raised their hand.
To unsubscribe from the events, you can use the off
method.
List of all participants with active state
To get information about all participants that have raised hand state on current call, you can use the getRaisedHands
api. he returned array is sorted by the order field.
Here's an example of how to use the getRaisedHands
API:
const raiseHandFeature = call.feature(Features.RaiseHand );
let participantsWithRaisedHands = raiseHandFeature.getRaisedHands();
Order of raised Hands
The participantsWithRaisedHands
variable will contain an array of participant objects, where each object has the following properties:
identifier
: the communication identifier of the participant
order
: the order in which the participant raised their hand
You can use this information to display a list of participants with the Raise Hand state and their order in the queue.
Install the SDK
Locate your project level build.gradle and make sure to add mavenCentral()
to the list of repositories under buildscript
and allprojects
buildscript {
repositories {
...
mavenCentral()
...
}
}
allprojects {
repositories {
...
mavenCentral()
...
}
}
Then, in your module level build.gradle add the following lines to the dependencies section
dependencies {
...
implementation 'com.azure.android:azure-communication-calling:1.0.0'
...
}
Initialize the required objects
To create a CallAgent
instance you have to call the createCallAgent
method on a CallClient
instance. This asynchronously returns a CallAgent
instance object.
The createCallAgent
method takes a CommunicationUserCredential
as an argument, which encapsulates an access token.
To access the DeviceManager
, a callAgent instance must be created first, and then you can use the CallClient.getDeviceManager
method to get the DeviceManager.
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an Activity for instance
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential).get();
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
To set a display name for the caller, use this alternative method:
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an Activity for instance
CallAgentOptions callAgentOptions = new CallAgentOptions();
callAgentOptions.setDisplayName("Alice Bob");
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential, callAgentOptions).get();
The Raise Hand feature allows participants in a call to indicate that they have a question, comment, or concern without interrupting the speaker or other participants. This feature can be used in any call type, including 1:1 calls and calls with many participants, in Azure Communication Service and in Teams calls. You first need to import calling Features from the Calling SDK:
import com.azure.android.communication.calling.RaiseHandFeature;
Then you can get the feature API object from the call instance:
RaiseHandFeature raiseHandFeature = call.feature(Features.RAISE_HAND);
Raise and lower hand for current participant:
To change the Raise Hand state for the current participant, you can use the raiseHand()
and lowerHand()
methods.
This is async methods, to verify results can be used RaisedHandReceived
and LoweredHandReceived
listeners.
RaiseHandFeature raiseHandFeature = call.feature(Features.RAISE_HAND);
//raise
raiseHandFeature.raiseHand();
//lower
raiseHandFeature.lowerHand();
Lower hands for other participants
This feature allows users with the Organizer and Presenter roles to lower all hands for other participants on Teams calls. In Azure Communication calls, changing the state of other participants is not allowed unless roles have been added.
To use this feature, you can use the following code:
RaiseHandFeature raiseHandFeature = call.feature(Features.RAISE_HAND);
//lower all hands on the call
raiseHandFeature.lowerAllHands();
//or we can provide array of CommunicationIdentifier to specify list of participants
List<CommunicationIdentifier> identifiers = new ArrayList<>();
CommunicationUserIdentifier acsUser = new CommunicationUserIdentifier(<USER_ID>);
MicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier(<USER_ID>);
identifiers.add(new CommunicationUserIdentifier("<USER_ID>"));
identifiers.add(new MicrosoftTeamsUserIdentifier("<USER_ID>"));
raiseHandFeature.lowerHands(identifiers);
Handle changed states
With the Raise Hand API, you can subscribe to the RaisedHandReceived
and LoweredHandReceived
events to handle changes in the state of participants on a call. These events are triggered by a call instance and provide information about the participant whose state has changed.
To subscribe to these events, you can use the following code:
RaiseHandFeature raiseHandFeature = call.feature(Features.RAISE_HAND)
// event example : {identifier: CommunicationIdentifier, isRaised: true, order:1}
call.feature(Features.RAISE_HAND).addOnRaisedHandReceivedListener(raiseHandEvent -> {
Log.i(TAG, String.format("Raise Hand: %s : %s", Utilities.toMRI(raiseHandEvent.getIdentifier()), raiseHandEvent.isRaised()));
});
The RaisedHandReceived
and LoweredHandReceived
events contain an object with the identifier
property, which represents the participant's communication identifier. In the example above, we log a message to the console indicating that a participant has raised their hand.
To unsubscribe from the events, you can use the off
method.
List of all participants with active state
To get information about all participants that have raised hand state on current call, you can use the getRaisedHands
api. he returned array is sorted by the order field.
Here's an example of how to use the getRaisedHands
API:
RaiseHandFeature raiseHandFeature = call.feature(Features.RAISE_HAND);
List<RaiseHand> participantsWithRaisedHands = raiseHandFeature.getRaisedHands();
Order of raised Hands
The participantsWithRaisedHands
variable will contain an array of participant objects, where each object has the following properties:
identifier
: the communication identifier of the participant
order
: the order in which the participant raised their hand
You can use this information to display a list of participants with the Raise Hand state and their order in the queue.```
Set up your system
Create the Xcode project
In Xcode, create a new iOS project and select the Single View App template. This quickstart uses the SwiftUI framework, so you should set the Language to Swift and User Interface to SwiftUI.
You're not going to create unit tests or UI tests during this quickstart. Feel free to clear the Include Unit Tests and Include UI Tests text boxes.
Install the package and dependencies with CocoaPods
Create a Podfile for your application, like this:
platform :ios, '13.0' use_frameworks! target 'AzureCommunicationCallingSample' do pod 'AzureCommunicationCalling', '~> 1.0.0' end
Run
pod install
.Open
.xcworkspace
with Xcode.
Request access to the microphone
To access the device's microphone, you need to update your app's information property list with NSMicrophoneUsageDescription
. You set the associated value to a string
that will be included in the dialog that the system uses to request access from the user.
Right-click the Info.plist
entry of the project tree and select Open As > Source Code. Add the following lines in the top-level <dict>
section, and then save the file.
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>
Set up the app framework
Open your project's ContentView.swift file and add an import
declaration to the top of the file to import the AzureCommunicationCalling
library. In addition, import AVFoundation
. You'll need it for audio permission requests in the code.
import AzureCommunicationCalling
import AVFoundation
Initialize CallAgent
To create a CallAgent
instance from CallClient
, you have to use a callClient.createCallAgent
method that asynchronously returns a CallAgent
object after it's initialized.
To create a call client, you have to pass a CommunicationTokenCredential
object.
import AzureCommunication
let tokenString = "token_string"
var userCredential: CommunicationTokenCredential?
do {
let options = CommunicationTokenRefreshOptions(initialToken: token, refreshProactively: true, tokenRefresher: self.fetchTokenSync)
userCredential = try CommunicationTokenCredential(withOptions: options)
} catch {
updates("Couldn't created Credential object", false)
initializationDispatchGroup!.leave()
return
}
// tokenProvider needs to be implemented by Contoso, which fetches a new token
public func fetchTokenSync(then onCompletion: TokenRefreshOnCompletion) {
let newToken = self.tokenProvider!.fetchNewToken()
onCompletion(newToken, nil)
}
Pass the CommunicationTokenCredential
object that you created to CallClient
, and set the display name.
self.callClient = CallClient()
let callAgentOptions = CallAgentOptions()
options.displayName = " iOS Azure Communication Services User"
self.callClient!.createCallAgent(userCredential: userCredential!,
options: callAgentOptions) { (callAgent, error) in
if error == nil {
print("Create agent succeeded")
self.callAgent = callAgent
} else {
print("Create agent failed")
}
})
The Raise Hand feature allows participants in a call to indicate that they have a question, comment, or concern without interrupting the speaker or other participants. This feature can be used in any call type, including 1:1 calls and calls with many participants, in Azure Communication Service and in Teams calls. You first need to import calling Features from the Calling SDK:
import AzureCommunicationCalling
Then you can get the feature API object from the call instance:
@State var raisehandFeature: RaiseHandCallFeature?
raiseHandFeature = self.call!.feature(Features.raiseHand)
Raise and lower hand for current participant:
To change the Raise Hand state for the current participant, you can use the raiseHand()
and lowerHand()
methods.
//publish raise hand state for local participant
raisehandFeature.raiseHand(completionHandler: { (error) in
if let error = error {
print ("Feature failed raise a hand %@", error as Error)
}
})
//remove raise hand state for local participant
raisehandFeature.lowerHand(completionHandler: { (error) in
if let error = error {
print ("Feature failed lower hand %@", error as Error)
}
})
Lower hands for other participants
This feature allows users with the Organizer and Presenter roles to lower all hands for other participants on Teams calls. In Azure Communication calls, changing the state of other participants is not allowed unless roles have been added.
To use this feature, you can use the following code:
// remove raise hand states for all participants on the call
raisehandFeature.lowerAllHands(completionHandler: { (error) in
if let error = error {
print ("Feature failed lower all hands %@", error as Error)
}
})
// remove raise hand states for all remote participants on the call
let identifiers = (call?.remoteParticipants.map {$0.identifier})!;
raisehandFeature.lowerHands(participants: identifiers, completionHandler: { (error) in
if let error = error {
print ("Feature failed lower hands %@", error as Error)
}
})
// remove raise hand state of specific user
var identifiers : [CommunicationIdentifier] = []
identifiers.append(CommunicationUserIdentifier("<USER_ID>"))
raisehandFeature.lowerHands(participants: identifiers, completionHandler: { (error) in
if let error = error {
print ("Feature failed lower hands %@", error as Error)
}
})
Handle changed states
With the Raise Hand API, you can subscribe to the RaisedHandReceived
and LoweredHandReceived
events to handle changes in the state of participants on a call. These events are triggered by a call instance and provide information about the participant whose state has changed.
To subscribe to these events, you can use the following code:
self.callObserver = CallObserver(view:self)
raisehandFeature = self.call!.feature(Features.raiseHand)
raisehandFeature!.delegate = self.callObserver
public class CallObserver : NSObject, RaiseHandCallFeatureDelegate
{
// event example : {identifier: CommunicationIdentifier}
public func raiseHandCallFeature(_ raiseHandCallFeature: RaiseHandCallFeature, didReceiveRaisedHand args: RaisedHandChangedEventArgs) {
os_log("Raise hand feature updated: %s is raised hand", log:log, Utilities.toMri(args.identifier))
raiseHandCallFeature.raisedHands.forEach { raiseHand in
os_log("Raise hand active: %s", log:log, Utilities.toMri(raiseHand.identifier))
}
}
public func raiseHandCallFeature(_ raiseHandCallFeature: RaiseHandCallFeature, didReceiveLoweredHand args: LoweredHandChangedEventArgs) {
os_log("Raise hand feature updated: %s is lowered hand", log:log, Utilities.toMri(args.identifier))
raiseHandCallFeature.raisedHands.forEach { raiseHand in
os_log("Raise hand active: %s", log:log, Utilities.toMri(raiseHand.identifier))
}
}
}
The RaisedHandReceived
and LoweredHandReceived
events contain an object with the identifier
property, which represents the participant's communication identifier. In the example above, we log a message to the console indicating that a participant has raised their hand.
To unsubscribe from the events, you can use the off
method.
List of all participants with active state
To get information about all participants that have raised hand state on current call, you can use the getRaisedHands
api. he returned array is sorted by the order field.
Here's an example of how to use the raisedHands
API:
raisehandFeature = self.call!.feature(Features.raiseHand)
raisehandFeature.raisedHands.forEach { raiseHand in
os_log("Raise hand active: %s", log:log, Utilities.toMri(raiseHand.identifier))
}
Order of raised Hands
The raisedHands
variable will contain an array of participant objects, where each object has the following properties:
identifier
: the communication identifier of the participant
order
: the order in which the participant raised their hand
You can use this information to display a list of participants with the Raise Hand state and their order in the queue.```
Setting up
Creating the Visual Studio project
For UWP app, in Visual Studio 2022, create a new Blank App (Universal Windows)
project. After entering the project name, feel free to pick any Windows SDK greater than 10.0.17763.0
.
For WinUI 3 app, create a new project with the Blank App, Packaged (WinUI 3 in Desktop)
template to set up a single-page WinUI 3 app. Windows App SDK version 1.3 and above is required.
Install the package and dependencies with NuGet Package Manager
The Calling SDK APIs and libraries are publicly available via a NuGet package. The following steps exemplify how to find, download, and install the Calling SDK NuGet package.
- Open NuGet Package Manager (
Tools
->NuGet Package Manager
->Manage NuGet Packages for Solution
) - Click on
Browse
and then typeAzure.Communication.Calling.WindowsClient
in the search box. - Make sure that
Include prerelease
check box is selected. - Click on the
Azure.Communication.Calling.WindowsClient
package, selectAzure.Communication.Calling.WindowsClient
1.4.0-beta.1 or newer version. - Select the checkbox corresponding to the CS project on the right-side tab.
- Click on the
Install
button.
The Raise Hand feature allows participants in a call to indicate that they have a question, comment, or concern without interrupting the speaker or other participants. This feature can be used in any call type, including 1:1 calls and calls with many participants, in Azure Communication Service and in Teams calls. You first need to import calling Features from the Calling SDK:
using Azure.Communication.Calling.WindowsClient;
Then you can get the feature API object from the call instance:
private RaiseHandCallFeature raiseHandCallFeature;
raiseHandCallFeature = (RaiseHandCallFeature)call.GetCallFeatureExtension(CallFeatureType.RaiseHand);
Raise and lower hand for current participant:
To change the Raise Hand state for the current participant, you can use the raiseHand()
and lowerHand()
methods.
This is async methods, to verify results can be used RaisedHandReceived
and LoweredhandReceived
listeners.
//publish raise hand state for local participant
raiseHandCallFeature.RaiseHandAsync();
//remove raise hand state for local participant
raiseHandCallFeature.LowerHandAsync();
Lower hands for other participants
This feature allows users with the Organizer and Presenter roles to lower all hands for other participants on Teams calls. In Azure Communication calls, changing the state of other participants is not allowed unless roles have been added.
To use this feature, you can use the following code:
// remove raise hand states for all participants on the call
raiseHandCallFeature.LowerAllHandsAsync();
// remove raise hand states for all remote participants on the call
var participants = call.RemoteParticipants;
var identifiers = participants.Select(p => p.Identifier).ToList().AsReadOnly();
raiseHandCallFeature.LowerHandsAsync(identifiers);
// remove raise hand state of specific user
var identifiers = new List<CallIdentifier>();
identifiers.Add(new UserCallIdentifier("USER_ID"));
raiseHandCallFeature.LowerHandsAsync(identifiers);
Handle changed states
With the Raise Hand API, you can subscribe to the RaisedHandReceived
and LoweredHandReceived
events to handle changes in the state of participants on a call. These events are triggered by a call instance and provide information about the participant whose state has changed.
To subscribe to these events, you can use the following code:
raiseHandCallFeature = (RaiseHandCallFeature)call.GetCallFeatureExtension(CallFeatureType.RaiseHand);
raiseHandCallFeature.RaisedHandReceived += OnRaisedHandChange;
raiseHandCallFeature.LoweredHandReceived += OnLoweredHandChange;
private async void OnRaisedHandChange(object sender, RaisedHandChangedEventArgs args)
{
Trace.WriteLine("RaiseHandEvent: participant " + args.Identifier + " is raised hand");
}
private async void OnLoweredHandChange(object sender, RaisedHandChangedEventArgs args)
{
Trace.WriteLine("RaiseHandEvent: participant " + args.Identifier + " is lowered hand");
}
The RaisedHandReceived
and LoweredHandReceived
events contain an object with the identifier
property, which represents the participant's communication identifier. In the example above, we log a message to the console indicating that a participant has raised their hand.
To unsubscribe from the events, you can use the off
method.
List of all participants with active state
To get information about all participants that have raised hand state on current call, you can use the getRaisedHands
api. he returned array is sorted by the order field.
Here's an example of how to use the RaisedHands
API:
raiseHandCallFeature = (RaiseHandCallFeature)call.GetCallFeatureExtension(CallFeatureType.RaiseHand);
foreach (RaiseHand rh in raiseHandCallFeature.RaisedHands.ToList())
{
Trace.WriteLine("Participant " + rh.Identifier.RawId + " has raised hand ");
}
Order of raised Hands
The RaisedHands
variable will contain an array of participant objects, where each object has the following properties:
identifier
: the communication identifier of the participant
order
: the order in which the participant raised their hand
You can use this information to display a list of participants with the Raise Hand state and their order in the queue.
Additional resources For more information about using the Raise Hand feature in Teams calls and meetings, see the Microsoft Teams documentation.
Next steps
Feedback
Submit and view feedback for