SUMMARY OF REDIAL
In Redial class, we have explored diverse and huge possibilities with telephony technology and its potential interactions with other platforms, interfaces and technologies. For instance, Asterisk Gate Way with RUBY, database with RUBY, SMS with Twilio, call a physical object or vice versa by using Arduino and Arduino Ethernet shield, in addition, the interaction between you phone with processing and webpage by using Tinyphone applications. We also have learned some basic research about speech recognition and synthesis, and related applications like Google Voice...
SUMMARY OF MY PROJECT
ITP Secret Sharing is the project I was developing in Radial class for 14 weeks. Basically, this project is a SMS system that allows user share and randomly get stories from others in community. By saying "secret", it does not have to be secret or anything related to privacy at all, it could be a funny story, joke you have, or what you have seen and experienced that you think worth sharing. The goal is triggering offline communication and "gossip" to enhance the relationship and understanding within community.
How to make "out of date" technology fresh and fun, meanwhile keep functionality concern in mind and embedded them into my Redial project is the top concern about this project. I want to craft a universal user experience and make it as accessible as possible. What do people love? What do people have?
"What do users have? " is the first question I was asking myself. No matter what user has is a dumm phone, Andriod, Windows or Apple phone, they all can make a phone call, send a SMS. "What do users love?" They love talking to others. They love sharing. They (most of them) love or curious about gossiping. How about a secret sharing system on Mobile communications? I thought about using voice recording as the format of secrets, later I found out that maybe text message would be more interesting, intriguing and accessible. The biggest concern when I was designing this sharing platform was how to keep user activity at a high level and keep the quality of the content of my service -- secrets. Like the old saying, "Everything in this world comes with strings attached", for my project, the only way to get others' secrets is sharing your secret first. Share yours, I will give you back, that is it. However, that is not enough to avoid "cheating". In case any attempt to spam the database with "Hello" "How are you" that no-one-wants secrets, I have to come up with another mechanic to "behave" users.
Here comes the rating system. Basically, the rating system is a tree-like system as pic follows: each user has one or more secrets, each secret has 0 or more ratings. The quality of the secret will be judged by all the other users ( score as 1--5), and reflected as the average rating of each secret ( sum up all the rating then divide the number of ratings for each secret) and all the average ratings of secrets that user has contributed will affect this user's level as the average of average ratings.
DETAILS AND DIFFICULTIES
I was using Sinatra in Ruby, datamapper Ruby and twilio to build my project. This was my first time to get my hands dirty on these and I was facing a lot of difficulties and out of expectation moments.
The interactions for ITP Secret Sharing are as follows:
1. Users send their secret to the service number (on twilio)
2. Twilio will immediately send and save this SMS and its related information to database in defined tables
3. A random secret will be picked and send out from database to twilio, most importantly, with attached cookie ( so the twilio will know which random secret has been sent out, because each secret has a specific secret_id as the token of its identity in database)
4. The secret with attached cookie will send to this user from twilio, also another SMS will be sent too to kindly remind user send his/her rating back for that secret.
5 & 6. If the rating had been sent from user, twilio will know which secret this rating is for because it has cookie in it, so the the rating, as a number from 1--5 will be saved into database as one of the ratings for that specific secret.
The first problem I encountered is how to send two SMS in a chain to user on Twilio. Eventually, it's been solved with the help from Twilio group.
I have tried to write the RUBY script like this:
#return a random saved secret return_secret = SMS.first(:offset => rand(SMS.count)) twiml = Twilio::TwiML::Response.new do |r| r.Sms return_secret.body #send another message to remind user for rating # ask_rating = remind_rating # if ask_rating # twiml = Twilio::TwiML::Response.new do |r| # r.Sms ask_rating end twiml.text
and like this:
#return a random saved secret return_secret = SMS.first(:offset => rand(SMS.count)) twiml = Twilio::TwiML::Response.new do |r| r.Sms return_secret.body end # NEW you might be trying to reuse the same response (r) # send another message to remind user for rating ask_rating = remind_rating if ask_rating twiml2 = Twilio::TwiML::Response.new do |r| r.Sms ask_rating end end
However, the answer and example I got from twilio is like something like follows, which proved that I was assuming to much...
require 'rubygems' require 'twilio-ruby' require 'sinatra' get '/sms-quickstart' do twiml = Twilio::TwiML::Response.new do |r| r.Message "Hey Monkey. Thanks for the message!" r.Message "this is the 2nd message" end twiml.text end
The second issue I got is how to allow a table has many to one and many to many relationship with other tables in Datamapper. The example in Datamapper tutorial, which I think is not informative enough, and I've Googled out another one in Stackoverflow (link), which would be a perfect example for building a tree-like database system.
During this process, other minor problems includes: After associating them, it was not saving associated data types. The right way to do this showed as below: you should tell Ruby Sinatra to save these data like this...
#save this secret secret = Secret.create(:body => params['Body'], :created_at => Time.now) caller = Caller.first_or_create(:from => params['From']) caller.secrets << secret caller.save
Also, in order to convert rating number from "string" in SMS to "integer", then save them into database for next step using, I have to do something like this:
rating_from_sms = params['Body'].to_i # save the rating(text) as integer rating = Rating.create(:score => rating_from_sms) secret.ratings << rating secret.save
The third one which was the most tough problem I've met during this project is the "cookie" ( called session in my case). Like what I mentioned before, I need embedded cookie has "secret_id" in it into the randomly sent back secret, as a way to track the conversation to save the rating to that specific secret correctly.
For twilio, they do support cookie function, but with limitations (please check there website for more info). The example they provide could barely apply to my case. Basically, the idea is not complicated, just get "secret_id" data from database, save it into cookie, and send it within SMS.
In the first place, my code looks like this:
and the out come is confusing:
As you can see, the red frame is what I've got when I was testing it and sanding a single number "4" from a cellphone number which has never sent SMS to my number before, which means, there should be no any "session" information saved in it ( I did not send "secret" before I send the number, so it is suppose to run the "elsif" part...), however, clearly, from the information in terminal, it seems like it will automatically assign a "secret_id" as session to that conversation, no matter the upcoming SMS is a secret or not. Meanwhile, when the SMS' body is rating number, it will execute the "reply_message" (Thank you for rating message) in "if" statement... I felt confused because I put the session part in "else" statement, so if it's running the "if" part, why the session part in "else" part has been activated too? Moreover, the "elsif" has never been executed, because session is always there, no matter what happened, secret_id will always be assigned to the coming SMS, even no matter it is a rating SMS or secret SMS.
The logic in my code is whenever got a SMS from user, check it is a rating or a secret. If it is a rating, two possibilities: if it has session (session is true), or it does not (else session is false). I tried to add another if...else in if statement, it turned out to be not working. the error was the "session_id is undefined." which totally make sense. After struggling for some time, I thought is there anything like "try" in JAVA in RUBY? WOW, "try" is "begin...rescue" in RUBY, such a cool name, much more cooler than "try" I thought... so I tried it... and it's working...
After the tricky cookie issue, the problem I was facing to is get average ratings. After the cookie disaster, I feel like getting average ratings is just a snap. Basically, like the system I showed in the first pic, the story shared from the user will be reviewed by other users, all the ratings from users will affect this story's review (as the average number of all rating numbers), and all the stories' reviews will affect this user's level, which means the only way for user to get more juicier story from the server is he/she has to share more juicier story to others first.
This is a gamification mechanic that build for providing a more reliable and satisfied user experience. Like other design work I did before, I like the idea of crowdsourcing and social innovation, because I like the way that it values the presence and participation of people. In social innovation design thinking, designers believe that users are a group of intelligent and smart people who could bring and share their intelligence to the system and benefit from each other and benefit to the system/product to make the system more eco-friendly, reliable and sustainable. One of the feedback from ITP spring show was "How to classify the stories into different categories, is there any mechanic build for this back in the server?" My answer for this question is all the users is the mechanic and the only judger. Why some of us prefer ignoring the presence of human intelligence and chasing for artificial intelligence? I think it is because some of us believe that users are stupid, they need help, they need designers to do everything, they can not do anything... anyway, I am a little carried away here, but it is a question that is worthy to think about.
What I left...
For the rating system, it is not 100% done yet. Now, the users' level part is not working actually. Moreover, I have to make my system more informative, because for now, there's no way for user to get to know their status in the system. For instance, there is no port provided for user to send a specific command to get the level information back from server, which means they are "playing" this system blindly, which wouldn't be a good user experience in a long term :)
However, this would be a detailed work and demand a lot of time I think. However, I would like to know how to make it happen and how it will affect user experience.
One Thing was Unexpected...
On Dec. 17th, one of our best friends, ITPer, Justin Restauri passed away right before the start of the show at 1PM... This grievous news made everyone in sorrow. I could not concentrate on the show in the first place and I was thinking what could I do for him.
I ended up turning my project as a space for remembrance about Justin where everyone could share his/her private memory and receive others' by using my project.
It went surprisingly well, and many ITPers told me they love this project and they think it is really helpful for getting a better understanding about Justin and doing a group memoirs about passed people. Most importantly, they think the experience this project crafted and delivered is new and accurate.
Here is what I've got so far...
My completion of my project could not have been accomplished without the help from so many people. I cannot express enough thanks to Christopher Kairalla, teacher in Redial class, the best teacher ever!! Thank him for his great teaching, informative class notes and extraordinary helpful office hours! Also, I would like to thank my classmates who gave me a lot of critics and suggestions. Last but not least, thank you Justin, I felt like it was you that changed my mind and made me realize that I could apply my project in this way. It is important to me because I realize that I am developing my projects possess a constant idea.
I will keep working on this project and I hope I could have the rating system 100% done as soon as possible. I will keep updating the process. Please let me know if you have any suggestions and reflections. Thank you!!!