diff --git a/zulip_bots/setup.py b/zulip_bots/setup.py
index 2c7b8dc6..3026fbc6 100755
--- a/zulip_bots/setup.py
+++ b/zulip_bots/setup.py
@@ -52,6 +52,7 @@ setuptools_info = dict(
         'html2text',  # for bots/define
         'BeautifulSoup4',  # for bots/googlesearch
         'lxml',  # for bots/googlesearch
+        'requests'  # for bots/link_shortener
     ],
 )
 
diff --git a/zulip_bots/zulip_bots/bots/link_shortener/__init__.py b/zulip_bots/zulip_bots/bots/link_shortener/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/zulip_bots/zulip_bots/bots/link_shortener/doc.md b/zulip_bots/zulip_bots/bots/link_shortener/doc.md
new file mode 100644
index 00000000..0982157c
--- /dev/null
+++ b/zulip_bots/zulip_bots/bots/link_shortener/doc.md
@@ -0,0 +1,17 @@
+# Link Shortener Bot
+
+Link Shortener Bot is a Zulip bot that will shorten URLs ("links") in a
+conversation. It uses the [goo.gl URL shortener API] to shorten its links.
+
+Links can be anywhere in the message, for example,
+
+ > @**Link Shortener Bot** @**Joe Smith** See
+ > https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots
+ > for a list of all Zulip bots.
+
+and LS Bot would respond
+
+ > https://github.com/zulip/python-zulip-api/tree/master/zulip_bots/zulip_bots/bots:
+ > **https://goo.gl/NjLZZH**
+
+[goo.gl URL shortener API]: https://goo.gl
diff --git a/zulip_bots/zulip_bots/bots/link_shortener/fixtures/test_normal.json b/zulip_bots/zulip_bots/bots/link_shortener/fixtures/test_normal.json
new file mode 100644
index 00000000..9c1d87be
--- /dev/null
+++ b/zulip_bots/zulip_bots/bots/link_shortener/fixtures/test_normal.json
@@ -0,0 +1,19 @@
+{
+  "request": {
+    "api_url": "https://www.googleapis.com/urlshortener/v1/url",
+    "method": "POST",
+    "params": {
+      "key": "qwertyuiop"
+    },
+    "json": {
+      "longUrl": "https://www.github.com/zulip/zulip"
+    }
+  },
+  "response": {
+    "id": "https://goo.gl/6uoWKb"
+  },
+  "response-headers": {
+    "status": 200,
+    "content-type": "application/json; charset=utf-8"
+  }
+}
diff --git a/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.conf b/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.conf
new file mode 100644
index 00000000..c3bacb44
--- /dev/null
+++ b/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.conf
@@ -0,0 +1,2 @@
+[link_shortener]
+key = <your API key>
diff --git a/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.py b/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.py
new file mode 100644
index 00000000..04450b82
--- /dev/null
+++ b/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.py
@@ -0,0 +1,80 @@
+import re
+import requests
+
+class LinkShortenerHandler(object):
+    '''A Zulip bot that will shorten URLs ("links") in a conversation using the
+    goo.gl URL shortener.
+    '''
+
+    def usage(self):
+        return (
+            'Mention the link shortener bot in a conversation and then enter '
+            'any URLs you want to shorten in the body of the message. \n\n'
+            '`key` must be set in `link_shortener.conf`.')
+
+    def initialize(self, bot_handler):
+        self.config_info = bot_handler.get_config_info('link_shortener')
+
+    def handle_message(self, message, bot_handler):
+        REGEX_STR = (
+            '('
+            '(?:http|https):\/\/'  # This allows for the HTTP or HTTPS
+                                   # protocol.
+            '[^"<>#%\{\}|\\^~[\]` ]+'  # This allows for any character except
+                                       # for certain non-URL-safe ones.
+            ')'
+        )
+
+        content = message['content']
+
+        if content.strip() == 'help':
+            bot_handler.send_reply(
+                message,
+                (
+                    'Mention the link shortener bot in a conversation and '
+                    'then enter any URLs you want to shorten in the body of '
+                    'the message.'
+                )
+            )
+            return
+
+        link_matches = re.findall(REGEX_STR, content)
+
+        shortened_links = [self.shorten_link(link) for link in link_matches]
+        link_pairs = [
+            (link_match + ': ' + shortened_link)
+            for link_match, shortened_link
+            in zip(link_matches, shortened_links)
+            if shortened_link != ''
+        ]
+        final_response = '\n'.join(link_pairs)
+
+        if final_response == '':
+            bot_handler.send_reply(
+                message,
+                'No links found. Send "help" to see usage instructions.'
+            )
+            return
+
+        bot_handler.send_reply(message, final_response)
+
+    def shorten_link(self, long_url):
+        '''Shortens a link using goo.gl Link Shortener and returns it, or
+        returns an empty string if something goes wrong.
+
+        Parameters:
+            long_url (str): The original URL to shorten.
+        '''
+
+        body = {'longUrl': long_url}
+        params = {'key': self.config_info['key']}
+
+        request = requests.post(
+            'https://www.googleapis.com/urlshortener/v1/url',
+            json=body,
+            params=params
+        )
+
+        return request.json().get('id', '')
+
+handler_class = LinkShortenerHandler
diff --git a/zulip_bots/zulip_bots/bots/link_shortener/test_link_shortener.py b/zulip_bots/zulip_bots/bots/link_shortener/test_link_shortener.py
new file mode 100644
index 00000000..fcff3ba5
--- /dev/null
+++ b/zulip_bots/zulip_bots/bots/link_shortener/test_link_shortener.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+from zulip_bots.test_lib import BotTestCase
+
+class TestLinkShortenerBot(BotTestCase):
+    bot_name = "link_shortener"
+
+    def test_bot(self):
+        MESSAGE = 'Shorten https://www.github.com/zulip/zulip please.'
+        RESPONSE = 'https://www.github.com/zulip/zulip: https://goo.gl/6uoWKb'
+
+        with self.mock_config_info({'key': 'qwertyuiop'}), \
+                self.mock_http_conversation('test_normal'):
+            self.initialize_bot()
+
+            self.assert_bot_response(
+                message = {'content': MESSAGE},
+                response = {'content': RESPONSE},
+                expected_method='send_reply'
+            )
+
+    def test_bot_empty(self):
+        MESSAGE = 'Shorten nothing please.'
+        RESPONSE = 'No links found. Send "help" to see usage instructions.'
+
+        # No `mock_http_conversation` is necessary because the bot will
+        # recognize that no links are in the message and won't make any HTTP
+        # requests.
+        with self.mock_config_info({'key': 'qwertyuiop'}):
+            self.initialize_bot()
+
+            self.assert_bot_response(
+                message = {'content': MESSAGE},
+                response = {'content': RESPONSE},
+                expected_method='send_reply'
+            )
+
+    def test_bot_help(self):
+        MESSAGE = 'help'
+        RESPONSE = (
+            'Mention the link shortener bot in a conversation and then enter '
+            'any URLs you want to shorten in the body of the message.'
+        )
+
+        # No `mock_http_conversation` is necessary because the bot will
+        # recognize that the message is 'help' and won't make any HTTP
+        # requests.
+        with self.mock_config_info({'key': 'qwertyuiop'}):
+            self.initialize_bot()
+
+            self.assert_bot_response(
+                message = {'content': MESSAGE},
+                response = {'content': RESPONSE},
+                expected_method='send_reply'
+            )