diff --git a/go.mod b/go.mod
index 1265d1560029703faf08c229169e080652c215b2..84a6dcdba3ed3c61371bc2f7eb5105b8ce089786 100644
--- a/go.mod
+++ b/go.mod
@@ -1,5 +1,7 @@
 module owo.codes/whats-this/cdn-origin
 
+go 1.14
+
 require (
 	github.com/BurntSushi/toml v0.3.1 // indirect
 	github.com/lib/pq v1.0.0
diff --git a/main.go b/main.go
index 6be31a1342490c1463c0d1ce23389301d3965dc2..34b23dbac6cff38fe5dff30fd5a8213a97d234f7 100644
--- a/main.go
+++ b/main.go
@@ -6,9 +6,11 @@ import (
 	"fmt"
 	"html/template"
 	"io"
+	"mime"
 	"net"
 	"os"
 	"path/filepath"
+	"regexp"
 	"sort"
 	"strings"
 	"time"
@@ -27,8 +29,16 @@ import (
 
 // Build config
 const (
-	configLocationUnix = "/etc/whats-this/cdn-origin/config.toml"
-	version            = "0.7.0"
+	configLocation = "/etc/whats-this/cdn-origin/config.toml"
+	version        = "0.8.0"
+)
+
+const (
+	rawParam = "_raw"
+)
+
+var (
+	discordBotRegex = regexp.MustCompile("(?i)discordbot")
 )
 
 // readCloserBuffer is a *bytes.Buffer that implements io.ReadCloser.
@@ -50,6 +60,19 @@ var redirectHTMLTemplate *template.Template
 // redirectPreviewHTML is the html/template template for generating redirect preview HTML.
 const redirectPreviewHTML = `<html><head><meta charset="UTF-8" /><title>Redirect Preview</title></head><body><p>This link goes to <code>{{.}}</code>. If you would like to visit this link, click <a href="{{.}}">here</a> to go to the destination.</p></body></html>`
 
+// discordHTML is the html/template template for generating Discord-fixing HTML.
+const discordHTML = `<html>
+	<head>
+		<meta property="twitter:card" content="summary_large_image" />
+		<meta property="twitter:image" content="{{.}}" />
+		<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
+		<meta http-equiv="Pragma" content="no-cache" />
+		<meta http-equiv="Expires" content="0" />
+	</head>
+</html>`
+
+var discordHTMLTemplate *template.Template
+
 var redirectPreviewHTMLTemplate *template.Template
 
 // printConfiguration iterates through a configuration map[string]interface{}
@@ -77,8 +100,8 @@ func init() {
 	// Flag configuration
 	flags := pflag.NewFlagSet("whats-this-cdn-origin", pflag.ExitOnError)
 	flags.IntP("log-level", "l", 1, "Set zerolog logging level (5=panic, 4=fatal, 3=error, 2=warn, 1=info, 0=debug)")
-	configFile := flags.StringP("config-file", "c", configLocationUnix,
-		fmt.Sprintf("Path to configuration file, defaults to %s", configLocationUnix))
+	configFile := flags.StringP("config-file", "c", configLocation,
+		fmt.Sprintf("Path to configuration file, defaults to %s", configLocation))
 	printConfig := flags.BoolP("print-config", "p", false, "Prints configuration and exits")
 	flags.Parse(os.Args)
 
@@ -120,7 +143,7 @@ func init() {
 
 	// Print configuration variables in alphabetical order
 	if *printConfig {
-		log.Info().Msg("Printing configuration values to Stdout")
+		log.Info().Msg("Printing configuration values to stdout")
 		settings := viper.AllSettings()
 		printConfiguration("", settings)
 		os.Exit(0)
@@ -159,6 +182,10 @@ func init() {
 	if err != nil {
 		log.Fatal().Err(err).Msg("failed to parse redirectPreviewHTML template")
 	}
+	discordHTMLTemplate, err = template.New("discordHTML").Parse(discordHTML)
+	if err != nil {
+		log.Fatal().Err(err).Msg("failed to parse discordHTML template")
+	}
 }
 
 var collector *metrics.Collector
@@ -297,6 +324,11 @@ func requestHandler(ctx *fasthttp.RequestCtx) {
 	switch object.ObjectType {
 	case 0: // file
 		ctx.SetUserValue("object_type", "file")
+		if object.SHA256Hash == nil {
+			log.Warn().Str("key", key).Msg("encountered file object with NULL sha256_hash")
+			internalServerError(ctx)
+			return
+		}
 		fPath := filepath.Join(viper.GetString("files.storageLocation"), *object.SHA256Hash)
 		ifNoneMatch := string(ctx.Request.Header.Peek("If-None-Match"))
 		if len(ifNoneMatch) > 2 {
@@ -320,6 +352,7 @@ func requestHandler(ctx *fasthttp.RequestCtx) {
 			}
 
 			// Get thumbnail
+			// TODO: refactor this
 			var thumb io.ReadCloser
 			if viper.GetBool("thumbnails.cacheEnable") {
 				thumb, err = thumbnailCache.GetThumbnail(thumbnailKey)
@@ -396,10 +429,50 @@ func requestHandler(ctx *fasthttp.RequestCtx) {
 				log.Warn().Err(err).Msg("failed to send thumbnail response")
 				ctx.Response.Header.Del("Content-Disposition")
 				internalServerError(ctx)
+				return
 			}
 			return
 		}
 
+		// Discord workaround. They're hiding direct image embeds, so we
+		// serve HTML pages with metadata showing the image.
+		if object.ContentType != nil && discordBotRegex.Match(ctx.Request.Header.UserAgent()) && !ctx.QueryArgs().Has(rawParam) {
+			typ, _, err := mime.ParseMediaType(*object.ContentType)
+			if err != nil {
+				log.Warn().Err(err).Msg("failed to parse content-type of file")
+				internalServerError(ctx)
+				return
+			}
+
+			if typ == "image/jpeg" || typ == "image/jpg" || typ == "image/png" || typ == "image/gif" {
+				var (
+					host = string(ctx.Request.Header.Peek("Host"))
+					// Assume anything Discord hits is HTTPS
+					// anyways.
+					scheme = "https"
+				)
+				if strings.Contains(host, "localhost:") {
+					scheme = "http"
+				}
+
+				url := fmt.Sprintf("%v://%s%s?%v=true", scheme, ctx.Request.Header.Peek("Host"), ctx.Path(), rawParam)
+
+				// Make it so CloudFlare won't cache it.
+				ctx.SetStatusCode(fasthttp.StatusOK)
+				ctx.Response.Header.SetContentType("text/html; charset=utf8")
+				ctx.Response.Header.Add("Cache-Control", "no-cache, no-store, must-revalidate")
+				ctx.Response.Header.Add("Pragma", "no-cache")
+				ctx.Response.Header.Add("Expires", "0")
+				err = discordHTMLTemplate.Execute(ctx, url)
+				if err != nil {
+					log.Warn().Err(err).Msg("failed to execute discord html template on discordbot connection")
+					internalServerError(ctx)
+					return
+				}
+				return
+			}
+		}
+
 		// Check for If-None-Match header
 		if ifNoneMatch == *object.SHA256Hash {
 			ctx.SetStatusCode(fasthttp.StatusNotModified)
@@ -432,7 +505,6 @@ func requestHandler(ctx *fasthttp.RequestCtx) {
 		} else {
 			err = redirectHTMLTemplate.Execute(ctx, object.DestURL)
 		}
-
 		if err != nil {
 			log.Warn().Err(err).
 				Str("dest_url", *object.DestURL).