Set Webex Meeting PMR PIN with Webex XML API

Don’t have time to develop this? Covene Control incorporates this feature, and many others; contact us for more info!

Host access to each WebEx user’s personal conference room is secured with a host PIN, and is easily accessible by the user within his or her own account settings. For most organizations this is a sufficient method of PIN management, but what if we need to access this PIN across a large number of users in the organization?

Recently a client had a requirement to initialize several thousand user host PINs, each to a 4 digit number. A manual process for setting the PIN for each user was not a viable option due to a large number of users, nor was there an existing user interface to do so.

How else can we access a user’s host PIN?

There are two API options available for interfacing with WebEx, but as of the time this article was written, only the WebEx XML API provides the ability to read and write the host PIN for a user’s personal conference room. This PIN can be set using the SetUser API call. 

Below is an example of the XML that would be used for a site named “acme” with a user “[email protected]” to set the host PIN to “3421”. The administrator credentials used are populated under “webExId” and “password” elements within the “securityContext” element.

Designing software to do the heavy lifting

Setting the host PIN for thousands of users, from both a time and cost perspective is a daunting task to have to do manually. Software, on the other hand, can do the job easily using WebEx XML API. We designed the software to read a spreadsheet of data containing two columns: The user’s WebExID (same as the email address in this case), and the desired host PIN for the user. The other information needed was the site name, and the credentials of an account with site administrative permissions. The application simply iterates over each row in the spreadsheet to get the email and the host PIN, then generates an XML document from this information and posts it to the API endpoint using the administrative credentials. 

<?xml version="1.0" encoding="UTF-8"?>
<serv:message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:serv="http://www.webex.com/schemas/2002/06/service" xsi:schemaLocation="http://www.webex.com/schemas/2002/06/service http://www.webex.com/schemas/2002/06/service/service.xsd">
  <header>
    <securityContext>
      <webExID>[email protected]</webExID>
      <password>p@ssw0rd</password>
      <siteName>acme</siteName>
      <returnAdditionalInfo>true</returnAdditionalInfo>
    </securityContext>
  </header>
  <body>
    <bodyContent xsi:type="java:com.webex.service.binding.user.SetUser">
      <webExId>[email protected]</webExId>
      <personalMeetingRoom>
        <hostPIN>3421</hostPIN>
      </personalMeetingRoom>
    </bodyContent>
  </body>
</serv:message>

Implementing the design

For our application we implemented a simple .Net application in written in C#, but there are many other languages that will get the job done. You just need a language with libraries that can send a HTTPS POST request with TLS 1.2 support.

Let’s break the problem down into its basic steps. Posting the XML requires a few simple steps:

  1. Generate the XML.
  2. Set the security protocol to support TLS 1.2.
  3. Create a new WebRequest object to the site endpoint.
  4. Set the method to “POST”.
  5. Set the content type to “application/x-www-form-urlencoded”.
  6. Write the XML to the stream.
  7. Get and read the reponse stream.

Below an example of what an implementation of these steps may look like in a standalone method. The method requires the site name, admin username and password, the WebExId for which the host PIN will be set, and the host PIN. The method returns the XML data returned by the API endpoint, which will indicate if the call was successful or the error that occurred.

public string SetUserPin(string siteName, string adminUserId, string adminPassword, string webExId, string pin)
{
    //1. Generate the XML
    StringBuilder sb = new StringBuilder();
    sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    sb.Append("<serv:message xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
sb.Append("xmlns:serv=\"http://www.webex.com/schemas/2002/06/service\" ");
sb.Append("xsi:schemaLocation=\"http://www.webex.com/schemas/2002/06/service ");
sb.Append("http://www.webex.com/schemas/2002/06/service/service.xsd\">");
    sb.Append("<header>");
    sb.Append("<securityContext>");
    sb.AppendFormat("<siteName>{0}</siteName>", siteName);
    sb.AppendFormat("<webExID>{0}</webExID>", adminUserId);
    sb.AppendFormat("<password>{0}</password>", adminPassword);
    sb.Append("<returnAdditionalInfo>true</returnAdditionalInfo>");
    sb.Append("</securityContext>");
    sb.Append("</header>");
    sb.Append("<body>");
    sb.Append("<bodyContent ");

    sb.Append("xsi:type=\"java:com.webex.service.binding.user.SetUser\">");
    sb.AppendFormat("<webExId>{0}</webExId>", webExId);
    sb.Append("<personalMeetingRoom>");
    sb.AppendFormat("<hostPIN>{0}</hostPIN>", pin);
    sb.Append("</personalMeetingRoom>");
    sb.Append("</bodyContent>");
    sb.Append("</body>");
    sb.Append("</serv:message>");
    string xml = sb.ToString();

    //2. Set the security protocol for TLS 1.2
    ServicePointManager.Expect100Continue = true;
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

    //3. Create a new web request object to the site endpoint
    WebRequest request = WebRequest.Create(
       "https://" + siteName + ".webex.com/WBXService/XMLService");

    //4. Set the method to "POST".
    request.Method = "POST";

    //5. Set the content type to "application/x-www-form-urlencoded".
            request.ContentType = "application/x-www-form-urlencoded";

    //6. Write the XML to the stream.

    //6a. Convert string to bytes.
    byte[] bytes = Encoding.UTF8.GetBytes(xml);

    //6b. Set the content length.
    request.ContentLength = bytes.Length;

    //6c. Write the bytes to the stream
    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(bytes, 0, bytes.Length);
        requestStream.Close();
    }
    string xmlResponse;

    //7. Get and read the reponse stream.
    using (WebResponse response = request.GetResponse())
    {
        using (Stream stream = response.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                xmlResponse = reader.ReadToEnd();
                reader.Close();
            }
            stream.Close();
        }
        response.Close();
    }
    //Return XML response from the server.
    //Indicate success/failure.
    return xmlResponse; 
}

Note that this code uses the Sytem.IO, the System.Net, and the System.Text namepaces, so be sure to add your usings and DLL references accordingly if you’re using this code.

Potential problems to consider

  • Be sure that the user credentials you use in the header is a site administrator. During testing I ran into a problem that even though I had full administrator permissions set on my account, I was unable to set the host PIN of other users using the API. Getting my user information from the GetUser API call revealed the siteAdmin element in the data was set to false. Fixing the problem required removing my user license, adding it back, disabling full permissions, then adding the full permissions back again.
  • Make sure your PINs are not too simple. The API will reject PINs that are all the same number or a sequence of numbers, so make sure you don’t use PINs such as 2222 or 3456.
  • I had encountered what appears to be a limit on the number of SetUser calls I could make to the API. After the 800th call, the API began returning the error: “Incorrect user or password”. Using the same credentials I was able to make other API calls, such as GetUser, but the SetUser call would consistently return the error once it had started. I have not determined the exact amount of time the error would persist, but it is somewhere between 3 and 20 hours. To complete the project with the customer a site administrator account was created for every 700 users and the work was completed in batches. I could not find any documentation of this limit so it may be something else; just be prepared to encounter this potential problem.

The WebEx XML API is an easy way to control your organization host PINs, but it has much more to offer. Check out Cisco’s Reference Guide to discover the list the full list of features.

Leave a Reply