Message Boards Message Boards

Wolfram Language Data Curator Through Twilio - Hackathon Project

Posted 8 years ago

Feel free to check out this project on Devpost! - WakeyWakey on Devpost


Hi, guys!

I attended Github's Open Source Hack hackathon this weekend and I built a service to accept information about what you want to know in a WebApp, and then curates custom text messages to be sent to your mobile phone through Twilio with that data you'd requested. It currently will return the latest tweet from someone you specify, the latest image and caption from your favorite subreddit, your current portfolio value given the ticker of the stock you own along with number of shares, and also the weather forecast for the day (of course).

I built this service entirely using Wolfram Language within Mathematica. The WakeyWakey service runs on a server I currently host that executes a function to send SMS messages with a user's curated data at set times throughout the day. It currently runs once per day in the morning at 8am to alert users of what's going on in their personal worlds that day.

To collect data of what a user wants to receive information about, I utilized Wolfram's Data Drop feature to create a Databin.

userData=CreateDatabin[]

To be the interface between the user and the Databin, I then created a webform using a CloudDeploy function wrapped around a FormFunction command. This allowed me to present a usable interaction window to a user so that they can in essence "sign up" for SMS alerts with curated data they request. This is shown below with functions to format this webform.

CloudDeploy[
 FormFunction[{{"phoneNumber", "Phone Number"} -> <|
     "Interpreter" -> "String", "Hint" -> "ex: 5556667788", 
     "Help" -> 
      "This phone number will be used to send SMS updates each \
morning about your personally tailored information."|>, \
{"weatherLocation", "Location"} -> <|"Interpreter" -> "Location", 
     "Hint" -> "San Francisco", 
     "Help" -> 
      "Type the location you'd like to receive weather updates for."|> \
, {"twitterUserHandle", "@"} -> <|"Interpreter" -> "String", 
     "Hint" -> "elonmusk", 
     "Help" -> 
      "Type the username of a Twitter user you'd like to receive \
morning updates about."|>, {"stocks", "Stock Tracking"} -> <|
     "Interpreter" -> "String", "Hint" -> "AAPL", 
     "Help" -> 
      "Type in the stock ticker symbol of a stock you'd like to \
track."|>, {"shareAmount", "Amount of Shares"} -> <|
     "Interpreter" -> "Number", "Hint" -> "32", 
     "Help" -> 
      "Type in the number of shares you own of the previous stock \
you'd like to track."|>,
   {"subreddit", "r/"} -> <|"Interpreter" -> "String", 
     "Hint" -> "pics", 
     "Help" -> 
      "Type in the name of the image based subreddit you'd like \
receive daily images from. (No gifs please! :D)"|>}, 
  DatabinAdd[
    userData, <|
     ToString[
       Length[Values[userData]] + 
        1] -> {#phoneNumber, #weatherLocation, #twitterUserHandle, \
#stocks, #shareAmount, #subreddit}|>] &, 
  AppearanceRules -> {"Title" ->*insert image file of WakeyWakey logo here*, "ItemLayout" -> "Horizontal"}, 
  FormTheme -> "Blue"]
 , Permissions -> "Public"]

This data is then stored in the Databin, userData for later access by the WakeyWakey backend. The format of an example entry in the Databin for a user is given below:

<|"1" -> {{"5551231234", GeoPosition[{37.2969, -121.819}], "vgr", 
    "VTSAX", 1, "pics"}}|>

Where the identifier for the entry is a single integer, and the entry is an array containing: phone number, location for requested weather data, handle of a twitter user the user would like to receive tweets from, stock ticker, number of shares of that stock, and the subreddit a user would like to receive pictures from respectively.

To curate data, I used API connectivity through the ServiceConnect functions to connect Twitter, Reddit, and Twilio. This allowed me to search for specific information regarding each website, such as tweets from a certain user, or the newest picture posted to a certain subreddit. Connecting Twilio allowed me to send SMS messages through my Twilio account containing the curated data I created.

reddit = ServiceConnect["Reddit"];
twitter = ServiceConnect["Twitter"];
twilio = ServiceConnect["Twilio"];

So that I could search for information for each registered user and not confuse or combine any data that a user did not request, I utilized a Do loop wrapped around all functions so that I could separate which data is processed when. The variable, currentRecipientInfo, allowed me to pass in one entry about a certain user, and then extract all relevant info about that user to run through my data curation function. This is shown below:

Do[
  currentRecipientInfo = 
   Values[Databin[userData, All, ToString[i]]][[1, 1]];
  recipientNumber = currentRecipientInfo[[1]];

  maxTemp = 
   ToString[
    WeatherForecastData[currentRecipientInfo[[2]], 
      DateObject[Tomorrow]]["MaxTemperature"]];
  minTemp = 
   ToString[
    WeatherForecastData[currentRecipientInfo[[2]], 
      DateObject[Tomorrow]]["MinTemperature"]];
  tweet = 
   twitter["TweetList", "Username" -> currentRecipientInfo[[3]]][[1, 
    2]];
  stockValue = 
   ToString[
    FinancialData[currentRecipientInfo[[4]]]*
     currentRecipientInfo[[5]]]; 
  posts = reddit["SubredditPosts", 
    "Subreddit" -> currentRecipientInfo[[6]]];
  topPic = posts["Posts"][4][6];
  topPicCaption = posts["Posts"][4][4];

  twilio["Send", {"To" -> recipientNumber, "From" -> "EXAMPLE PHONE NUMBER", 
    "Body" -> 
     "Good morning! I hope you have a wonderful day. Here's your \
update:"}];

  twilio["Send", {"To" -> recipientNumber, "From" -> "EXAMPLE PHONE NUMBER", 
    "Body" -> 
     "The latest pic from r/" <> currentRecipientInfo[[6]] <> 
      " reads: " <> topPicCaption, "MediaURL" -> topPic}];

  twilio["Send", {"To" -> recipientNumber, "From" -> "EXAMPLE PHONE NUMBER", 
    "Body" -> 
     "The high today is going to be " <> maxTemp <> 
      " while the low is going to be " <> minTemp <> "."}];

  twilio["Send", {"To" -> recipientNumber, "From" -> "EXAMPLE PHONE NUMBER", 
    "Body" -> 
     "Your current portfolio value today is $" <> stockValue <> 
      "."}];

  twilio["Send", {"To" -> recipientNumber, "From" -> "EXAMPLE PHONE NUMBER", 
    "Body" -> 
     "The latest tweet from @" <> currentRecipientInfo[[3]] <> 
      " reads: " <> tweet}];

  , {i, Length[Values[userData]]}]
 ]

Expanding upon this, I also included an option for a user to receive information about their stock portfolio, and current weather conditions for a location they initially requested. The stock portfolio information was a bit difficult to asses due to the fact that the main stock app I use, Robinhood, does not have a public API to utilize, so I requested which stock the user owned in the original webform and requested how many shares of that stock a user owned (currently limited to tracking one stock), and then ran simple math on the server to return a value of a user's current portfolio given the current value for that certain stock on a certain day.

stockValue = 
 ToString[FinancialData[currentRecipientInfo[[4]]]*
   currentRecipientInfo[[5]]]; posts = 
 reddit["SubredditPosts", "Subreddit" -> currentRecipientInfo[[6]]];

This service could be run on a home server to send out data to users daily, or at a set time interval using the RunScheduledTask function very easily. It could also be set up to run on a Raspberry Pi with Wolfram Language and be left on continuously.

I'm proud of the fact that I built a service that not only I can use, but others who wish to have curated news and data in their mornings can take advantage of. I originally built the service as a proof of concept within my own personal sphere of information, but I believe that data should be shared and information be made widely available. So I opened it for everyone :)

Feel free to check it out on Devpost! - WakeyWakey on Devpost

Attachments:
POSTED BY: Aaron Brzowski

enter image description here - you earned "Featured Contributor" badge, congratulations !

This is a great post and it has been selected for the curated Staff Picks group. Your profile is now distinguished by a "Featured Contributor" badge and displayed on the "Featured Contributor" board.

POSTED BY: Moderation Team
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract