使用Unified Communications Managed API獲取Lync線上會議的連結地址

dax.net發表於2013-08-11

最近在專案上遇到一個問題,需要能夠在程式中獲取Lync會議的連結地址。Lync是微軟出品的一套即時通訊(IM)客戶端軟體,配合Microsoft Lync Server使用,其前身是Microsoft Office Communicator(MOC)。與Live Messenger相比,Lync更適合企業內部使用,因為它還具備一定的與企業級應用元件進行整合的功能。在Microsoft Office 2010/2013中,Lync已成為Office中的一個套件。

在企業內部使用Outlook和Lync的讀者一定知道,Outlook中有一個Lync的外掛,當啟用了該外掛後,即可在“日曆”檢視中通過單擊New Lync Meeting按鈕來安排一個帶有Lync線上會議連結地址的Appointment:

8-9-2013 4-51-42 PM

正如上圖所示,在這個Appointment視窗中,有個Join Lync Meeting的超級連結,滑鼠移動到這個連結上,會提示出其所對應的超級連結地址,也就是Lync線上會議的連結地址。現在,我們就需要通過編寫C#程式的方式,來獲得這個Lync線上會議的連結地址。

SDK的選擇

經過上網搜尋研究,與Outlook和Lync相關的SDK大致有以下幾種:

  1. Lync 2010/2013 SDK
  2. Exchange Web Services (EWS)
  3. Unified Communications Managed API (UCMA)
  4. Unified Communications Web API (UCWA)

Lync 2010/2013 SDK主要是通過Automation物件來實現Lync客戶端的操作,因此,使用Lync SDK時,Lync客戶端需要一直執行,否則無法獲得Automation物件。Lync SDK也支援Suppress UI的模式,這樣開發者就可以遮蔽Lync的使用者介面,而使用自己的軟體介面來使用Lync客戶端的功能,但無論是否是Suppress UI的模式,都需要Lync客戶端一直執行。

Exchange Web Services (EWS)是一套訪問Exchange Server的API,通過使用EWS,可以在程式中通過Exchange Server傳送電子郵件、管理電子郵件、安排Outlook會議,以及管理自己的Outlook資料夾等等。

Unified Communications Managed API (UCMA) 是一套基於.NET的API,通過使用UCWA,可以獲得Microsoft Lync Server的增強狀態資訊、即時訊息、電話、視訊、音訊、會議等的訪問和控制功能。

Unified Communications Web API (UCWA) 是UCMA的Web版,通過Javascript、Json等技術向異構平臺提供UCMA的功能。

終上所述,在我們的應用中,應該選擇Unified Communications Managed API (UCMA)來實現Lync線上會議連結地址的獲取。

程式碼實現

首先需要安裝Unified Communications Web API,這可以到微軟的官方網站下載。下載安裝之後,即可開始編寫程式碼。

建立一個控制檯應用程式(Console Application),新增對Microsoft.Rtc.Collaboration.dll程式集的引用。之後,還需要會議組織者在企業中的電子郵件地址,以及Lync伺服器的地址。前者容易獲得,讀者可以使用自己的郵件地址進行測試;而Lync伺服器的地址,則可以在托盤中右鍵單擊Lync圖示,在彈出的選單中選擇顯示Lync詳細資訊的選項來獲得。

下面的程式碼完整地展示了通過UCMA來獲取Lync線上會議的連結地址,具體內容請參考程式碼中的註釋:

using System;
using System.Threading;
using Microsoft.Rtc.Collaboration;
using Microsoft.Rtc.Collaboration.ConferenceManagement;
using Microsoft.Rtc.Signaling;

namespace ConsoleApplication7
{
    class Program
    {
        static AutoResetEvent platformStartupCompleted = new AutoResetEvent(false);
        static AutoResetEvent endpointInitCompleted = new AutoResetEvent(false);
        static AutoResetEvent conferenceScheduleCompleted = new AutoResetEvent(false);

        static void Main(string[] args)
        {
            var ownerURI = "<在此填寫會議組織者URI,格式為:sip:郵箱地址>";
            var serverAddress = "<在此填寫Lync伺服器地址>";
            var applicationName = "ConsoleApplication";
            // 通過ClientPlatformSettings來初始化一個CollaborationPlatform。
            // 注意,Transport Type應使用SipTransportType.Tls。
            ClientPlatformSettings clientPlatformSettings = new ClientPlatformSettings(applicationName, 
                SipTransportType.Tls);
            CollaborationPlatform platform = new CollaborationPlatform(clientPlatformSettings);
            // 啟動CollaborationPlatform例項
            platform.BeginStartup(platformEndStartup, platform);
            platformStartupCompleted.WaitOne();
            Console.WriteLine("Platform initialized...");

            // 通過UserEndpointSettings來初始化一個UserEndpoint。
            UserEndpointSettings userEndpointSettings = new UserEndpointSettings(ownerURI, serverAddress);
            userEndpointSettings.Credential = System.Net.CredentialCache.DefaultNetworkCredentials;
            UserEndpoint endpoint = new UserEndpoint(platform, userEndpointSettings);
            // 建立UserEndpoint的連線
            endpoint.BeginEstablish(endpointEndEstablish, endpoint);
            endpointInitCompleted.WaitOne();
            Console.WriteLine("Endpoint initialized...");

            // 設定會議的建立選項,詳細的設定選項請參考ConferenceScheduleInformation類的定義。
            ConferenceScheduleInformation conferenceScheduleInformation = new ConferenceScheduleInformation();
            conferenceScheduleInformation.AccessLevel = ConferenceAccessLevel.Invited;
            conferenceScheduleInformation.Description = "Conference Description";
            ConferenceParticipantInformation participantA_Information =
                new ConferenceParticipantInformation(ownerURI, ConferencingRole.Leader);
            conferenceScheduleInformation.Participants.Add(participantA_Information);
            conferenceScheduleInformation.LobbyBypass = LobbyBypass.EnabledForGatewayParticipants;
            conferenceScheduleInformation.AutomaticLeaderAssignment = AutomaticLeaderAssignment.SameEnterprise;
            ConferenceMcuInformation audioVideoMCU = new ConferenceMcuInformation(McuType.AudioVideo);
            conferenceScheduleInformation.Mcus.Add(audioVideoMCU);

            // 根據會議的建立選項建立新的Lync會議
            endpoint.ConferenceServices.BeginScheduleConference(conferenceScheduleInformation,
                conferenceEndScheduled, endpoint.ConferenceServices);
            
            conferenceScheduleCompleted.WaitOne();

            Console.WriteLine("Press anykey to exit.");
            Console.ReadLine();
        }

        static void conferenceEndScheduled(IAsyncResult ar)
        {
            try
            {
                ConferenceServices session = (ConferenceServices)ar.AsyncState;
                Conference conference = session.EndScheduleConference(ar);
                // 在控制檯輸出Lync會議的連結地址
                Console.WriteLine(conference.WebUrl);
            }
            catch
            {
                throw;
            }
            finally
            {
                conferenceScheduleCompleted.Set();
            }
        }

        static void endpointEndEstablish(IAsyncResult ar)
        {
            try
            {
                UserEndpoint endpoint = ar.AsyncState as UserEndpoint;
                endpoint.EndEstablish(ar);
            }
            catch
            {
                throw;
            }
            finally
            {
                endpointInitCompleted.Set();
            }
        }

        static void platformEndStartup(IAsyncResult ar)
        {
            try
            {
                CollaborationPlatform collabPlatform = ar.AsyncState as CollaborationPlatform;
                collabPlatform.EndStartup(ar);
            }
            catch
            {
                throw;
            }
            finally
            {
                platformStartupCompleted.Set();
            }
        }
    }
}

執行效果

以下是本程式執行的結果,可以看到,程式已經可以在控制檯輸出會議連結地址了:

image

相關文章