INPUT MY OUTPUT
RESEARCH & EXPERIMENTS
Category: Web

Rehuddle.com is a web application I built with Phil Groman that makes group calling as easy as individual calling. We built the web application in order to give small creative businesses the ability to setup conference calls without paying for enterprise level telephony systems. Our goal was to make conference rooms easier to create, easier to join, and easier to share.

Traditional conference rooms often come with frustrating user experiences where many callers can’t seem to get in, missed the invitation, or can’t seem to find the e-mail where the call details were provided. With Rehuddle, users are given several super simple ways to share: 1) click to automatically copy the call details to your clipboard 2) click to auto generate an e-mail with the call details 3) text message someone to join the room 4) share the room via facebook and 5) generate a call that places a caller directly in the room (no extension needed).

The site is built with Ruby, Asterisk, Javascript, Node.js, and MySQL. Each user that joins a “huddle” is provided an avatar based on the last four digits of their phone-number. This allows each user to be uniquely identified and understand who is on the call. The avatars are currently being generated using Node.js and Underscore.js. Node is being used to ping our mySQL server every second and pipe the results into a socket that the client can read by parsing JSON. Underscore.js is being used to compare the current list of callers with a previous list of callers. This allows the client to know which callers to add for each browser and which callers to remove. Each conference room also gets a unique URL. If a user creates a room called “Sony Meeting” – Rehuddle will auto generate a URL Rehuddle.com/sony-meeting where the call can live. This url generation is being done with Ruby utilizing Sinatra and Datamapper/MySQL. Within the room our copy to clipboard share feature is using a JQuery library called zClip. The SMS messages are being routed through a Twilio’s Ruby API, the Facebook share call-to-action is using the standard Facebook Developers share button, and the call generator is happening in Asterisk, but is routed through Flowroute through a SIP registry.

In future iterations Phil and I are looking to add document sharing features, editable name tags for each avatar, and potentially unique phone numbers for each room. We both feel that there’s a huge gap in the market for conference systems that are simple, easy to use, easy to share, and provide an informative and enjoyable web interface. We both look forward to more user testing to see where this product takes us. A big thank you goes to Chris Kairalla for teaching us Asterisk and helping us debug throughout the build!

My Ruby/Sinatra code is as noted below:

require 'sinatra'
 
#generates a call file that will connect to the arduino context
def gencallfile(numbertocall)
  time = (Time.now.to_f * 1000).to_i #current timestamp
  temp_dir = "/tmp/"
  callfile = "call_" + time.to_s + ".call"
  startcallfile = temp_dir + callfile
  end_dir = "/var/spool/asterisk/outgoing/"
  endcallfile = end_dir + callfile
  #write file to disk
  file = File.open(startcallfile,"w")
  file.puts("Channel: SIP/#{numbertocall}@flowroute\n")
  file.puts("MaxRetries: 1\n")
  file.puts("RetryTime: 60\n")
  file.puts("WaitTime: 30\n")
  file.puts("CallerID: Arduino <2122738466>\n")
  file.puts("Context: rtt233_arduinocall\n")
  file.puts("Extension: s\n")
  file.close
  #change file permission
  File.chmod(0777, startcallfile)
  FileUtils.chown(ENV['USER'],'asterisk',startcallfile)
  #move file to /var/spool/outgoing
  FileUtils.mv(startcallfile,endcallfile)
end
 
# Main route  - this is the form where we take the input
get '/' do
	call_number=params[:callnumber]
	if call_number
		gencallfile(call_number)
  		# params[:callnumber] will be used to generate a call file
  		# which will play back a message from the "Arduino".
  		"Called #{call_number}"
  else
  		"missing \"callnumber\" param"
  end
end
For my telephony class we experimented with creating a asterisk connection through an Arduino. I used sinatra/ruby to create a webpage on my server that generates a call file in my /var/spool/asterisk/outgoing directory. With asterisk installed on my rackspace ubuntu server – any file within my outgoing directory will automatically be routed for a call. I also signed up with ipKall for my inbound calls and FlowRoute for my outbound calls (which is being used in this example).

My Arduino code is noted below:

//state constants
#define HTTP_ACTIVE 10
#define HTTP_IDLE 20
#include <SPI.h>
#include <Ethernet.h>fa
 
//setup          70    A5    DA    00    85    70
byte mac[] = { 0x70, 0xA5, 0xDA, 0x00, 0x85, 0x70 };
IPAddress server (XXX,XXX,XXX,XX);  // my server
//client stuff
char httpCommand[] = "GET /~rtilton1/sinatra/arduinocall/?callnumber=19174365310 HTTP/1.0";
EthernetClient client;
byte httpState = HTTP_IDLE;
int httpDelay = 5000; //wait at least this long in millis before sending another request
unsigned long connectTime = 0;
 
//button stuff
const int buttonPin = 2;
int buttonState = 0;
 
void setup() {
    Serial.begin(9600);
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("ready.");
}
 
void loop() {
  //read input from server, if any.
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  //check button, only read if there are no active http connections and we're past minimum delay
  if (httpState == HTTP_IDLE && pastHttpDelay()) {
    buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH) {
      serverConnect();
    }
 
  }
  //close client if disconnected
  if (!client.connected() && httpState == HTTP_ACTIVE) {
    client.stop();
    httpState = HTTP_IDLE;
    Serial.println();
    Serial.println("disconnected.");
  }
}
 
boolean pastHttpDelay(){
  if ((millis() - connectTime) > httpDelay) {
    return true;
  }
  else {
    return false;
  }
}
 
void serverConnect(){
  Serial.println("connecting to stu.itp.nyu.edu");
  if (client.connect(server, 80)) {
    httpState = HTTP_ACTIVE;
    connectTime = millis(); //when did we connect?
    Serial.println("connected");
    client.println(httpCommand);
    client.println();
  }
  else {
    httpState = HTTP_IDLE;
    Serial.println("connection failed");
  }
}
The Voice of Tomorrow is a project inspired by the Face of tomorrow. It attempts to use the phone as a recording device in order to find the average male and female voice in the world. The unified voice alludes to where we currently stand as evolving humans.

For my redial midterm I created a website where this project can live. It uses asterisk to generate a call and bring a user through a dial plan where a MySQL database is communicated with through AGI, AJAX, and Ruby. Overall I’m happy with the way the project turned out and am excited to receive data to begin averaging the voices. Hopefully the results will prove to be interesting. Currently the site is hosted on the ITP server, but when it launches I plan to move it to voiceoftomorrow.com.

Today, Greg Borenstein gave us an introduction to Git and Github – both amazing and necessary tools within the development world. My GitHub account can be found here. The Git workflow is as follows:

  1. Do work
  2. Save changes (commit)
  3. Share changes (push)
  4. Get changes (pull)
  5. Experiment (branch)
  6. See changes (diff)
  7. Combine changes (merge)
  8. Undo changes (revert)



General commands that are important to know are:
pwd  #where you are
cd  #move to file directory
open .  #opens in finder
mkdir #create a folder
ls #list content within the folder you’re looking at
man [command] #view manual of a specified commans (ex. man ls)
:q  #quit if you’re in edit mode
ls -la #show hidden files
which git #shows where git is installed on your machine
open .git/config #opens git config file in that folder

Now onto the interesting stuff.  How do you create a git repository, add, commit, and save locally:
git init #make git repository in current location
git status #show status of modifications
git add . #add everything in this folder to be commited
git commit -m “[message]” #commit to repository – this will create a number called a sha
If you have changed the file since your last commit you can use the following to view the difference, commit or revert
git log #views repository logs for this folder
git diff [sha1]..[sha2] #shows what has changed within the file
git revert [sha] #reverts to specific repository date
git reset — hard #undos the last git commit
git checkout -b [name] #creates a name associated with updates
git checkout [name] #brings you to how the file last looked like with that associated name.  This is good in order to toggle between two peoples updates

Lastly, we learned how to push and pull our Git to a GitHub repository:
First – got to your Github.com account and create new repository.  This will give you the information needed to go to your terminal and do the following:
git remote add [git@github.com:[username]/[repositoryName].git] #links the folder you’re in to the github folder
git add .
git commit -m “note”
git push #pushes files to the repository
If you’re pulling someone elses repository down into a local file you would do the following:
git remote add [name] https://github.com/[name]/[repositoryName].git #add the remote directory
git pull [name] master #pulls the files from external account
git pull #this is to pull from your own account