Share via


Walkthrough: Respond to a Conversation Invitation (Lync 2010 SDK)

This topic demonstrates how to participate in conversations started by remote users. To begin this process, your application must first start listening for incoming conversation invitations by registering for the ConversationAdded event on an instance of ConversationManager. To accept or reject an incoming conversation invitation, you must iterate on the Modalities exposed through the event argument, Conversation property. Each of the incoming conversation's modalities are individually accepted or rejected.

Preparing for Conversation Invitations

  1. Create a method called using the System.EventHandler<ConversationManagerEventArgs> delegate to handle the ConversationAdded event that is raised on an incoming invitation. You accept or reject a conversation invitation in this method.

    The details of this delegate method are described in the following steps.

  2. Get the Microsoft.Lync.Model.LyncClient. Make sure the State is ConversationState.SignedIn. For information about signing in to Microsoft Lync Server 2010, see Walkthrough: Sign In to Lync (Lync 2010 SDK).

  3. Get the Microsoft.Lync.Model.Conversation.ConversationManager class instance by reading the ConversationManager property of Microsoft.Lync.Model.LyncClient.

  4. Register for the ConversationManager.ConversationAdded event on ConversationManager.

  5. Get the Contact instance representing the local user from signed in Microsoft.Lync.Model.LyncClient instance. You must verify that this contact can participate in conversations using the conversation's modalities.

Handling a Conversation Invitation

You execute the following steps within a method that handles ConversationAdded.

Important

A conversation whose only notified modality is the InstantMessageModality should be accepted but the modality is automatically connected. You can send and receive messages as soon as the instant message conversation is active.

  1. Check the state of the Microsoft.Lync.Model.Conversation.AudioVideo.AVModality of the added conversation. If the state is ModalityState.Notified, the added conversation must be accepted or rejected. If accepted, the AVModality must be connected as shown in step 5.

    Important

    ConversationAdded is also raised when your application creates a new conversation and generates an invitation to a remote user. In this case, the conversation modality state is ModalityState.Disconnected when the new conversation is obtained in the ConversationAdded event.

  2. Verify that there is an active audio device configured on the local machine by reading the ActiveAudioDevice property. If the property returns a null value, an audio device is not configured on the local machine.

  3. Reject the incoming call if the previous walkthrough step shows that there is no active audio device. Call Reject on the conversation Microsoft.Lync.Model.Conversation.AudioVideo.AVModality.

  4. Accept the conversation modality notification by calling Modality.Accept on the Modality instance.

  5. Connect to the audio/video modality to activate the audio portion of the conversation.

Examples

The following example accepts or rejects an incoming conversation invitation based on the modalities specified for the conversation.

        /// <summary>
        /// Handles ConversationAdded state change event raised on ConversationsManager
        /// </summary>
        /// <param name="source">ConversationsManager The source of the event.</param>
        /// <param name="data">ConversationsManagerEventArgs The event data. The incoming Conversation is obtained here.</param>
        void ConversationManager_ConversationAdded(object sender, ConversationManagerEventArgs data)
        {

            Boolean IncomingAV = false;
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            //Is this an audio/video invitation?
            if (data.Conversation.Modalities[ModalityTypes.AudioVideo].State == ModalityState.Notified)
            {
                if (_LyncClient.DeviceManager.ActiveAudioDevice != null)
                {
                    sb.Append("Incoming call from ");
                    IncomingAV = true;
                }
                else
                {
                    data.Conversation.Modalities[ModalityTypes.AudioVideo].Reject(ModalityDisconnectReason.NotAcceptableHere);
                }
            }
            if (data.Conversation.Modalities[ModalityTypes.InstantMessage].State == ModalityState.Connected)
            {
                sb.Append("Incoming IM from ");
            }
            string callerName = data.Conversation.Participants[1].Contact.GetContactInformation(ContactInformationType.DisplayName).ToString();
            sb.Append(callerName);
            sb.Append(System.Environment.NewLine);
            sb.Append("Do you want to accept the invitiation?");
            if (System.Windows.Forms.MessageBox.Show(
                sb.ToString()
                , "Incoming Invitation"
                , System.Windows.Forms.MessageBoxButtons.YesNo
                , System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                data.Conversation.ParticipantAdded += Conversation_ParticipantAdded;
                data.Conversation.StateChanged += Conversation_ConversationChangedEvent;
                data.Conversation.ActionAvailabilityChanged += Conversation_ActionAvailabilityChanged;
                if (IncomingAV == true)
                {
                    InitiateAVStream(data.Conversation);
                }
            }
        }

The following example registers for participant events on the new conversation, accepts the conversation notification, and then connects to the conversation modality.

        /// <summary>
        /// Registers for events on a new conversation and connects to audio/video modality if call is incoming.
        /// </summary>
        /// <param name="pConversation">Conversation. New conversation.</param>
        private void InitiateAVStream(Conversation pConversation)
        {
            if (pConversation.State == ConversationState.Terminated)
            {
                return;
            }


            if (pConversation.Modalities[ModalityTypes.AudioVideo].CanInvoke(ModalityAction.Connect))
            {
                pConversation.Modalities[ModalityTypes.AudioVideo].ModalityStateChanged += _AVModality_ModalityStateChanged;
                pConversation.Modalities[ModalityTypes.AudioVideo].ActionAvailabilityChanged += _AVModality_ActionAvailabilityChanged;

                //Accept the notification. If Lync UI is enabled, incoming call notification is closed.
                pConversation.Modalities[ModalityTypes.AudioVideo].Accept();

                //Connect the AV modality and begin to send and received AV stream.
                object[] asyncState = { pConversation.Modalities[ModalityTypes.AudioVideo], "CONNECT" };
                pConversation.Modalities[ModalityTypes.AudioVideo].BeginConnect(ModalityCallback, asyncState);

            }
        }

        /// <summary>
        /// Called on the LyncClient worker thread when an audio/video modality action completes.
        /// </summary>
        /// <param name="ar">IAsyncResult. The state of the asynchronous operation.</param>
        private void ModalityCallback(IAsyncResult ar)
        {


            Object[] asyncState = (Object[])ar.AsyncState;
            try
            {
                if (ar.IsCompleted == true)
                {
                    if (asyncState[1].ToString() == "RETRIEVE")
                    {
                        ((AVModality)asyncState[0]).EndRetrieve(ar);
                    }
                    if (asyncState[1].ToString() == "HOLD")
                    {
                        ((AVModality)asyncState[0]).EndHold(ar);
                    }
                    if (asyncState[1].ToString() == "CONNECT")
                    {
                        ((AVModality)asyncState[0]).EndConnect(ar);
                    }
                    if (asyncState[1].ToString() == "FORWARD")
                    {
                        ((AVModality)asyncState[0]).EndForward(ar);
                    }
                }
            }
            catch (LyncClientExceptions)
            { }


        }

See Also

Concepts

Lync 2010 General Reference