Tropo is part of CiscoLearn More

Creating a Chat Room Interface using Multiple Conferences

Posted on February 20, 2012 by kbond

In this blog, I will demonstrate how to turn multiple conferences into a chat room interface, including a full option menu . A great perk to this app is the ability to monitor everyone in the room using CouchDB – with CouchDB, you can see how many people are in each room, along with their corresponding callerIDs. There are several different CouchDBs that you can use, however for this blog I will use iris.

To start, set up an instance of CouchDB by initially going here. Once on that page, fill in the “Sign Up” fields on the right side of the page and hit “SEND”. You will then be directed to the page where you can access your CouchDB; it looks something like this:

To finish setting up CouchDB, first click the link you received from the confirmation; once there, click “Create Database” towards the top – you can name your database whatever you want, however, to follow the app’s design, I named mine conferences.

Now that the database is created, you need to make a “New Document”. When you click “New Document”, there should only be one field in it – _id, which will be the name of the document. I named this document “count”; our conferencing app will be looking for that name later, so keep whatever you name it in mind for later. To add new fields, click “Add Field”. Below are all the fields that you should have:

_id = count

body={
"1": {
"count": "0",
"people": [ ]
},
"2": {
"count": "0",
"people": [ ]
},
"3": {
"count": "0",
"people": []
},
"4": {
"count": "0",
"people": []
},
"5": {
"count": "0",
"people": []
},
"6": {
"count": "0",
"people": []
},
"7": {
"count": "0",
"people": []
},
"8": {
"count": "0",
"people": []
},
"9": {
"count": "0",
"people": []
}
}

Once this is filled out, save it and your final product should look something like this (don’t worry about making the _rev field, it will generate automatically):

Your CouchDB database is now set up. We can now start looking through the application code that will use this database, along with Tropo, to create and track multiple conferences. The first thing to do, as always, is import the libraries that we need.

require 'rubygems'
require 'net/http'
require 'json'

The next bit of code is a class that was made for accessing CouchDB. This class just makes HTTP requests to update or retrieve information from our CouchDB.

module Couch
class Server
def initialize(host, port, options = nil)
@host = host
@port = port
@options = options
end
def delete(uri)
request(Net::HTTP::Delete.new(uri))
end
def get(uri)
request(Net::HTTP::Get.new(uri))
end

def put(uri, json)
req = Net::HTTP::Put.new(uri)
req["content-type"] = "application/json"
req.body = json
request(req)
end
def request(req)
res = Net::HTTP.start(@host, @port) { |http|http.request(req) }
unless res.kind_of?(Net::HTTPSuccess)
handle_error(req, res)
end
res
end

private
def handle_error(req, res)
e = RuntimeError.new("#{res.code}:#{res.message}nMETHOD:#{req.method}nURI:#{req.path}n#{res.body}")
raise e
end
end
end

Now that we have our class ready to go, we can start using it. Since we will access the database multiple times during this call, we will make three methods that will make our life super easy. The first method relays each of the conference room names and lets the user choose which one they would like to join:

def determineRoom(conferenceRooms, looking)
say"Press the number according to the room you want to enter or zero to exit"
incr = 1
conferenceRooms.each { |x|
askRoom = ask "Press #{incr} for #{x}", {
:choices => "[1 DIGIT]",
:timeout => 2,
:mode => "dtmf",
:interdigitTimeout => 5 ,
:onChoice => lambda { |event|
say "Thank you! You choice was accepted"
$choice = event.value
looking = "2"
},
:onHangup => lambda { |event|
$choice = "0"
looking = "2"
}
}
break if looking == "2"
incr += 1
}
if looking == "1"
say"You did not specify a room, please try again."
determineRoom(conferenceRooms, looking)
end

return  $choice
end

This next method will retrieve all of the information in our database and parse it into JSON for use:

def getCounchDBData
url = URI.parse("http://couchgoodness.iriscouch.com/_utils/")
server = Couch::Server.new(url.host, url.port)
res = server.get("/conferences/count")
json = res.body
json = JSON.parse(json)
end

Finally, the last method updates the information in your database. Since we’re using CouchDB to keep track of how many people are in each conference, this method will either add or subtract 1 to the corresponding conference.

def updateCouchDBData(roomNum, method, callerID)
json = getCounchDBData
url = URI.parse("http://couchgoodness.iriscouch.com/_utils/")

server = Couch::Server.new(url.host, url.port)
server.delete("/conferences")
server.put("/conferences", "")
avail = json["body"]

if method == "add"
avail["#{roomNum}"]["count"] = (avail["#{roomNum}"]["count"].to_i + 1).to_s
avail["#{roomNum}"]["people"][avail["#{roomNum}"]["people"].length] = "#{callerID}"
else
avail["#{roomNum}"]["count"] = (avail["#{roomNum}"]["count"].to_i - 1).to_s
incr = 0
newPeople = []

avail["#{roomNum}"]["people"].each do |x|
if x != callerID
newPeople[incr]="#{x}"
incr = incr + 1
end
end
avail["#{roomNum}"]["people"] = newPeople
end

doc = <<-JSON
{"type":"comment","body": #{avail.to_json}}
JSON

server.put("/conferences/count", doc.strip)
end

Now that we have our helper methods setup, it’s time to start the actual app. To begin, we need to prompt the user for the room they want to enter. Since that method already exists, all we need to do is call that method. It takes an array, which will be the conference room names, and a variable to oversee user input (to reset this variable, set it to “1”). This method will return the room number the user entered, which is used as the conference ID. In our database, we need to update two things: the room number and the an array of callerIDs. In order to handle both, we also need to extract the callerID:

#Different rooms available
conferenceRooms = ["conference 1", "conference 2", "conference 3", "conference 4", "conference 5", "conference 6", "conference 7", "conference 8", "conference 9"]

#Determining which room to start with
room = determineRoom(conferenceRooms, "1")

#set the room number to an integer for the conference ID
room = room.to_i

#Resetting the loop variable that will be used shortly
$choice = 1

#Extracting the callerID
callerID = $currentCall.callerID

Next is the main “while” loop, which allows the user to enter and leave different rooms. This loop will exit when the user presses zero or hangs up. Below is the full code with comments to explain what’s happening:

#This loop will be active until the user wants to leave all conferences
while $choice != "0"

#Entering the specified conference
if $choice != "8"
#Promts the user which room they are entering and the options that they can choose from
say"Entering room #{conferenceRooms[room.to_i - 1]}. Press 9 to move to the next room, 6 to move to the previous room, 8 to hear how many people are in the room, 1 to hear the choices again or 0 to exit."

#Updates the CouchDB - takes the room number and goes to the function add and adds one person with their callerID
updateCouchDBData(room.to_i, "add", callerID)
end

#Setting the choice to 0 in case of a hangup
$choice = "0"

#Entering the conference using the room number as the conference ID
conference "#{room.to_i - 1}", {
:terminator => "6, 9, 0, 1, 8",
:mode => "dtmf",
:onChoice => lambda { |event|
#When the user hits eight, they want to stay in the room, but they want to know how many people are in the room
if event.value != "8"
say("leaving room")
end
#setting the choice variable to the key pressed
$choice = event.value
}
}

#Move to the next conference
if $choice == "9"

#This updates the database by subtracting 1 from the room count and removes the callerID
updateCouchDBData(room.to_i, "sub", callerID)

#Since the user is moving to the next room, set the conference ID to the next room
room = room.to_i + 1

#If the room number is greater than 9, set it back to the beginning
if room.to_i > 9
room = "1"
end

#Move to the previous conference
elsif $choice == "6"

#This updates the database by subtracting 1 from the room count and removes the callerID
updateCouchDBData(room.to_i, "sub", callerID)

#Since the user is moving to the previous room, set the conference ID to the room before
room = room.to_i - 1

#If the room number is less than 1, set it to the last conference ID
if room.to_i < 1
room = "9"
end

#Listing all of the conferences

elsif $choice == "1"

#Since this method will prompt the user which room they want to enter, they are no
#longer in their current conferenece so remove them
updateCouchDBData(room.to_i, "sub", callerID)

#Use the method determineRoom to prompt the user
room = determineRoom(conferenceRooms, "1")

#Set the conference ID
room = room.to_i

#Giving the number of people in that room
elsif $choice == "8"

json = getCounchDBData
count = json["body"]["#{room}"]["count"]
say "There is #{count} in the room."

#This means the person hungup, so delete him from that room
elsif $choice == "0"
updateCouchDBData(room.to_i, "sub", callerID)
end
end
say"Please come back soon!"

With that last bit of code, the app is complete. The only portion you would need/want to change in the code is the conference names; feel free to be creative! If you want to see the app in its entirety, go to github.com to view it.

Thank you for reading and have some fun!

One Response

  1. adult chatroom says:

    Terrific work! This is the type of information that are supposed to be shared across the net. Shame on Google for now not positioning this publish higher! Come on over and consult with my website . Thanks =)

Leave a Reply