func sanitize(s string) string {
	if len(s) >= lenStartCommand {
		if s[:lenStartCommand] == startCommand {
			s = s[lenStartCommand:]
		}
	}
	if len(s) >= lenPunchCommand {
		if s[:lenPunchCommand] == punchCommand {
			s = s[lenPunchCommand:]
		}
	}
	if len(s) >= lenBotTag {
		if s[:lenBotTag] == botTag {
			s = s[lenBotTag:]
		}
	}
	return s
}
sanitize remove clutter like /start /punch or the bot name from the string s passed as input
package handler
import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
)
const punchCommand string = "/punch"
var lenPunchCommand int = len(punchCommand)
const startCommand string = "/start"
var lenStartCommand int = len(startCommand)
const botTag string = "@RapGeniusBot"
var lenBotTag int = len(botTag)
const telegramApiBaseUrl string = "https://api.telegram.org/bot"
const telegramApiSendMessage string = "/sendMessage"
const telegramTokenEnv string = "TELEGRAM_BOT_TOKEN"
var telegramApi string = telegramApiBaseUrl + os.Getenv(telegramTokenEnv) + telegramApiSendMessage
const rapLyricsApiEnv string = "RAPLYRICS_API"
var rapLyricsApi string = os.Getenv(rapLyricsApiEnv)
type Update struct {
	UpdateId int     `json:"update_id"`
	Message  Message `json:"message"`
}
func (u Update) String() string {
	return fmt.Sprintf("(update id: %d, message: %s)", u.UpdateId, u.Message)
}
type Message struct {
	Text     string   `json:"text"`
	Chat     Chat     `json:"chat"`
	Audio    Audio    `json:"audio"`
	Voice    Voice    `json:"voice"`
	Document Document `json:"document"`
}
func (m Message) String() string {
	return fmt.Sprintf("(text: %s, chat: %s, audio %s)", m.Text, m.Chat, m.Audio)
}
type Audio struct {
	FileId   string `json:"file_id"`
	Duration int    `json:"duration"`
}
func (a Audio) String() string {
	return fmt.Sprintf("(file id: %s, duration: %d)", a.FileId, a.Duration)
}
type Voice Audio
type Document struct {
	FileId   string `json:"file_id"`
	FileName string `json:"file_name"`
}
func (d Document) String() string {
	return fmt.Sprintf("(file id: %s, file name: %s)", d.FileId, d.FileName)
}
type Chat struct {
	Id int `json:"id"`
}
func (c Chat) String() string {
	return fmt.Sprintf("(id: %d)", c.Id)
}
type Lyric struct {
	Punch string `json:"output"`
}
func HandleTelegramWebHook(w http.ResponseWriter, r *http.Request) {
	var update, err = parseTelegramRequest(r)
	if err != nil {
		log.Printf("error parsing update, %s", err.Error())
		return
	}
	var sanitizedSeed = sanitize(update.Message.Text)
	var lyric, errRapLyrics = getPunchline(sanitizedSeed)
	if errRapLyrics != nil {
		log.Printf("got error when calling RapLyrics API %s", errRapLyrics.Error())
		return
	}
	var telegramResponseBody, errTelegram = sendTextToTelegramChat(update.Message.Chat.Id, lyric)
	if errTelegram != nil {
		log.Printf("got error %s from telegram, response body is %s", errTelegram.Error(), telegramResponseBody)
	} else {
		log.Printf("punchline %s successfully distributed to chat id %d", lyric, update.Message.Chat.Id)
	}
}
func parseTelegramRequest(r *http.Request) (*Update, error) {
	var update Update
	if err := json.NewDecoder(r.Body).Decode(&update); err != nil {
		log.Printf("could not decode incoming update %s", err.Error())
		return nil, err
	}
	if update.UpdateId == 0 {
		log.Printf("invalid update id, got update id = 0")
		return nil, errors.New("invalid update id of 0 indicates failure to parse incoming update")
	}
	return &update, nil
}