diff --git a/config.go b/config.go
index e252e848d9961e155daec5001c9c7aaef50a9bc8..f099886dd0f21cf731c494247089b51056846592 100644
--- a/config.go
+++ b/config.go
@@ -41,9 +41,10 @@ type telegramConf struct {
 }
 
 type discordConf struct {
-	Token       string
-	NameFormat  string
-	StickerText bool
+	Token             string
+	NameFormat        string
+	StickerText       bool
+	NoMentionEveryone bool
 }
 
 type bridgeConf struct {
@@ -114,9 +115,10 @@ var defConf = conf{
 		BypassBacklog: true,
 	},
 	Discord: discordConf{
-		Token:       "INSERT_TOKEN_HERE",
-		NameFormat:  "$USER#$DISCRIMINATOR",
-		StickerText: true,
+		Token:             "INSERT_TOKEN_HERE",
+		NameFormat:        "$USER#$DISCRIMINATOR",
+		StickerText:       true,
+		NoMentionEveryone: true,
 	},
 	Bridges: struct{ Item []bridgeConf }{Item: []bridgeConf{
 		{
diff --git a/discord.go b/discord.go
index bd6048ee2ce84c2e6b6b55ede8080bdd1c3d3d8c..b07bd70732c299df0c7837a41434bfd2420351a0 100644
--- a/discord.go
+++ b/discord.go
@@ -5,7 +5,10 @@ import (
 	"log"
 )
 
-var session *discordgo.Session
+var (
+	session     *discordgo.Session
+	application *discordgo.Application
+)
 
 func init() {
 	discordgo.Logger = func(msgL, _ int, format string, a ...interface{}) {
@@ -45,6 +48,13 @@ func openDiscord() {
 			session.State.User.Username, session.State.User.Discriminator, session.State.User.ID)
 	}
 
+	if app, err := session.Application("@me"); err != nil {
+		log.Fatalf("error getting application: %s", err)
+	} else {
+		log.Printf("fetched self discord application %s (%s)", app.Name, app.ID)
+		application = app
+	}
+
 	ready <- struct{}{}
 }
 
diff --git a/telegram.go b/telegram.go
index 53a9088dd629b0166046fac26241118491fb7b68..3a94de2afb898c1ce973895aae3ef05bc6b9246a 100644
--- a/telegram.go
+++ b/telegram.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"fmt"
 	"github.com/bwmarrin/discordgo"
 	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
 	"log"
@@ -102,7 +103,7 @@ func respondTelegram(update tgbotapi.Update) {
 				header, _ := makeHeader(update.EditedMessage, true)
 				content = header + content
 			}
-			if _, err := session.ChannelMessageEdit(reference.ChannelID, reference.MessageID, content); err != nil {
+			if _, err := session.ChannelMessageEdit(reference.ChannelID, reference.MessageID, escape(content)); err != nil {
 				msg := tgbotapi.NewMessage(update.EditedMessage.Chat.ID, "error relaying edit")
 				msg.ReplyToMessageID = update.EditedMessage.MessageID
 				log.Printf("error relaying edit of %v: %s", update.EditedMessage.MessageID, err)
@@ -126,19 +127,7 @@ func respondTelegram(update tgbotapi.Update) {
 	}
 
 	if update.Message.IsCommand() {
-		message := tgbotapi.NewMessage(update.Message.Chat.ID, "")
-		switch update.Message.Command() {
-		case "id":
-			message.Text = strconv.Itoa(int(update.Message.Chat.ID))
-		default:
-		}
-		if message.Text != "" {
-			message.ReplyToMessageID = update.Message.MessageID
-			if _, err := botAPI.Send(message); err != nil {
-				log.Printf("error responding to command %v, %s", update.Message.Chat.ID, err)
-			}
-			return
-		}
+		go telegramCommand(update)
 	}
 
 	var (
@@ -176,55 +165,45 @@ func respondTelegram(update tgbotapi.Update) {
 
 	header, has := makeHeader(update.Message, false)
 
-	if update.Message.Photo != nil && (len(*update.Message.Photo)/4) > 0 {
-		fids := ""
-		files := make([]*discordgo.File, len(*update.Message.Photo)/4)
+	if update.Message.Photo != nil {
+		var file *discordgo.File
 
 		p := *update.Message.Photo
-		for i := 0; i < len(files); i++ {
-			// FIXME: multiple images
-			info := p[((i+1)*4)-1]
-
-			var url string
-			if u, err := botAPI.GetFileDirectURL(info.FileID); err != nil {
-				msg := tgbotapi.NewMessage(update.Message.Chat.ID, "error getting URL")
-				msg.ReplyToMessageID = update.Message.MessageID
-				log.Printf("error getting URL of %s: %s", info.FileID, err)
-				_, _ = botAPI.Send(msg)
-				return
-			} else {
-				url = u
-			}
+		info := p[len(p)-1]
 
-			if resp, err := http.Get(url); err != nil {
-				msg := tgbotapi.NewMessage(update.Message.Chat.ID, "error getting file")
-				msg.ReplyToMessageID = update.Message.MessageID
-				log.Printf("error getting file %s: %s", info.FileID, err)
-				_, _ = botAPI.Send(msg)
-				return
-			} else {
-				files[i] = &discordgo.File{
-					Name:        "image.jpg",
-					ContentType: "image/jpeg",
-					Reader:      resp.Body,
-				}
-				//goland:noinspection GoDeferInLoop
-				defer func() {
-					if err = resp.Body.Close(); err != nil {
-						log.Printf("error closing request body: %s", err)
-					}
-				}()
-			}
+		var url string
+		if u, err := botAPI.GetFileDirectURL(info.FileID); err != nil {
+			msg := tgbotapi.NewMessage(update.Message.Chat.ID, "error getting URL")
+			msg.ReplyToMessageID = update.Message.MessageID
+			log.Printf("error getting URL of %s: %s", info.FileID, err)
+			_, _ = botAPI.Send(msg)
+			return
+		} else {
+			url = u
+		}
 
-			if i != 0 {
-				fids += ", "
+		if resp, err := http.Get(url); err != nil {
+			msg := tgbotapi.NewMessage(update.Message.Chat.ID, "error getting file")
+			msg.ReplyToMessageID = update.Message.MessageID
+			log.Printf("error getting file %s: %s", info.FileID, err)
+			_, _ = botAPI.Send(msg)
+			return
+		} else {
+			file = &discordgo.File{
+				Name:        "image.jpg",
+				ContentType: "image/jpeg",
+				Reader:      resp.Body,
 			}
-			fids += info.FileID
+			defer func() {
+				if err = resp.Body.Close(); err != nil {
+					log.Printf("error closing request body: %s", err)
+				}
+			}()
 		}
 
 		if message, err := session.ChannelMessageSendComplex(strconv.Itoa(dc.ID), &discordgo.MessageSend{
-			Content:   header + update.Message.Caption,
-			Files:     files,
+			Content:   escape(header + update.Message.Caption),
+			File:      file,
 			Reference: reference,
 		}); err != nil {
 			msg := tgbotapi.NewMessage(update.Message.Chat.ID, "error relaying message")
@@ -246,7 +225,7 @@ func respondTelegram(update tgbotapi.Update) {
 		hasHeader[update.Message.MessageID] = has
 
 		log.Printf("T%vM%v -> D%vM%s @%s (%v) [photo]: %s; caption: %s",
-			tc.ID, update.Message.MessageID, dc.ID, dMessageID, username, id, fids, update.Message.Caption)
+			tc.ID, update.Message.MessageID, dc.ID, dMessageID, username, id, info.FileID, update.Message.Caption)
 		return
 	}
 
@@ -288,7 +267,7 @@ func respondTelegram(update tgbotapi.Update) {
 		}
 
 		if message, err := session.ChannelMessageSendComplex(strconv.Itoa(dc.ID), &discordgo.MessageSend{
-			Content:   content,
+			Content:   escape(content),
 			File:      file,
 			Reference: reference,
 		}); err != nil {
@@ -322,7 +301,7 @@ func respondTelegram(update tgbotapi.Update) {
 		return
 	}
 
-	if message, err := session.ChannelMessageSendReply(strconv.Itoa(dc.ID), header+update.Message.Text, reference); err != nil {
+	if message, err := session.ChannelMessageSendReply(strconv.Itoa(dc.ID), escape(header+update.Message.Text), reference); err != nil {
 		msg := tgbotapi.NewMessage(update.Message.Chat.ID, "error relaying message")
 		msg.ReplyToMessageID = update.Message.MessageID
 		log.Printf("error relaying message %v: %s", update.Message.MessageID, err.Error())
@@ -359,3 +338,39 @@ func makeHeader(message *tgbotapi.Message, force bool) (string, bool) {
 	}
 	return "", false
 }
+
+func escape(str string) string {
+	if !config.Discord.NoMentionEveryone {
+		return str
+	}
+	return strings.ReplaceAll(strings.ReplaceAll(str,
+		"@everyone", "@\u200beveryone"),
+		"@here", "@\u200bhere")
+}
+
+func telegramCommand(update tgbotapi.Update) {
+	message := tgbotapi.NewMessage(update.Message.Chat.ID, "")
+	switch update.Message.Command() {
+	case "start":
+		if update.Message.Chat.ID == int64(update.Message.From.ID) {
+			message.ParseMode = "Markdown"
+			message.Text = "Thanks for using BridgeThing!\n" +
+				"To find the ID of a Telegram chat, use /id\n" +
+				"To get the invite URL, use /invite\n" +
+				"Have fun!"
+		}
+	case "id":
+		message.Text = strconv.Itoa(int(update.Message.Chat.ID))
+	case "invite":
+		message.DisableWebPagePreview = true
+		message.Text = fmt.Sprintf("https://discord.com/oauth2/authorize?client_id=%s&scope=bot&permissions=8192",
+			application.ID)
+	}
+	if message.Text != "" {
+		message.ReplyToMessageID = update.Message.MessageID
+		if _, err := botAPI.Send(message); err != nil {
+			log.Printf("error responding to command %v, %s", update.Message.Chat.ID, err)
+		}
+		return
+	}
+}