Version 3, last updated by Jonathan Ferguson at May 30, 2010 UTC
Defined set of poll options
The first example considers a poll where the all options are known, for instance: "Will you vote in the next election?" There are two options, yes and no. It would be trivial to include an "unsure" option.
To set this up, first make sure you enable web hooks by clicking the "Enable developer mode" button on the left hand side of the Settings tab at Taykt.com. Next, register the options as text-in words, in this case, "yes" and "no" (and "unsure" if you want to). The message text should not be empty even though web hooks are being used: in the case that no response is received from the web hook, this message text will be sent instead. Finally enter the web hook URL, which for this example can behttp://taykt-demo.appspot.com/poll?name=election. Here's how that might look:

You repeat this set up for "No"
Now let's look at the code that's executed when the web hook is called.
class DefinedOptionsPollServlet extends PollTrait {
override def doPost(request:HttpServletRequest , response:HttpServletResponse ) {
val pollName = request.getParameter("name")
response.setContentType("text/plain")
response.setCharacterEncoding("utf-8")
if (null == pollName)
response.getWriter().println("No poll name provided, contact Poll organiser")
else {
pollOptionFromString(request.getParameter("text")) match {
case None => response.getWriter().println("You didn't say what you wanted to vote for!")
case Some(pollOption) =>
polls.get(pollName) match {
case None => polls += (pollName -> Map(pollOption -> 1)) // new poll
case Some(poll) => //existing poll
poll.get(pollOption) match {
case Some(value) => poll += (pollOption -> (value + 1)) // existing poll option
case None => poll += (pollOption -> 1) // new poll option
}
}
response.getWriter().println(sMSResponse(pollName, pollOption))
}
}
}
override def pollOptionFromString(raw:String):Option[String] = raw match {
case null => None
case option => Some(option.split(" ")(0))
}
}
What we're doing here is taking the name of the poll from the request parameter of name which you set when you associated the web hook to the URL. Next, we look at what word the person texted in, which we get from the text request parameter that Taykt sends to the web hook. With the basic information gathered, we look up the poll name in our hashmap. This will either give us a hashmap for the poll, which associates the option ("yes", "no") with the count so far, so we can increment the count; or it won't, in which case we create the poll and store it. Finally, we send back a response.
When someone texts-in, Taykt will POST the message to the web hook URL. A simulation of this would be as follows:
$ curl http://taykt-demo.appspot.com/poll?name=election -X POST -d text="yes" -d pid="abc123"
The response from Taykt would be:"You've voted for yes. It has 100% of the vote. Currently yes is in the lead." In this example we have also implemented HTTP GET, allowing you to see how the poll is going in your web browser.
trait PollTrait extends HttpServlet{
protected val polls = Map[String, Map[String, Int]]()
override def doGet(request:HttpServletRequest , response:HttpServletResponse ) = {
val pollName = request.getParameter("name")
response.setContentType("text/html")
if (null == pollName) {
response.getWriter().println(NO_POLL)
} else {
polls.get(pollName) match {
case Some(poll) =>
val table = poll.map { entry => "<tr><td>" + entry._1+ "</td><td>" + entry._2 + "</td></tr>" }.mkString
response.getWriter().println(
RESULTS_HTML.replaceAll("POLL_NAME",pollName).replaceAll("RESULTS_TABLE", table).replaceAll("CHART_URL",chartUrl(poll)))
case None =>
response.getWriter().println(NO_RESULTS_HTML.replaceAll("POLL_NAME",pollName))
}
}
}
def pollOptionFromString(raw:String ):String
def chartUrl(poll:Map[String, Int] ) = "http://chart.apis.google.com/chart?cht=p3&chs=500x250&chd=t:" + poll.values.toList.mkString(",") + "&chl=" + poll.keys.toList.mkString("|")
def sMSResponse(pollName:String , option:String ) = RESPONSE_TEXT.replace("{OPTION}", option).replace("{PERCENT}", percentage(polls(pollName), option)).replace("{LEADER}", leader(polls(pollName)))
def percentage(poll:Map[String, Int] , option:String) = { (poll(option) / total(poll).toDouble * 100).toString }
def total(poll:Map[String, Int] ):Int = { (0 /: poll) ( _ + _._2 ) }
def leader(poll:Map[String, Int] ) = poll.toList.sort( (_._2 >_._2) )(0)._1
val RESPONSE_TEXT = "You've voted for OPTION. It has PERCENT% of the vote. Currently LEADER is in the lead."
val NO_RESULTS_HTML = """<html>
<head>
<title>Poll results for POLL_NAME</title>
</head>
<body>
<p>No votes have been collected for the POLL_NAME poll yet.</p>
</body>
</html>"""
val RESULTS_HTML = """<html>
<head>
<title>Poll results for POLL_NAME</title>
</head>
<body>
<table>RESULTS_TABLE</table>
<img src="CHART_URL">
</bodyv
</html>"""
val NO_POLL = """<html>
<head>
<title>Poll results</title>
</head>
<body>
<p>You need to provide a poll name.</p>
</body>
</html>"""
}
To view how a poll is going, point your browser at http://taykt-demo.appspot.com/poll?name=pollname, so for the example above it would be http://taykt-demo.appspot.com/poll?name=election