diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,77 @@
+## Who let you in here?
+
+Relax! I'm here to make your life easier. Has your company ever
+switched to using [Slack](https://slack.com), and then you wanted to
+write silly Slack bots in Haskell as a way to learn Haskell?
+
+<sup>Really?<sup>Wow<sup>That was a pretty specific question.</sup></sup>
+
+Uh, do you want to be friends? Well let's talk about it later, because right now I have an example for you.
+
+## Show me an example!
+
+Here's a `/jpgto` bot. If you run this program and then tell Slack
+about your server (incoming hook and custom slash command) and then
+type `/jpgto diplomatico` in one of your channels, you'll get the
+image from [http://diplomatico.jpg.to](http://diplomatico.jpg.to). How, you say? _Screen scraping_.
+
+```haskell
+import Network.Linklater (say, slash,
+                          Command(..), Config(..), Icon(..), Message(..), User(..))
+
+urlParser :: Parser B.ByteString
+urlParser = p
+  where
+    p = garbage *> url
+    garbage = string "src=\"" <|> (P.take 1 *> garbage)
+    url = takeTill (== _quotedbl)
+
+urlFor :: Text -> IO Text
+urlFor search = do
+  r <- get (T.unpack $ F.format "http://{}.jpg.to/" [search])
+  (return . handle . parse urlParser . strictly) (r ^. responseBody)
+  where
+    strictly = B.concat . L.toChunks
+    handle (Fail i ctxs s) = error (show (i, ctxs, s))
+    handle (Partial f) = handle (f "")
+    handle (Done _ r) = toText r
+
+jpgto :: Maybe Command -> Application
+jpgto (Just (Command (User user) channel text)) req respond = do
+  url <- urlFor (maybe "spolsky" id text)
+  say (Message channel (response url) (EmojiIcon "gift")) config
+  (respond . responseLBS status200 headers) ""
+  where
+    response url = F.format "@{} {}" (user, url)
+    config = Config token "trello.slack.com"
+    headers = [("Content-Type", "text/plain")]
+
+main :: IO ()
+main = do
+  let port = 80
+  putStrLn (F.format "+ Listening on port {}" [port])
+  run port (slash jpgto)
+  return ()
+```
+
+For the full example (since this one is missing a ton of imports), see
+the `examples/` directory on GitHub.
+
+Now! `/jpgto corgi`:
+
+![jpgtobot in action](corgi.jpg)
+
+So easy. Much fast.
+
+## Features
+
+* Uses `Text` everywhere so you can send your slash commands crazy Unicode characters all day long.
+* Lovely documentation.
+* Battle-tested.
+
+
+## Contributors
+
+* [Hao Lian](https://hao.codes), author
+* [Ian Henry](https://ianthehenry.com), design review and _future contributor_???
+* *Shields* (the Grizzly Bear album), which I listened all the way through for the first time while I was writing this ★★★★
diff --git a/changelog b/changelog
new file mode 100644
--- /dev/null
+++ b/changelog
@@ -0,0 +1,9 @@
+-*- markdown -*-
+
+## 2014-07-23 1.0.0.3
+
+* Include extra source files in `.cabal`
+
+## 2014-07-23 1.0.0.2 (and 1.0.0.1)
+
+* Lower dependency constraints for GHC 7.6.x users
diff --git a/examples/JointPhotographicExpertsGroupTonga.hs b/examples/JointPhotographicExpertsGroupTonga.hs
new file mode 100644
--- /dev/null
+++ b/examples/JointPhotographicExpertsGroupTonga.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module JointPhotographicExpertsGroupTonga where
+
+import           Control.Applicative
+import           Control.Lens hiding ((.=))
+import           Control.Monad
+import           Data.Attoparsec.ByteString
+import qualified Data.Attoparsec.ByteString as P
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Lazy as L
+import qualified Data.Text.Format as F
+import           Data.Text.Lazy (Text)
+import qualified Data.Text.Lazy as T
+import           Data.Text.Lazy.Encoding (decodeUtf8)
+import           Data.Text.Lazy.IO
+import           Data.Word8
+import           Network.HTTP.Types (status200)
+import           Network.Linklater
+import           Network.Wai
+import           Network.Wai.Handler.Warp (run)
+import           Network.Wreq hiding (params, headers)
+import           Prelude hiding (readFile, writeFile, putStrLn)
+
+toText :: B.ByteString -> Text
+toText = decodeUtf8 . L.fromChunks . return
+
+token :: Text
+token = undefined
+
+urlParser :: Parser B.ByteString
+urlParser = p
+  where
+    p = garbage *> url
+    garbage = string "src=\"" <|> (P.take 1 *> garbage)
+    url = takeTill (== _quotedbl)
+
+urlFor :: Text -> IO Text
+urlFor search = do
+  r <- get (T.unpack $ F.format "http://{}.jpg.to/" [search])
+  (return . handle . parse urlParser . strictly) (r ^. responseBody)
+  where
+    strictly = B.concat . L.toChunks
+    handle (Fail i ctxs s) = error (show (i, ctxs, s))
+    handle (Partial f) = handle (f "")
+    handle (Done _ r) = toText r
+
+jpgto :: Maybe Command -> Application
+jpgto (Just (Command (User user) channel text)) req respond = do
+  url <- urlFor (maybe "spolsky" id text)
+  say (Message channel (response url) (EmojiIcon "gift")) config
+  (respond . responseLBS status200 headers) ""
+  where
+    response url = F.format "@{} {}" (user, url)
+    config = Config token "trello.slack.com"
+    headers = [("Content-Type", "text/plain")]
+
+main :: IO ()
+main = do
+  let port = 80
+  putStrLn (F.format "+ Listening on port {}" [port])
+  run port (slash jpgto)
+  return ()
diff --git a/linklater.cabal b/linklater.cabal
--- a/linklater.cabal
+++ b/linklater.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name: linklater
-version: 1.0.0.2
+version: 1.0.0.3
 synopsis: Write bots for your Slack account, and then go to sleep (because it's so easy and late at night)
 homepage: https://github.com/hlian/linklater
 license: BSD3
@@ -18,6 +18,11 @@
   A library for writing <https://slack.com/> Slack chat bots.
   .
   A mistake?
+
+extra-source-files:
+  examples/*.hs
+  README.md
+  changelog
 
 flag developer
   default: False
