Ok, so I've got BBB setup, I'm setting the voicebridge and webvoice settings; however, when i dial in to freeswitch it tells me that i'm the only one in the conference, the audio can't be heard through the computer bbb client, and it doesn't show a new user in the bbb client nor does it bind the audio to my existing user in the bbb conference. I've followed the instructions in the FAQ, but it didn't resolve the issue. Below I am listing my create.jsp, bbb_api.jsp,netstat and bbb-conf --check settings.
BigBlueButton Server 0.8-beta-4 (951)
Kernel version: 2.6.32-41-generic-pae
Distribution: Ubuntu 10.04.4 LTS (32-bit)
/var/www/bigbluebutton/client/conf/config.xml (bbb-client)
Port test (tunnel): 10.200.100.176
/etc/nginx/sites-available/bigbluebutton (nginx)
server name: 10.200.100.176
bbb-client dir: /var/www/bigbluebutton
/var/lib/tomcat6/webapps/bigbluebutton/WEB-INF/classes/bigbluebutton.properties (bbb-web)
bbb-web host: 10.200.100.176
/var/lib/tomcat6/webapps/demo/bbb_api_conf.jsp (API demos)
/usr/share/red5/webapps/bigbluebutton/WEB-INF/red5-web.xml (red5)
voice conference: FreeSWITCH
/usr/local/bigbluebutton/core/scripts/slides.yml (record and playback)
playback host: 10.200.100.176
** Potential problems described below **
# Error: The voice application failed to register with the sip server.
# Warning: The API demos are installed and accessible from:
# Use the API demos test your BigBlueButton setup. To remove
# sudo apt-get purge bbb-demo
<%@ page language="java" contentType="text/html; charset=UTF-8"
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<title>Create Your Own Meeting</title>
<script type="text/javascript"
src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/heartbeat.js"></script>
<%@ include file="bbb_api.jsp"%>
<%@ page import="java.util.regex.*"%>
if (request.getParameterMap().isEmpty()) {
// Assume we want to create a meeting
<%@ include file="demo_header.jsp"%>
<h2>Create Your Own Meeting</h2>
<FORM NAME="form1" METHOD="GET">
<table width=600 cellspacing="20" cellpadding="20"
style="border-collapse: collapse; border-right-color: rgb(136, 136, 136);"
<td width="50%">Create your own meeting.
<td width="50%">Step 1. Enter your name: <input type="text" autofocus required name="username1" /> <br />
<td width="50%">Step 2. Enter Admin password: <input type="text" autofocus required name="adminpass" /> <br />
<td width="50%">Step 3. Enter User password: <input type="text" autofocus required name="userpass" /> <br />
<INPUT TYPE=hidden NAME=action VALUE="create"> <br />
<input id="submit-button" type="submit" value="Create meeting" /></td>
// We could have asked the user for both their name and a meeting title, but we'll just use their name to create a title
// We'll use JQuery to dynamically update the button
$(document).ready(function(){
$("input[name='username1']").keyup(function() {
if ($("input[name='username1']").val() == "") {
$("#submit-button").attr('value',"Create meeting" );
$("#submit-button").attr('value',"Create " +$("input[name='username1']").val()+ "'s meeting" );
} else if (request.getParameter("action").equals("create")) {
// User has requested to create a meeting
Double number = Math.floor(Math.random()*90000) + 10000;
String number2 = number.toString();
String meeting = number2.substring(0,5);
String username = request.getParameter("username1");
String meetingID = meeting;
String voiceBridge = meeting;
String webVoice = meeting;
String moderatorPW = request.getParameter("adminpass");
String attendeePW = request.getParameter("userpass");
// This is the URL for to join the meeting as moderator
String joinURL = getJoinURL(username, meetingID, "false", "<br>Welcome to %%CONFNAME%%.<br><br>Please dial " + dialNumber + " to join via phone.<br><br>Use " + voiceBridge + " as the conference number.<br>", null, null, dialNumber, webVoice, moderatorPW, attendeePW, voiceBridge);
String url = BigBlueButtonURL.replace("bigbluebutton/","demo/");
String inviteURL = url + "create.jsp?action=invite&meetingID=" + URLEncoder.encode(meetingID, "UTF-8");
<table width="800" cellspacing="20" cellpadding="20"
style="border-collapse: collapse; border-right-color: rgb(136, 136, 136);"
<center><strong> <%=username%>'s meeting</strong> has been
Step 2. Invite others using the following <a href="<%=inviteURL%>">link</a> (shown below):
<form name="form2" method="POST">
<textarea cols="62" rows="5" name="myname" style="overflow: hidden">
<p />Step 3. Click the following link to start your meeting:
<center><a href="<%=joinURL%>">Start Meeting</a></center>
} else if (request.getParameter("action").equals("enter")) {
// The user is now attempting to joing the meeting
String meetingID = request.getParameter("meetingID");
String username = request.getParameter("username");
String password = request.getParameter("password");
String url = BigBlueButtonURL.replace("bigbluebutton/","demo/");
String enterURL = url + "create.jsp?action=join&username="
+ URLEncoder.encode(username, "UTF-8") + "&meetingID="
+ URLEncoder.encode(meetingID, "UTF-8") + "&password=" + URLEncoder.encode(password, "UTF-8");
if (isMeetingRunning(meetingID).equals("true")) {
// The meeting has started -- bring the user into the meeting.
<script type="text/javascript">
window.location = "<%=enterURL%>";
// The meeting has not yet started, so check until we get back the status that the meeting is running
String checkMeetingStatus = getURLisMeetingRunning(meetingID);
<script type="text/javascript">
$(document).ready(function(){
url: "<%=checkMeetingStatus%>",
// Not elegant, but works around a bug in IE8
var isMeetingRunning = ($("#HeartBeatDIV").text().search("true") > 0 );
window.location = "<%=enterURL%>";
<h2><strong><%=meetingID%></strong> has not yet started.</h2>
<table width=600 cellspacing="20" cellpadding="20"
style="border-collapse: collapse; border-right-color: rgb(136, 136, 136);"
<p>Now waiting for the moderator to start <strong><%=meetingID%></strong>.</p>
<p>(Your browser will automatically refresh and join the meeting
<td width="50%"><img src="polling.gif"></img></td>
} else if (request.getParameter("action").equals("invite")) {
// We have an invite to an active meeting. Ask the person for their name
String meetingID = request.getParameter("meetingID");
<FORM NAME="form3" METHOD="GET">
<table width=600 cellspacing="20" cellpadding="20"
style="border-collapse: collapse; border-right-color: rgb(136, 136, 136);"
<p />You have been invited to join<br />
<strong><%=meetingID%></strong>.
<td width="50%">Enter your name: <input type="text"
name="username" /> <br />
Enter password: <input type="text" name="password" /> <br />
<INPUT TYPE=hidden NAME=meetingID VALUE="<%=meetingID%>"> <INPUT
TYPE=hidden NAME=action VALUE="enter"> <br />
<input type="submit" value="Join" /></td>
} else if (request.getParameter("action").equals("join")) {
// We have an invite request to join an existing meeting and the meeting is running
// We don't need to pass a meeting descritpion as it's already been set by the first time
// the meeting was created.
String joinURL = getJoinURLViewer(request.getParameter("username"), request.getParameter("meetingID"), request.getParameter("password"));
if (joinURL.startsWith("http://")) {
<script language="javascript" type="text/javascript">
window.location.href="<%=joinURL%>";
Error: getJoinURL() failed
<%@ include file="demo_footer.jsp"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="javax.xml.transform.dom.DOMSource"%>
<%@page import="javax.xml.transform.stream.StreamResult"%>
<%@page import="javax.xml.transform.OutputKeys"%>
<%@page import="javax.xml.transform.TransformerFactory"%>
<%@page import="javax.xml.transform.Transformer"%>
<%@page import="org.w3c.dom.Element"%>
<%@page import="com.sun.org.apache.xerces.internal.dom.ChildNode"%>
<%@page import="org.w3c.dom.Node"%>
<%@page import="org.w3c.dom.NodeList"%>
<%@page import="java.util.*,java.io.*,java.net.*,javax.crypto.*,javax.xml.parsers.*,org.w3c.dom.Document,org.xml.sax.*" errorPage="error.jsp"%>
<%@ page import="org.apache.commons.codec.digest.*"%>
<%@ page import="java.io.*"%>
<%@ page import="java.nio.channels.FileChannel"%>
<%@ page import="org.apache.commons.lang.StringEscapeUtils"%>
<%@ include file="bbb_api_conf.jsp"%>
// Create a meeting with specific
// - xml (for pre-upload of slides)
public String createMeeting(String meetingID, String welcome, String moderatorPassword, String viewerPassword, Integer voiceBridge, String logoutURL) {
String base_url_create = BigBlueButtonURL + "api/create?";
String welcome_param = "";
String attendee_password_param = "&attendeePW=ap1";
String moderator_password_param = "&moderatorPW=mp1";
String voice_bridge_param = "";
String logoutURL_param = "";
if ((welcome != null) && !welcome.equals("")) {
welcome_param = "&welcome=" + urlEncode(welcome);
if ((moderatorPassword != null) && !moderatorPassword.equals("")) {
moderator_password_param = "&moderatorPW=" + urlEncode(moderatorPassword);
if ((viewerPassword != null) && !viewerPassword.equals("")) {
attendee_password_param = "&attendeePW=" + urlEncode(viewerPassword);
if ((voiceBridge != null) && voiceBridge > 0) {
voice_bridge_param = "&voiceBridge=" + urlEncode(voiceBridge.toString());
// No voice bridge number passed, so we'll generate a random one for this meeting
Random random = new Random();
Integer n = 70000 + random.nextInt(9999);
voice_bridge_param = "&voiceBridge=" + n;
if ((logoutURL != null) && !logoutURL.equals("")) {
logoutURL_param = "&logoutURL=" + urlEncode(logoutURL);
String create_parameters = "name=" + urlEncode(meetingID)
+ "&meetingID=" + urlEncode(meetingID) + welcome_param
+ attendee_password_param + moderator_password_param
+ voice_bridge_param + logoutURL_param;
// Attempt to create a meeting using meetingID
String xml = getURL(base_url_create + create_parameters
+ checksum("create" + create_parameters + salt));
if (doc.getElementsByTagName("returncode").item(0).getTextContent().trim().equals("SUCCESS")) {
+ doc.getElementsByTagName("messageKey").item(0).getTextContent().trim()
+ doc.getElementsByTagName("message").item(0).getTextContent()
// getJoinMeetingURL() -- get join meeting URL for both viewer and moderator
public String getJoinMeetingURL(String username, String meetingID, String password) {
String base_url_join = BigBlueButtonURL + "api/join?";
String join_parameters = "meetingID=" + urlEncode(meetingID)
+ "&fullName=" + urlEncode(username) + "&password="
return base_url_join + join_parameters + "&checksum="
+ checksum("join" + join_parameters + salt);
// Create a meeting and return a URL to join it as moderator. This is used for the API demos.
// - record ["true", "false"]
// - welcome message (null causes BigBlueButton to use the default welcome message
// - metadata (passed through when record="true"
// - xml (used for pre-upload of slides)_
// - valid join URL using the username
// Note this meeting will use username for meetingID
public String getJoinURL(String username, String meetingID, String record, String welcome, Map<String, String> metadata, String xml, String dialNumber, String webVoice, String moderatorPW, String attendeePW, String voiceBridge) {
String base_url_create = BigBlueButtonURL + "api/create?";
String base_url_join = BigBlueButtonURL + "api/join?";
String welcome_param = "";
if ((welcome != null) && !welcome.equals("")) {
welcome_param = "&welcome=" + urlEncode(welcome);
if ((xml != null) && !xml.equals("")) {
Random random = new Random();
String voiceBridge_param = "&voiceBridge=" + voiceBridge; // (70000 + random.nextInt(9999));
// When creating a meeting, the 'name' parameter is the name of the meeting (not to be confused with
// the username). For example, the name could be "Fred's meeting" and the meetingID could be "ID-1234312".
// While name and meetingID should be different, we'll keep them the same. Why? Because calling api/create?
// with a previously used meetingID will return same meetingToken (regardless if the meeting is running or not).
// This means the first person to call getJoinURL with meetingID="Demo Meeting" will actually create the
// meeting. Subsequent calls will return the same meetingToken and thus subsequent users will join the same
// Note: We're hard-coding the password for moderator and attendee (viewer) for purposes of demo.
String create_parameters = "name=" + urlEncode(meetingID)
+ "&meetingID=" + urlEncode(meetingID) + welcome_param + voiceBridge_param
+ "&attendeePW=" + attendeePW + "&moderatorPW=" + moderatorPW
+ "&record=" + record + getMetaData( metadata );
// Attempt to create a meeting using meetingID
String url = base_url_create + create_parameters
+ checksum("create" + create_parameters + salt);
doc = parseXml( postURL( url, xml_param ) );
if (doc.getElementsByTagName("returncode").item(0).getTextContent()
.trim().equals("SUCCESS")) {
// Looks good, now return a URL to join that meeting
String join_parameters = "meetingID=" + urlEncode(meetingID)
+ "&fullName=" + urlEncode(username) + "&password=" + moderatorPW;
return base_url_join + join_parameters + "&checksum="
+ checksum("join" + join_parameters + salt);
return doc.getElementsByTagName("messageKey").item(0).getTextContent()
+ doc.getElementsByTagName("message").item(0).getTextContent()
//Create a meeting and return a URL to join it as moderator
public String getJoinURLXML(String username, String meetingID, String welcome, String xml) {
String base_url_create = BigBlueButtonURL + "api/create?";
String base_url_join = BigBlueButtonURL + "api/join?";
String welcome_param = "";
Random random = new Random();
Integer voiceBridge = 70000 + random.nextInt(9999);
if ((welcome != null) && !welcome.equals("")) {
welcome_param = "&welcome=" + urlEncode(welcome);
if ((xml != null) && !xml.equals("")) {
String create_parameters = "name=" + urlEncode(meetingID)
+ "&meetingID=" + urlEncode(meetingID) + welcome_param
+ "&attendeePW=ap&moderatorPW=mp&voiceBridge=" + voiceBridge;
// Attempt to create a meeting using meetingID
String params = postURL(base_url_create + create_parameters
+ checksum("create" + create_parameters + salt), xml_param);
if (doc.getElementsByTagName("returncode").item(0).getTextContent()
.trim().equals("SUCCESS")) {
String join_parameters = "meetingID=" + urlEncode(meetingID)
+ "&fullName=" + urlEncode(username) + "&password=mp";
return base_url_join + join_parameters + "&checksum="
+ checksum("join" + join_parameters + salt);
return doc.getElementsByTagName("messageKey").item(0).getTextContent()
+ doc.getElementsByTagName("message").item(0).getTextContent()
// getJoinURLViewer() -- Get the URL to join a meeting as viewer
public String getJoinURLViewer(String username, String meetingID, String uPW) {
String base_url_join = BigBlueButtonURL + "api/join?";
String join_parameters = "meetingID=" + urlEncode(meetingID)
+ "&fullName=" + urlEncode(username) + "&password=" + urlEncode(uPW);
return base_url_join + join_parameters + "&checksum="
+ checksum("join" + join_parameters + salt);
// getURLisMeetingRunning() -- return a URL that the client can use to poll for whether the given meeting is running
public String getURLisMeetingRunning(String meetingID) {
String meetingParameters = "meetingID=" + urlEncode(meetingID);
return BigBlueButtonURL + "api/isMeetingRunning?" + meetingParameters
+ checksum("isMeetingRunning" + meetingParameters + salt);
// isMeetingRunning() -- check the BigBlueButton server to see if the meeting is running (i.e. there is someone in the meeting)
public String isMeetingRunning(String meetingID) {
doc = parseXml( getURL( getURLisMeetingRunning(meetingID) ));
if (doc.getElementsByTagName("returncode").item(0).getTextContent()
.trim().equals("SUCCESS")) {
return doc.getElementsByTagName("running").item(0).getTextContent()
+ doc.getElementsByTagName("messageKey").item(0)
+ doc.getElementsByTagName("message").item(0).getTextContent()
public String getMeetingInfoURL(String meetingID, String password) {
String meetingParameters = "meetingID=" + urlEncode(meetingID)
+ "&password=" + password;
return BigBlueButtonURL + "api/getMeetingInfo?" + meetingParameters
+ checksum("getMeetingInfo" + meetingParameters + salt);
public String getMeetingInfo(String meetingID, String password) {
return getURL( getMeetingInfoURL(meetingID, password));
e.printStackTrace(System.out);
public String getMeetingsURL() {
String meetingParameters = "random=" + new Random().nextInt(9999);
return BigBlueButtonURL + "api/getMeetings?" + meetingParameters
+ checksum("getMeetings" + meetingParameters + salt);
// Calls getMeetings to obtain the list of meetings, then calls getMeetingInfo for each meeting
// and concatenates the result.
public String getMeetings() {
Document doc = parseXml( getURL( getMeetingsURL() ));
// tags needed for parsing xml documents
final String startTag = "<meetings>";
final String endTag = "</meetings>";
final String startResponse = "<response>";
final String endResponse = "</response>";
// if the request succeeded, then calculate the checksum of each meeting and insert it into the document
NodeList meetingsList = doc.getElementsByTagName("meeting");
String newXMldocument = startTag;
for (int i = 0; i < meetingsList.getLength(); i++) {
Element meeting = (Element) meetingsList.item(i);
String meetingID = meeting.getElementsByTagName("meetingID").item(0).getTextContent();
String password = meeting.getElementsByTagName("moderatorPW").item(0).getTextContent();
String data = getURL( getMeetingInfoURL(meetingID, password) );
if (data.indexOf("<response>") != -1) {
int startIndex = data.indexOf(startResponse) + startTag.length();
int endIndex = data.indexOf(endResponse);
newXMldocument += "<meeting>" + data.substring(startIndex, endIndex) + "</meeting>";
newXMldocument += endTag;
e.printStackTrace(System.out);
public String getendMeetingURL(String meetingID, String moderatorPassword) {
String end_parameters = "meetingID=" + urlEncode(meetingID) + "&password="
+ urlEncode(moderatorPassword);
return BigBlueButtonURL + "api/end?" + end_parameters + "&checksum="
+ checksum("end" + end_parameters + salt);
public String endMeeting(String meetingID, String moderatorPassword) {
String xml = getURL(getendMeetingURL(meetingID, moderatorPassword));
if (doc.getElementsByTagName("returncode").item(0).getTextContent()
.trim().equals("SUCCESS")) {
+ doc.getElementsByTagName("messageKey").item(0)
+ doc.getElementsByTagName("message").item(0).getTextContent()
//////////////////////////////////////////////////////////////////////////////
// Added for BigBlueButton 0.8
//////////////////////////////////////////////////////////////////////////////
public String getRecordingsURL(String meetingID) {
String record_parameters = "meetingID=" + urlEncode(meetingID);
return BigBlueButtonURL + "api/getRecordings?" + record_parameters + "&checksum="
+ checksum("getRecordings" + record_parameters + salt);
public String getRecordings(String meetingID) {
//recordID,name,description,starttime,published,playback,length
String newXMLdoc = "<recordings>";
String url = getRecordingsURL(meetingID);
doc = parseXml( getURL(url) );
// if the request succeeded, then calculate the checksum of each meeting and insert it into the document
NodeList recordingList = doc.getElementsByTagName("recording");
for (int i = 0; i < recordingList.getLength(); i++) {
Element recording = (Element) recordingList.item(i);
if(recording.getElementsByTagName("recordID").getLength()>0){
String recordID = recording.getElementsByTagName("recordID").item(0).getTextContent();
String name = recording.getElementsByTagName("name").item(0).getTextContent();
NodeList metadata = recording.getElementsByTagName("metadata");
if(metadata.getLength()>0){
Element metadataElem = (Element) metadata.item(0);
if(metadataElem.getElementsByTagName("description").getLength() > 0){
description = metadataElem.getElementsByTagName("description").item(0).getTextContent();
String starttime = recording.getElementsByTagName("startTime").item(0).getTextContent();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Date resultdate = new Date(Long.parseLong(starttime));
starttime = sdf.format(resultdate);
String published = recording.getElementsByTagName("published").item(0).getTextContent();
NodeList formats = recording.getElementsByTagName("format");
for (int j = 0; j < formats.getLength(); j++){
Element format = (Element) formats.item(j);
String typeP = format.getElementsByTagName("type").item(0).getTextContent();
String urlP = format.getElementsByTagName("url").item(0).getTextContent();
String lengthP = format.getElementsByTagName("length").item(0).getTextContent();
playback += StringEscapeUtils.escapeXml("<a href='" + urlP + "'>" + typeP + "</a>");
if(typeP.equalsIgnoreCase("slides")){
newXMLdoc += "<recording>";
newXMLdoc += "<recordID>" + recordID + "</recordID>";
newXMLdoc += "<name><![CDATA[" + name + "]]></name>";
newXMLdoc += "<description><![CDATA[" + description + "]]></description>";
newXMLdoc += "<startTime>" + starttime + "</startTime>";
newXMLdoc += "<published>" + published + "</published>";
newXMLdoc += "<playback>" + playback + "</playback>";
newXMLdoc += "<length>" + length + "</length>";
newXMLdoc += "</recording>";
e.printStackTrace(System.out);
return "error: "+e.getMessage();
newXMLdoc += "</recordings>";
public String getPublishRecordingsURL(boolean publish, String recordID) {
String publish_parameters = "recordID=" + urlEncode(recordID)
return BigBlueButtonURL + "api/publishRecordings?" + publish_parameters + "&checksum="
+ checksum("publishRecordings" + publish_parameters + salt);
public String setPublishRecordings(boolean publish, String recordID){
return getURL( getPublishRecordingsURL(publish,recordID));
e.printStackTrace(System.out);
public String getDeleteRecordingsURL(String recordID) {
String delete_parameters = "recordID=" + urlEncode(recordID);
return BigBlueButtonURL + "api/deleteRecordings?" + delete_parameters + "&checksum="
+ checksum("deleteRecordings" + delete_parameters + salt);
public String deleteRecordings(String recordID){
return getURL( getDeleteRecordingsURL(recordID));
e.printStackTrace(System.out);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
public String getMetaData( Map<String, String> metadata ) {
String metadata_params = "";
for(String metakey : metadata.keySet()){
metadata_params = metadata_params + "&meta_" + urlEncode(metakey) + "=" + urlEncode(metadata.get(metakey));
// checksum() -- create a hash based on the shared salt (located in bbb_api_conf.jsp)
public static String checksum(String s) {
checksum = org.apache.commons.codec.digest.DigestUtils.shaHex(s);
// getURL() -- fetch a URL and return its contents as a String
public static String getURL(String url) {
StringBuffer response = null;
HttpURLConnection httpConnection = (HttpURLConnection) u
httpConnection.setUseCaches(false);
httpConnection.setDoOutput(true);
httpConnection.setRequestMethod("GET");
httpConnection.connect();
int responseCode = httpConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream input = httpConnection.getInputStream();
// Read server's response.
response = new StringBuffer();
Reader reader = new InputStreamReader(input, "UTF-8");
reader = new BufferedReader(reader);
char[] buffer = new char[1024];
for (int n = 0; n >= 0;) {
n = reader.read(buffer, 0, buffer.length);
response.append(buffer, 0, n);
httpConnection.disconnect();
return response.toString();
public static String postURL(String targetURL, String urlParameters)
HttpURLConnection connection = null;
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
connection.setRequestProperty("Content-Length", "" +
Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream ());
wr.writeBytes (urlParameters);
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
return response.toString();
// parseXml() -- return a DOM of the XML
public static Document parseXml(String xml)
throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory docFactory = DocumentBuilderFactory
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new InputSource(new StringReader(xml)));
// urlEncode() -- URL encode the string
public static String urlEncode(String s) {
return URLEncoder.encode(s, "UTF-8");
public String getMeetingsWithoutPasswords() {
Document doc = parseXml( getURL( getMeetingsURL() ));
// tags needed for parsing xml documents
final String startTag = "<meetings>";
final String endTag = "</meetings>";
final String startResponse = "<response>";
final String endResponse = "</response>";
// if the request succeeded, then calculate the checksum of each meeting and insert it into the document
NodeList meetingsList = doc.getElementsByTagName("meeting");
String newXMldocument = startTag;
for (int i = 0; i < meetingsList.getLength(); i++) {
Element meeting = (Element) meetingsList.item(i);
String meetingID = meeting.getElementsByTagName("meetingID").item(0).getTextContent();
String password = meeting.getElementsByTagName("moderatorPW").item(0).getTextContent();
String data = getURL( getMeetingInfoURL(meetingID, password) );
if (data.indexOf("<response>") != -1) {
data = removeTag(data, "<attendeePW>", "</attendeePW>");
data = removeTag(data, "<moderatorPW>", "</moderatorPW>");
int startIndex = data.indexOf(startResponse) + startResponse.length();
int endIndex = data.indexOf(endResponse);
newXMldocument += "<meeting>" + data.substring(startIndex, endIndex) + "</meeting>";
newXMldocument += endTag;
e.printStackTrace(System.out);
public static String removeTag(String data, String startTag, String endTag){
int startIndex = data.indexOf(startTag);
int endIndex = data.indexOf(endTag) + endTag.length();
String tagStr = data.substring(startIndex, endIndex);
return data.replace(tagStr,"");