In-flight messaging
I was on a Delta flight the other day, and I was thinking about how they offer
free messaging from your smartphone.
How do they limit the wifi? Maybe they have some basic filter that says “deny
everything except the urls for these 3 messaging apps”, which makes sense
conceptually.
What if we don’t want to pay for wifi and we still want to be able to browse the
web?
Tunneling through WhatsApp
If the wifi is letting WhatsApp messages through, what if we used WhatsApp as a
vehicle for the information we really care about? Much like we encapsulate the
rest of our networking objects in higher-level objects, we could encapsulate
web pages inside of WhatsApp messages.
We could start with a simple case, like Wikipedia. It’s mostly text-based, so
there should be no issue with sending images (which are blocked in the free
messaging over wifi). What if we built a basic service that allowed users to
query Wikipedia pages and read them over WhatsApp?
Maybe it looks something like this, where a user sends a message to a WhatsApp
number. If we hook that number into a WhatsApp automated backend (probably via
Twilio), we can have that backend parse the message, query Wikipedia, and send
the response.
There are two main components to this Wikipedia Over WhatsApp, or WoW
service:
- The parsing of the messages and making requests to Wikipedia
- The WhatsApp interface for sending/receiving messages
Requesting articles from Wikipedia
Wikipedia has a pretty approachable API
that allows you to do a few
things. We can keep our service very simple: let’s say the user has to send the
title of a Wikipedia article. If there’s an article that matches, we respond
with it. If there isn’t an article that matches, we can do a search for the
given text and return the top 10 articles.
A very basic Python version might look something like this:
import urllib.parse
import urllib.request
import json
# URL to query a page, format JSON, extract the text, and give us plain wiki text.
PAGE_WIKI_REQ_STRING = 'https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&list=&formatversion=2&exlimit=1&explaintext=1&exsectionformat=wiki&titles='
# URL to search for articles for a search term.
SEARCH_WIKI_REQ_STRING = 'https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&formatversion=2&srsearch='
# This is a simple function for getting articles from wikipedia
def get_wiki_page(page_name):
# Encode the article name and build the URL.
encoded_page_name = urllib.parse.quote(page_name.encode('utf8'))
page_req_url = PAGE_WIKI_REQ_STRING + encoded_page_name
page_result = urllib.request.urlopen(page_req_url)
result_body = page_result.read()
result_json = json.loads(result_body.decode('utf-8'))
# If it's an article, we should have gotten an 'extract', so we can send it.
# In our case, this will be the entire article.
query_result = result_json['query']['pages'][0]
if 'extract' in query_result and query_result['extract'] != '':
return query_result['extract']
else:
# If we don't have an article, we can instead search for articles for
# that term and return the top 10 results.
result_string = 'I didn't find a perfect match for ' +
page_name + ', but you can try one of the following:n'
# Try to search for it now.
search_req_url = SEARCH_WIKI_REQ_STRING + encoded_page_name
search_result = urllib.request.urlopen(search_req_url)
search_result_body = search_result.read()
search_result_json = json.loads(search_result_body.decode('utf-8'))
for result in search_result_json['query']['search']:
result_string += result['title'] + 'n'
return result_string
To test this, we could even throw it together for a quick CLI tool:
... code from above
def main():
while(True):
page_name = ''
whil