Journally is a simple chatbot that allows users to keep track of their daily mood and activities with minimal effort. Due to the fact that my carrier does not support MMS messaging, so I chose a service build on SMS messaging. During the implementation of this chatbot, I coded using Ruby language in Sinatra environment with the application of various ruby gems, Twilio's API, cloud platform Heroku and Postgres Database. The goal of this project is for me to get familiar with API and interaction with the database.



A precedent product is Call Frank, a bot will call you at a time every day and record what you say, but it is not accepting new users now. Journally is designed for those who want to record something about their life but are not active enough to do it every day, so the chatbot could make journaling an interactive process that takes them only 2-3 minutes. The bot will send SMS to users through Twilio. Users’ responses will be stored in the database and users are allowed to retrieve records of journals from the cloud with an input of date or phrases. This application provides a convenient way for the users to take a note on their daily life, it is not for people who already have the habit of journaling but for people who want to start journaling, so minimal information is better in this case. It can also be used by some people who want to simply keep track of their mood as a method to observe mental health.



I started with researching memo mobile apps in the market and found one I liked the most, which requires minimal effort to write a journal every day. I then drew out a workflow map with a data diagram.


I then iterated on the code from MeBot project to build the interaction between Journally and users when recording a new journal. I then set a daily schedule on Heroku that can send a daily reminder to the users. After that, I built a database using two models in the data diagram - user and journal. Journals are linked to users with user_id. Each journal is created by adding a date, so whenever the user wants to add/update journal, the journal will be found by querying the created date, so s/he would not create duplicate journals, which is a mess.



1. Sign up

Users can sign up using two ways. One is from the website, and another is by sending "<name> <Mary>" to Journally. The user's name and the phone number will be stored in the database. Users are found by phone numbers, and I found out that the parameter FROM in twilio is in format +1xxxxxxxxxx, so I change the signup page accordingly. Also I added a new way to signup through SMS, which eliminated the step to enter phone numbers.


2. Record a journal

The user can start a journal after receive a reminder message. S/he needs to add "mood" "act" before the content and the content could be just a number from the list I provided or s/he can type anything, including text or emoji. 

Example of mood input
elsif body.start_with? "mood"  
    mood = body.gsub(/[^0-9]/, '')
    if mood.nil? || ""
      arr = [body]
      mood = arr.map{ |s| s.gsub("mood ", "").gsub(" "," ") }[0]
    recording = Journal.find_by(created_time: DateTime.now.to_date)
    recording.mood = mood
Click to Expand

The newly added journal is in the database.


3. Retrieve journals

With the implementation of Chronic gem, users can retrieve journals by entering "get today", "get yesterday", "get two days ago", etc. The demo video is as below.

elsif body.start_with? "get"
    arr = [body]
    date_string = arr.map{ |s| s.gsub("get ", "").gsub(" "," ") }[0]
    date = Chronic.parse(date_string).to_date
    recording = Journal.find_by(created_time: date)
    mood = recording.mood
    activity = recording.activity
    note = recording.note
    if recording.mood.to_i.between?(1, 5)
      moods = ["Wonderful😊", "Good🙂", "Meh😐", "Bad😞", "Awful😣"]
      mood_index = recording.mood.to_i
      mood = moods[mood_index-1]
    if recording.activity.to_i.between?(1, 10)
      activities = ["work/study💻", "relax☕️", "friends🤼‍♀️", "date💕", "sport🏋", "party🍻", "movies🎥", "reading📖", "gaming🎮", "travel✈️"]
      activity_index = recording.activity.to_i
      activity = activities[activity_index-1]
    message = "Mood: #{mood} \nActivity: #{activity} \nNote: #{note} \n#{date}"
Click to Expand


This is an interesting project and I think I've applied many skills I learned in this course. It was fun to build the bot by adding features one by one. I really like the gem and API libraries that make my life much easier. If I would further work on this project, I would probably add a weekly/month report feature that can send reports to users through email. A good API I found is Sendgrid but my free trial expired. Sample code I worked on is as below.

Github: https://github.com/daraghbyrne/onlineprototypes2018/tree/master/students/xiz2/finalproject

get "/email/:address" do  
  from = Email.new(email: 'xiz2@andrew.cmu.edu')
  to = Email.new(email: "#{params['address']}")
  subject = 'test'
  content = Content.new(type: 'text/plain', value: 'and easy to do anywhere, even with Ruby')
  mail = Mail.new(from, subject, to, content)

  sg = SendGrid::API.new(api_key: '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')
  response = sg.client.mail._('send').post(request_body: mail.to_json)
  puts response.status_code
  puts response.body
  puts response.headers
Click to Expand
Share this Project


49714 Programming for Online Prototypes

· 9 members

A hands on introduction to building online products and services through code




October 18th, 2018