handlers

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 31, 2022 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

* Copyright 2021 M1K * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright 2021 M1K * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright 2021 M1K * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright 2021 M1K * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright 2021 M1K * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright 2021 M1K * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright 2021 M1K * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright 2021 M1K * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright 2021 M1K * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

Index

Constants

View Source
const (
	TICKER   = "ticker"
	SCALE_PT = "scale_pt"
	EXIT_PT  = "exit_pt"
	DESC     = "desc"
	PRICE    = "pt"
	STOPLOSS = "stop"
	POI      = "poi"
	ENTRY    = "entry"

	COIN = "coin"

	EXPIRY   = "expiry"
	STRIKE   = "strike"
	CONTRACT = "contract"
)

Variables

View Source
var CommandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
	"alert": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		embed := getAlertEmbed(s, i.Interaction.ChannelID, i.Member.User.Mention(), i.ApplicationCommandData().Options...)
		log.Println("Calling alert...")
		if embed == nil {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("unable to create embed"))
			return
		}
		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: i.ApplicationCommandData().Options[0].StringValue() + " @everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Embeds: []*discordgo.MessageEmbed{embed},
			},
		})

		msg, _ := s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: "New General Alert! @everyone",
			AllowedMentions: &discordgo.MessageAllowedMentions{
				Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
			},
			Embeds: []*discordgo.MessageEmbed{embed},
		},
		)

		var ms *discordgo.MessageSend

		if msg == nil {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
			}
		} else {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Reference: msg.Reference(),
			}
		}

		msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)

		go func() {
			m := msg
			time.Sleep(time.Second * 10)
			s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
		}()
	},
	"tracker": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		log.Println("Calling tracker...")
		e := discord.EODEmbed(s, i.Interaction.GuildID)

		if e == nil {
			log.Println("Tracker nil")
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
		discord.EOD(s, i.Interaction.GuildID)
	},
	"nuke": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		d := db.InitDBConnection(i.Interaction.GuildID)
		log.Println("Calling nuke...")
		err := d.RmAll(i.Interaction.GuildID)

		if err != nil {
			discord.SendError(s, i.Interaction.ChannelID, err)
			return
		}
		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "***50,000 people used to live here...***",
			},
		})
	},
	"all": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "",
			},
		})
		log.Println("Calling all...")
		respStrs := all(s, i.Interaction.ChannelID, i.Interaction.GuildID)

		if len(respStrs) > 0 {
			s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
				Content: "See report below:",
			},
			)
		} else {
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
		}

		for _, str := range respStrs {
			s.ChannelMessageSend(i.Interaction.ChannelID, str)
		}
	},
	"refresh": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "",
			},
		})

		respStr := refresh(s, i.Interaction.ChannelID, i.Interaction.GuildID)
		log.Println("Calling refresh...")

		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: "***Refreshed the following from the Database...***\n" + respStr,
		},
		)
	},
	"s": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		log.Println("Calling stock...")
		var (
			ticker string
			s_pt   string
			e_pt   string
			desc   string
			poi    string
			expiry string
			stop   string
			entry  string
		)
		log.Println("Calling stock for " + ticker)
		argValMap := make(map[string]string)

		for _, v := range i.ApplicationCommandData().Options {
			argValMap[v.Name] = v.StringValue()
		}

		if v, ok := argValMap[TICKER]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("ticker not defined"))
			return
		} else {
			ticker = strings.ToUpper(v)
		}
		if v, ok := argValMap[SCALE_PT]; ok {
			s_pt = v
		}
		if v, ok := argValMap[EXIT_PT]; ok {
			e_pt = v
		}
		if v, ok := argValMap[DESC]; ok {
			desc = v
		}
		if v, ok := argValMap[POI]; ok {
			poi = v
		}
		if v, ok := argValMap[EXPIRY]; ok {
			expiry = v
		}
		if v, ok := argValMap[STOPLOSS]; ok {
			stop = v
		}
		if v, ok := argValMap[ENTRY]; ok {
			entry = v
		}

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "",
			},
		})

		channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)

		if channelType == -1 {
			log.Println(errors.New("invalid channel type"))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		msg, _ := s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{Content: "Thinking..."})
		var embed *discordgo.MessageEmbed
		var err error
		var starting float32

		if msg == nil {
			embed, starting, err = createStocksHandler(s, i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, s_pt, e_pt, expiry, entry, poi, stop, channelType, nil)
		} else {
			embed, starting, err = createStocksHandler(s, i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, s_pt, e_pt, expiry, entry, poi, stop, channelType, msg.Reference())
		}

		if err != nil {
			log.Println(fmt.Errorf("error creating createStockHandler: %w", err))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		msg, _ = s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: fmt.Sprintf("Stock %v @ $%.2f \n***%v***", ticker, starting, desc),
			AllowedMentions: &discordgo.MessageAllowedMentions{
				Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
			},
			Embeds: []*discordgo.MessageEmbed{embed},
			Components: []discordgo.MessageComponent{
				discordgo.ActionsRow{
					Components: []discordgo.MessageComponent{
						discordgo.SelectMenu{
							CustomID:    "opt_stock",
							MinValues:   0,
							MaxValues:   1,
							Placeholder: "Actions",
							Options: []discordgo.SelectMenuOption{
								{
									Label:       "Remove Alert",
									Description: "Removes this alert. Only the alerter can do this - will fail for anyone else.",
									Default:     false,
									Value:       "rm_" + ticker,
									Emoji: discordgo.ComponentEmoji{
										Name: "❌",
									},
								},
								{
									Label:       "Get Email alerts for this (this does nothing atm)",
									Description: "Recieve Email alerts.",
									Default:     false,
									Value:       "em_" + ticker,
									Emoji: discordgo.ComponentEmoji{
										Name: "📧",
									},
								},
							},
						},
					},
				},
			},
		},
		)
		componentMsgMap["s_"+ticker] = msg
		var ms *discordgo.MessageSend

		includeChart := true

		chart, err := graph.Get15MStocksChart(ticker)

		if err != nil {
			includeChart = false
		}

		file, err := os.Open(chart)
		if err != nil {
			includeChart = false
		}
		defer func() {
			file.Close()

			os.Remove(chart)
		}()

		if msg == nil {
			ms = &discordgo.MessageSend{
				Content: "BTO " + ticker + " @everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
			}

		} else {
			ms = &discordgo.MessageSend{
				Content: "BTO " + ticker + " @everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Reference: msg.Reference(),
			}
		}

		if includeChart {
			ms.Files = []*discordgo.File{
				{
					Name:        chart,
					ContentType: "image/png",
					Reader:      file,
				},
			}
			ms.Embeds = []*discordgo.MessageEmbed{
				{
					Image: &discordgo.MessageEmbedImage{
						URL: "attachment://" + chart,
					},
				},
			}
		}
		msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)

		go func() {
			m := msg
			time.Sleep(time.Second * 30)
			s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
		}()
	},
	"rms": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		log.Println("Calling rm-stock...")
		var (
			ticker string
			desc   string
		)
		log.Println("Calling rm-stock for " + ticker)
		argValMap := make(map[string]string)

		for _, v := range i.ApplicationCommandData().Options {
			argValMap[v.Name] = v.StringValue()
		}

		if v, ok := argValMap[TICKER]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("ticker not defined"))
			return
		} else {
			ticker = strings.ToUpper(v)
		}

		if v, ok := argValMap[DESC]; ok {
			desc = v
		}

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{},
		})

		channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)

		if channelType == -1 {
			log.Println(errors.New("invalid channel type"))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}
		var embed *discordgo.MessageEmbed

		embed, err := rmStocksCommandHandler(i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, desc, channelType)

		if err != nil {
			log.Println(fmt.Errorf("error creating rmStockHandler: %w", err))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		closing, _ := stonks.GetStock(ticker)

		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: fmt.Sprintf("Stock alert removed - **%v** @ $%.2f"+"@everyone", ticker, closing),
			AllowedMentions: &discordgo.MessageAllowedMentions{
				Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
			},
			Embeds: []*discordgo.MessageEmbed{embed},
		},
		)
		var msg *discordgo.Message
		if msg, ok := componentMsgMap["s_"+ticker]; ok {
			str := fmt.Sprintf("This alert has been deleted - closed @ $%.2f", closing)
			s.ChannelMessageEditComplex(&discordgo.MessageEdit{
				Content:    &str,
				Components: []discordgo.MessageComponent{},
				ID:         msg.ID,
				Channel:    msg.ChannelID,
			})

			delete(componentMsgMap, "s_"+ticker)
		}

		var ms *discordgo.MessageSend

		if msg == nil {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
			}
		} else {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Reference: msg.Reference(),
			}
		}

		msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
		go func() {
			m := msg
			time.Sleep(time.Second * 10)
			s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
		}()
	},
	"sh": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		log.Println("Calling short...")
		var (
			ticker string
			spt    string
			ept    string
			desc   string
			poi    string
			expiry string
			stop   string
			entry  string
		)
		log.Println("Calling short for " + ticker)
		argValMap := make(map[string]string)

		for _, v := range i.ApplicationCommandData().Options {
			argValMap[v.Name] = v.StringValue()
		}

		if v, ok := argValMap[TICKER]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("ticker not defined"))
			return
		} else {
			ticker = strings.ToUpper(v)
		}
		if v, ok := argValMap[SCALE_PT]; ok {
			spt = v
		}
		if v, ok := argValMap[EXIT_PT]; ok {
			ept = v
		}

		if v, ok := argValMap[DESC]; ok {
			desc = v
		}

		if v, ok := argValMap[STOPLOSS]; ok {
			stop = v
		}

		if v, ok := argValMap[POI]; ok {
			poi = v
		}

		if v, ok := argValMap[EXPIRY]; ok {
			expiry = v
		}

		if v, ok := argValMap[ENTRY]; ok {
			entry = v
		}

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{},
		})

		channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)

		if channelType == -1 {
			log.Println(errors.New("invalid channel type"))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}
		msg, _ := s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{Content: "Thinking..."})
		var embed *discordgo.MessageEmbed
		var err error
		var starting float32

		if msg == nil {
			embed, starting, err = createShortsHandler(s, i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, spt, ept, expiry, entry, poi, stop, channelType, nil)
		} else {
			embed, starting, err = createShortsHandler(s, i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, spt, ept, expiry, entry, poi, stop, channelType, msg.Reference())
		}

		if err != nil {
			log.Println(fmt.Errorf("error creating createShortHandler: %w", err))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		msg, _ = s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: fmt.Sprintf("Short %v @ $%.2f \n***%v***", ticker, starting, desc),
			AllowedMentions: &discordgo.MessageAllowedMentions{
				Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
			},
			Embeds: []*discordgo.MessageEmbed{embed},
			Components: []discordgo.MessageComponent{
				discordgo.ActionsRow{
					Components: []discordgo.MessageComponent{
						discordgo.SelectMenu{
							CustomID:    "opt_short",
							MinValues:   0,
							MaxValues:   1,
							Placeholder: "Actions",
							Options: []discordgo.SelectMenuOption{
								{
									Label:       "Remove Alert",
									Description: "Removes this alert. Only the alerter can do this - will fail for anyone else.",
									Default:     false,
									Value:       "rm_" + ticker,
									Emoji: discordgo.ComponentEmoji{
										Name: "❌",
									},
								},
								{
									Label:       "Get Email alerts for this (this does nothing atm)",
									Description: "Recieve Email alerts.",
									Default:     false,
									Value:       "em_" + ticker,
									Emoji: discordgo.ComponentEmoji{
										Name: "📧",
									},
								},
							},
						},
					},
				},
			},
		},
		)
		componentMsgMap["sh_"+ticker] = msg
		var ms *discordgo.MessageSend

		if msg == nil {
			ms = &discordgo.MessageSend{
				Content: "Short " + ticker + " @everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
			}
		} else {
			ms = &discordgo.MessageSend{
				Content: "Short " + ticker + " @everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Reference: msg.Reference(),
			}
		}
		msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
		go func() {
			m := msg
			time.Sleep(time.Second * 7)
			s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
		}()
	},
	"rmsh": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		log.Println("Calling rm-short...")
		var (
			ticker string
			desc   string
		)
		log.Println("Calling rm-short for " + ticker)
		argValMap := make(map[string]string)

		for _, v := range i.ApplicationCommandData().Options {
			argValMap[v.Name] = v.StringValue()
		}

		if v, ok := argValMap[TICKER]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("ticker not defined"))
			return
		} else {
			ticker = strings.ToUpper(v)
		}

		if v, ok := argValMap[DESC]; ok {
			desc = v
		}

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{},
		})

		channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)

		if channelType == -1 {
			log.Println(errors.New("invalid channel type"))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		embed, err := rmShortsCommandHandler(i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, desc, channelType)

		if err != nil {
			log.Println(fmt.Errorf("error removing short: %w", err))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		closing, _ := stonks.GetStock(ticker)

		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: fmt.Sprintf("Short alert removed - **%v** @ $%.2f"+"@everyone", ticker, closing),
			AllowedMentions: &discordgo.MessageAllowedMentions{
				Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
			},
			Embeds: []*discordgo.MessageEmbed{embed},
		},
		)
		var msg *discordgo.Message
		if msg, ok := componentMsgMap["sh_"+ticker]; ok {
			str := fmt.Sprintf("This alert has been deleted - closed @ $%.2f", closing)
			s.ChannelMessageEditComplex(&discordgo.MessageEdit{
				Content:    &str,
				Components: []discordgo.MessageComponent{},
				ID:         msg.ID,
				Channel:    msg.ChannelID,
			})

			delete(componentMsgMap, "sh_"+ticker)
		}

		var ms *discordgo.MessageSend

		if msg == nil {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
			}
		} else {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Reference: msg.Reference(),
			}
		}

		msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
		go func() {
			m := msg
			time.Sleep(time.Second * 10)
			s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
		}()
	},
	"c": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		log.Println("Calling crypto...")
		var (
			ticker string
			ept    string
			spt    string
			desc   string
			poi    string
			stop   string
			expiry string
			entry  string
		)
		argValMap := make(map[string]string)

		for _, v := range i.ApplicationCommandData().Options {
			argValMap[v.Name] = v.StringValue()
		}

		if v, ok := argValMap[COIN]; !ok {
			log.Println(errors.New("coin not defined"))
			return
		} else {
			ticker = strings.ToUpper(v)
		}
		log.Println("Calling crypto for " + ticker)

		if v, ok := argValMap[SCALE_PT]; ok {
			spt = v
		}
		if v, ok := argValMap[EXIT_PT]; ok {
			ept = v
		}

		if v, ok := argValMap[DESC]; ok {
			desc = v
		}

		if v, ok := argValMap[POI]; ok {
			poi = v
		}

		if v, ok := argValMap[STOPLOSS]; ok {
			stop = v
		}

		if v, ok := argValMap[EXPIRY]; ok {
			expiry = v
		}

		if v, ok := argValMap[ENTRY]; ok {
			entry = v
		}

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{},
		})

		channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)

		if channelType == -1 {
			log.Println(errors.New("invalid channel type"))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		msg, err := s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{Content: "Thinking..."})

		if err != nil {
			fmt.Println(err)
			os.Exit(0)
		}
		var embed *discordgo.MessageEmbed
		var starting float32
		if msg == nil {
			embed, starting, err = createCryptoHandler(s, i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, spt, ept, expiry, poi, entry, stop, channelType, nil)
		} else {
			embed, starting, err = createCryptoHandler(s, i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, spt, ept, expiry, poi, entry, stop, channelType, msg.Reference())
		}

		if err != nil {
			log.Println(fmt.Errorf("error creating createCryptoHandler: %w", err))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		if err != nil {
			log.Println(err)
			starting = -1.0
		}
		msg, _ = s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: fmt.Sprintf("Crypto %v @ $%.2f \n***%v***", ticker, starting, desc),
			AllowedMentions: &discordgo.MessageAllowedMentions{
				Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
			},
			Embeds: []*discordgo.MessageEmbed{embed},
			Components: []discordgo.MessageComponent{
				discordgo.ActionsRow{
					Components: []discordgo.MessageComponent{
						discordgo.SelectMenu{
							CustomID:    "opt_crypto",
							MinValues:   0,
							MaxValues:   1,
							Placeholder: "Actions",
							Options: []discordgo.SelectMenuOption{
								{
									Label:       "Remove Alert",
									Description: "Removes this alert. Only the alerter can do this - will fail for anyone else.",
									Default:     false,
									Value:       "rm_" + ticker,
									Emoji: discordgo.ComponentEmoji{
										Name: "❌",
									},
								},
								{
									Label:       "Get Email alerts for this (this does nothing atm)",
									Description: "Recieve Email alerts.",
									Default:     false,
									Value:       "em_" + ticker,
									Emoji: discordgo.ComponentEmoji{
										Name: "📧",
									},
								},
							},
						},
					},
				},
			},
		},
		)

		componentMsgMap["c_"+ticker] = msg
		var ms *discordgo.MessageSend

		if msg == nil {
			ms = &discordgo.MessageSend{
				Content: "Crypto  " + ticker + " @everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
			}
		} else {
			ms = &discordgo.MessageSend{
				Content: "Crypto  " + ticker + " @everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Reference: msg.Reference(),
			}
		}
		msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
		go func() {
			m := msg
			time.Sleep(time.Second * 7)
			s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
		}()
	},
	"rmc": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		log.Println("Calling rm-Crypto...")
		var (
			ticker string
			desc   string
		)
		argValMap := make(map[string]string)

		for _, v := range i.ApplicationCommandData().Options {
			argValMap[v.Name] = v.StringValue()
		}

		if v, ok := argValMap[COIN]; !ok {
			log.Println(errors.New("ticker not defined"))
			return
		} else {
			ticker = strings.ToUpper(v)
		}
		log.Println("Calling rm-Crypto for " + ticker)

		if v, ok := argValMap[DESC]; ok {
			desc = v
		}

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{},
		})

		channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)

		if channelType == -1 {
			log.Println(errors.New("invalid channel type"))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		embed, err := rmCryptoCommandHandler(i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, desc, channelType)

		if err != nil {
			log.Println(fmt.Errorf("error removing crypto: %w", err))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		closing, _ := stonks.GetCrypto(ticker, false)

		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: fmt.Sprintf("Crypto alert removed - **%v** @ $%.2f"+"@everyone", ticker, closing),
			AllowedMentions: &discordgo.MessageAllowedMentions{
				Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
			},
			Embeds: []*discordgo.MessageEmbed{embed},
		},
		)
		var msg *discordgo.Message
		if msg, ok := componentMsgMap["c_"+ticker]; ok {
			str := fmt.Sprintf("This alert has been deleted - closed @ $%.2f", closing)
			s.ChannelMessageEditComplex(&discordgo.MessageEdit{
				Content:    &str,
				Components: []discordgo.MessageComponent{},
				ID:         msg.ID,
				Channel:    msg.ChannelID,
			})

			delete(componentMsgMap, "c_"+ticker)
		}

		var ms *discordgo.MessageSend

		if msg == nil {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
			}
		} else {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Reference: msg.Reference(),
			}
		}

		msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
		go func() {
			m := msg
			time.Sleep(time.Second * 10)
			s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
		}()
	},
	"o": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		log.Println("Calling option...")
		var (
			ticker string
			expiry string
			strike string
			entry  string
			poi    string
			stop   string
			desc   string
			year   string
			month  string
			day    string
			pt     string
		)
		argValMap := make(map[string]string)

		for _, v := range i.ApplicationCommandData().Options {
			argValMap[v.Name] = v.StringValue()
		}

		if v, ok := argValMap[TICKER]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("ticker not defined"))
			return
		} else {
			ticker = strings.ToUpper(v)
		}
		log.Println("Calling option for " + ticker)

		if v, ok := argValMap[EXPIRY]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("expiry not defined"))
			return
		} else {
			expiry = v
		}

		if v, ok := argValMap[STRIKE]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("strike not defined"))
			return
		} else {
			strike = v
		}

		if v, ok := argValMap[POI]; ok {
			poi = v
		}

		if v, ok := argValMap[STOPLOSS]; ok {
			stop = v
		}

		if v, ok := argValMap[DESC]; ok {
			desc = v
		}

		if v, ok := argValMap[PRICE]; ok {
			pt = v
		}

		if v, ok := argValMap[ENTRY]; ok {
			entry = v
		}

		month, day, year, err := utils.ParseDate(expiry)
		if err != nil {
			discord.SendError(s, i.Interaction.ChannelID, err)
			return
		}

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{},
		})

		channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)

		if channelType == -1 {
			log.Println(errors.New("invalid channel type"))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}
		msg, _ := s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{Content: "Thinking..."})
		var embed *discordgo.MessageEmbed
		var starting float32
		if msg == nil {
			embed, starting, err = createOptionsHandler(s, i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, strike, year, month, day, entry, poi, stop, pt, channelType, nil)
		} else {
			embed, starting, err = createOptionsHandler(s, i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, strike, year, month, day, entry, poi, stop, pt, channelType, msg.Reference())
		}

		if err != nil {
			log.Println(fmt.Errorf("error creating createOptionHandler: %w", err).Error())
			s.FollowupMessageCreate(s.State.User.ID, i.Interaction, false, &discordgo.WebhookParams{
				Content: "Unable to create alert - " + err.Error(),
				Flags:   1 << 6,
			})
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}
		strikePriceFl, _ := strconv.ParseFloat(strike[:len(strike)-1], 32)
		oID := stonks.GetCode(ticker, strike[len(strike)-1:], day, month, year, float32(strikePriceFl))
		msg, err = s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: fmt.Sprintf("%v **%v/%v/%v %v** @ $%.2f \n***%v***", ticker, month, day, year, strike, starting, desc),
			AllowedMentions: &discordgo.MessageAllowedMentions{
				Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
			},
			Embeds: []*discordgo.MessageEmbed{embed},
			Components: []discordgo.MessageComponent{
				discordgo.ActionsRow{
					Components: []discordgo.MessageComponent{
						discordgo.SelectMenu{
							CustomID:    "opt_options",
							MinValues:   0,
							MaxValues:   1,
							Placeholder: "Actions",
							Options: []discordgo.SelectMenuOption{
								{
									Label:       "Remove Alert",
									Description: "Removes this alert. Only the alerter can do this - will fail for anyone else.",
									Default:     false,
									Value:       "rm_" + oID,
									Emoji: discordgo.ComponentEmoji{
										Name: "❌",
									},
								},
								{
									Label:       "Get Email alerts for this (this does nothing atm)",
									Description: "Recieve Email alerts.",
									Default:     false,
									Value:       "em_" + stonks.GetCode(ticker, strike[len(strike)-1:], day, month, year, float32(strikePriceFl)),
									Emoji: discordgo.ComponentEmoji{
										Name: "📧",
									},
								},
							},
						},
					},
				},
			},
		},
		)

		componentMsgMap[oID] = msg

		if err != nil {
			log.Println(err)
		}
		var ms *discordgo.MessageSend
		includeChart := true

		chart, err := graph.Get15MStocksChart(ticker)

		if err != nil {
			includeChart = false
		}

		file, err := os.Open(chart)
		if err != nil {
			includeChart = false
		}
		defer func() {
			file.Close()

			os.Remove(chart)
		}()
		if msg == nil {
			ms = &discordgo.MessageSend{
				Content: fmt.Sprintf("%v **%v/%v %v** @everyone \n***%v***", ticker, month, day, strike, desc),
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
			}
		} else {
			ms = &discordgo.MessageSend{
				Content: fmt.Sprintf("%v **%v/%v %v** @everyone \n***%v***", ticker, month, day, strike, desc),
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Reference: msg.Reference(),
			}
		}

		if includeChart {
			ms.Files = []*discordgo.File{
				{
					Name:        chart,
					ContentType: "image/png",
					Reader:      file,
				},
			}
			ms.Embeds = []*discordgo.MessageEmbed{
				{
					Image: &discordgo.MessageEmbedImage{
						URL: "attachment://" + chart,
					},
				},
			}
		}
		msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
		go func() {
			m := msg
			time.Sleep(time.Second * 30)
			s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
		}()
	},
	"rmo": func(s *discordgo.Session, i *discordgo.InteractionCreate) {

		if !isAuthed(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}
		log.Println("Calling rm-option...")
		var (
			ticker string
			expiry string
			strike string
			desc   string
			year   string
			month  string
			day    string
		)
		log.Println("Calling option for " + ticker)
		argValMap := make(map[string]string)

		for _, v := range i.ApplicationCommandData().Options {
			argValMap[v.Name] = v.StringValue()
		}

		if v, ok := argValMap[TICKER]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("ticker not defined"))
			return
		} else {
			ticker = strings.ToUpper(v)
		}

		if v, ok := argValMap[EXPIRY]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("expiry not defined"))
			return
		} else {
			expiry = v
		}

		if v, ok := argValMap[STRIKE]; !ok {
			discord.SendError(s, i.Interaction.ChannelID, errors.New("strike not defined"))
			return
		} else {
			strike = v
		}
		if v, ok := argValMap[DESC]; ok {
			desc = v
		}

		month, day, year, err := utils.ParseDate(expiry)
		if err != nil {
			discord.SendError(s, i.Interaction.ChannelID, err)
			return
		}

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{},
		})

		channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)

		if channelType == -1 {
			log.Println(errors.New("invalid channel type"))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		embed, err := rmOptionsCommandHandler(i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, strike, year, month, day, desc, channelType)

		if err != nil {
			log.Println(fmt.Errorf("error removing Option: %w", err))
			s.InteractionResponseDelete(s.State.User.ID, i.Interaction)
			return
		}

		strikePriceFl, _ := strconv.ParseFloat(strike[:len(strike)-1], 32)
		cType := strike[len(strike)-1:]
		oID := stonks.GetCode(ticker, strike[len(strike)-1:], day, month, year, float32(strikePriceFl))
		prettyStr := utils.NiceStr(ticker, cType, day, month, year, float32(strikePriceFl))
		closing, _, _ := stonks.GetOption(ticker, cType, day, month, year, float32(strikePriceFl), 0)

		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Content: fmt.Sprintf("Option alert removed - **%v** @ $%.2f", prettyStr, closing),
			AllowedMentions: &discordgo.MessageAllowedMentions{
				Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
			},
			Embeds: []*discordgo.MessageEmbed{embed},
		},
		)

		var msg *discordgo.Message
		if msg, ok := componentMsgMap[oID]; ok {
			str := fmt.Sprintf("This alert has been deleted - closed @ $%.2f", closing)
			s.ChannelMessageEditComplex(&discordgo.MessageEdit{
				Content:    &str,
				Components: []discordgo.MessageComponent{},
				ID:         msg.ID,
				Channel:    msg.ChannelID,
			})

			delete(componentMsgMap, oID)
		}

		var ms *discordgo.MessageSend

		if msg == nil {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
			}
		} else {
			ms = &discordgo.MessageSend{
				Content: "@everyone",
				AllowedMentions: &discordgo.MessageAllowedMentions{
					Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
				},
				Reference: msg.Reference(),
			}
		}

		msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
		go func() {
			m := msg
			time.Sleep(time.Second * 10)
			s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
		}()
	},
	"c15": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthedLower(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}

		log.Println("Calling c15...")

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "",
			},
		})

		chart, err := graph.Get15MStocksChart(i.ApplicationCommandData().Options[0].StringValue())

		if err != nil {
			return
		}
		file, err := os.Open(chart)
		defer func() {
			file.Close()

			os.Remove(chart)
		}()

		if err != nil {
			return
		}
		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Files: []*discordgo.File{
				{
					Name:        chart,
					ContentType: "image/png",
					Reader:      file,
				},
			},
			Embeds: []*discordgo.MessageEmbed{
				{
					Image: &discordgo.MessageEmbedImage{
						URL: "attachment://" + chart,
					},
				},
			},
		})
	},
	"ch": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthedLower(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}

		log.Println("Calling ch...")

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "",
			},
		})

		chart, err := graph.GetHStocksChart(i.ApplicationCommandData().Options[0].StringValue())

		if err != nil {
			return
		}
		file, err := os.Open(chart)
		defer func() {
			file.Close()

			os.Remove(chart)
		}()

		if err != nil {
			return
		}

		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Files: []*discordgo.File{
				{
					Name:        chart,
					ContentType: "image/png",
					Reader:      file,
				},
			},
			Embeds: []*discordgo.MessageEmbed{
				{
					Image: &discordgo.MessageEmbedImage{
						URL: "attachment://" + chart,
					},
				},
			},
		})
	},
	"cd": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthedLower(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}

		log.Println("Calling cd...")

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "",
			},
		})

		chart, err := graph.GetDStocksChart(i.ApplicationCommandData().Options[0].StringValue())

		if err != nil {
			return
		}
		file, err := os.Open(chart)
		defer func() {
			file.Close()

			os.Remove(chart)
		}()

		if err != nil {
			return
		}
		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Files: []*discordgo.File{
				{
					Name:        chart,
					ContentType: "image/png",
					Reader:      file,
				},
			},
			Embeds: []*discordgo.MessageEmbed{
				{
					Image: &discordgo.MessageEmbedImage{
						URL: "attachment://" + chart,
					},
				},
			},
		})
	},
	"cc15": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthedLower(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}

		log.Println("Calling cc15...")

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "",
			},
		})

		chart, err := graph.Get15MCryptoChart(i.ApplicationCommandData().Options[0].StringValue())
		if err != nil {
			return
		}

		file, err := os.Open(chart)
		defer func() {
			file.Close()

			os.Remove(chart)
		}()

		if err != nil {
			return
		}

		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Files: []*discordgo.File{
				{
					Name:        chart,
					ContentType: "image/png",
					Reader:      file,
				},
			},
			Embeds: []*discordgo.MessageEmbed{
				{
					Image: &discordgo.MessageEmbedImage{
						URL: "attachment://" + chart,
					},
				},
			},
		})
	},
	"cch": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthedLower(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}

		log.Println("Calling cch...")

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "",
			},
		})

		chart, err := graph.GetHCryptoChart(i.ApplicationCommandData().Options[0].StringValue())

		if err != nil {
			return
		}

		file, err := os.Open(chart)
		defer func() {
			file.Close()

			os.Remove(chart)
		}()

		if err != nil {
			return
		}

		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Files: []*discordgo.File{
				{
					Name:        chart,
					ContentType: "image/png",
					Reader:      file,
				},
			},
			Embeds: []*discordgo.MessageEmbed{
				{
					Image: &discordgo.MessageEmbedImage{
						URL: "attachment://" + chart,
					},
				},
			},
		})
	},
	"ccd": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		if !isAuthedLower(i) {
			log.Println("no perms for this action " + i.Interaction.Member.User.Username)
			return
		}

		log.Println("Calling ccd...")

		s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
			Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
			Data: &discordgo.InteractionResponseData{
				Content: "",
			},
		})

		chart, err := graph.GetDCryptoChart(i.ApplicationCommandData().Options[0].StringValue())

		if err != nil {
			return
		}

		file, err := os.Open(chart)
		defer func() {
			file.Close()

			os.Remove(chart)
		}()

		if err != nil {
			return
		}

		s.InteractionResponseEdit(s.State.User.ID, i.Interaction, &discordgo.WebhookEdit{
			Files: []*discordgo.File{
				{
					Name:        chart,
					ContentType: "image/png",
					Reader:      file,
				},
			},
			Embeds: []*discordgo.MessageEmbed{
				{
					Image: &discordgo.MessageEmbedImage{
						URL: "attachment://" + chart,
					},
				},
			},
		})
	},
}
View Source
var Commands = []*discordgo.ApplicationCommand{
	{
		Name:        "s",
		Description: "Adds a new stock alert.",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "ticker",
				Description: "The stock ticker you want to alert",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "scale_pt",
				Description: "The PT you want the underlying to hit where its is suggested to scale out.",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "exit_pt",
				Description: "The PT you want the underlying to hit.",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "desc",
				Description: "Any additional info you want included in the alert",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "stop",
				Description: "A stop loss that will expire the alert with the message STOP LOSS HIT",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "poi",
				Description: "Point of interest. Will alert to enter when this is hit (when the price reaches +-0.5%)",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "entry",
				Description: "The price of the alerters entry, if different from the current price",
				Required:    false,
			},
		},
	},
	{
		Name:        "sh",
		Description: "Adds a new short alert.",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "ticker",
				Description: "The short ticker you want to alert",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "scale_pt",
				Description: "The PT you want the underlying to hit where its is suggested to scale out.",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "exit_pt",
				Description: "The PT you want the underlying to hit.",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "desc",
				Description: "Any additional info you want included in the alert",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "stop",
				Description: "A stop loss that will expire the alert with the message STOP LOSS HIT",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "poi",
				Description: "Point of interest. Will alert to enter when this is hit (when the price reaches +-0.5%)",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "entry",
				Description: "The price of the alerters entry, if different from the current price",
				Required:    false,
			},
		},
	},
	{
		Name:        "c",
		Description: "Adds a new crypto alert.",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "coin",
				Description: "The coin you want to alert",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "scale_pt",
				Description: "The PT you want the underlying to hit where its is suggested to scale out.",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "exit_pt",
				Description: "The PT you want the underlying to hit.",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "desc",
				Description: "Any additional info you want included in the alert",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "stop",
				Description: "A stop loss that will expire the alert with the message STOP LOSS HIT",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "poi",
				Description: "Point of interest. Will alert to enter when this is hit (when the price reaches +-0.5%)",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "entry",
				Description: "The price of the alerters entry, if different from the current price",
				Required:    false,
			},
		},
	},
	{
		Name:        "o",
		Description: "Adds a new options alert. The alert will automatically remove itself after the strike date.",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "ticker",
				Description: "The stock you want the option to be based on",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "expiry",
				Description: "The expiry of the contract. If the expiry is this year, then mm/dd. Else, mm/ddd/yy.",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "strike",
				Description: "The strike price of the contract + the contract type, e.g. 140C, 55.50P",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "desc",
				Description: "Any additional info you want included in the alert",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "entry",
				Description: "The price of the alerters entry, if different from the current price",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "stop",
				Description: "A stop loss (based on the underlying) that will expire the alert",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "poi",
				Description: "Point of interest. Will alert to enter when this is hit (when the underlying price reaches +-0.5%)",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "scale_pt",
				Description: "The PT you want the underlying to hit where its is suggested to scale out.",
				Required:    false,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "exit_pt",
				Description: "The PT you want the underlying to hit.",
				Required:    false,
			},
		},
	},
	{
		Name:        "rms",
		Description: "Removes a stock alert.",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "ticker",
				Description: "The stock ticker you want to remove",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "desc",
				Description: "Any additional info you want included in the alert",
				Required:    false,
			},
		},
	},
	{
		Name:        "rmsh",
		Description: "Removes a short alert.",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "ticker",
				Description: "The short ticker you want to remove",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "desc",
				Description: "Any additional info you want included in the alert",
				Required:    false,
			},
		},
	},
	{
		Name:        "rmc",
		Description: "Removes a crypto alert.",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "coin",
				Description: "The coin you want to remove",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "desc",
				Description: "Any additional info you want included in the alert",
				Required:    false,
			},
		},
	},
	{
		Name:        "rmo",
		Description: "Removes an options alert.",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "ticker",
				Description: "The stock you want the option to be based on",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "expiry",
				Description: "The expiry of the contract. If the expiry is this year, then mm/dd. Else, mm/ddd/yy.",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "strike",
				Description: "The strike price of the contract + the contract type, e.g. 140C, 55.50P",
				Required:    true,
			},
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "desc",
				Description: "Any additional info you want included in the alert",
				Required:    false,
			},
		},
	},
	{
		Name:        "nuke",
		Description: "Nuke.",
	},
	{
		Name:        "all",
		Description: "Show all active alerts.",
	},
	{
		Name:        "refresh",
		Description: "Refresh all alerts. Must be called after a restart",
	},
	{
		Name:        "alert",
		Description: "Alert whatever you type",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "msg",
				Description: "The content of the alert.",
				Required:    true,
			},
		},
	},
	{
		Name:        "tracker",
		Description: "Print out the End of Day tracker of day trades for the previous day",
	},
	{
		Name:        "c15",
		Description: "Stocks 15m Chart",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "ticker",
				Description: "Ticker to get the 15m chart of",
				Required:    true,
			},
		},
	},
	{
		Name:        "ch",
		Description: "Stocks Hourly Chart",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "ticker",
				Description: "Ticker to get the Hourly chart of",
				Required:    true,
			},
		},
	},
	{
		Name:        "cd",
		Description: "Stocks Daily Chart",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "ticker",
				Description: "Ticker to get the Daily chart of",
				Required:    true,
			},
		},
	},
	{
		Name:        "cc15",
		Description: "Crypto 15m Chart",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "coin",
				Description: "Coin to get the 15m chart of",
				Required:    true,
			},
		},
	},
	{
		Name:        "cch",
		Description: "Crypto Hourly Chart",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "coin",
				Description: "coin to get the Hourly chart of",
				Required:    true,
			},
		},
	},
	{
		Name:        "ccd",
		Description: "Crypto Daily Chart",
		Options: []*discordgo.ApplicationCommandOption{
			{
				Type:        discordgo.ApplicationCommandOptionString,
				Name:        "coin",
				Description: "coin to get the Daily chart of",
				Required:    true,
			},
		},
	},
}
View Source
var ComponentHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
	"opt_options": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		data := i.MessageComponentData()

		if len(data.Values) != 1 {
			log.Println("Passed values != 1")
			log.Println(len(data.Values))
			return
		}

		if data.Values[0][:3] == "rm_" {
			code := data.Values[0][3:]

			log.Println("RM Button pressed for " + i.Interaction.GuildID + code)

			ticker, cType, day, month, year, price, err := getOptAndCheckOwner(i.Interaction.GuildID, code, i.Member.User.ID)

			if err != nil {
				log.Println(fmt.Errorf("error button removing option: %w", err))
				s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
					Type: discordgo.InteractionResponseChannelMessageWithSource,
					Data: &discordgo.InteractionResponseData{
						Flags:   1 << 6,
						Content: "Error removing option - " + err.Error(),
					},
				})
				return
			}
			channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)
			embed, err := rmOptionsCommandHandler(i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, fmt.Sprintf("%f%v", price, cType), year, month, day, "", channelType)
			if err != nil {
				log.Println(fmt.Errorf("error removing Option: %w", err))
				s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
					Type: discordgo.InteractionResponseChannelMessageWithSource,
					Data: &discordgo.InteractionResponseData{
						Flags:   1 << 6,
						Content: "Error removing option - " + err.Error() + " try removing with /rmo. If that doesnt work, ping @<M1K#8125>",
					},
				})
				return
			}

			oID := stonks.GetCode(ticker, cType, day, month, year, price)
			prettyStr := utils.NiceStr(ticker, cType, day, month, year, price)
			closing, _, _ := stonks.GetOption(ticker, cType, day, month, year, price, 0)

			s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
				Type: discordgo.InteractionResponseChannelMessageWithSource,
				Data: &discordgo.InteractionResponseData{
					Content: fmt.Sprintf("Option alert removed - **%v** @ $%.2f @everyone", prettyStr, closing),
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
					Embeds: []*discordgo.MessageEmbed{embed},
				},
			},
			)

			var msg *discordgo.Message
			if msg, ok := componentMsgMap[oID]; ok {
				str := fmt.Sprintf("This alert has been deleted - closed @ $%.2f", closing)
				s.ChannelMessageEditComplex(&discordgo.MessageEdit{
					Content:    &str,
					Components: []discordgo.MessageComponent{},
					ID:         msg.ID,
					Channel:    msg.ChannelID,
				})

				delete(componentMsgMap, oID)
			}

			var ms *discordgo.MessageSend

			if msg == nil {
				ms = &discordgo.MessageSend{
					Content: "@everyone",
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
				}
			} else {
				ms = &discordgo.MessageSend{
					Content: "@everyone",
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
					Reference: msg.Reference(),
				}
			}

			msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
			go func() {
				m := msg
				time.Sleep(time.Second * 10)
				s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
			}()

		} else if data.Values[0][:3] == "em_" {
			return
		}
	},
	"opt_crypto": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		data := i.MessageComponentData()

		if len(data.Values) != 1 {
			log.Println("Passed values != 1")
			log.Println(len(data.Values))
			return
		}

		if data.Values[0][:3] == "rm_" {
			ticker := data.Values[0][3:]

			err := getCryptoAndCheckOwner(i.Interaction.GuildID, ticker, i.Member.User.ID)

			if err != nil {
				log.Println(fmt.Errorf("error button removing Crypto: %w", err))
				s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
					Type: discordgo.InteractionResponseChannelMessageWithSource,
					Data: &discordgo.InteractionResponseData{
						Flags:   1 << 6,
						Content: "Error removing Crypto - " + err.Error(),
					},
				})
				return
			}
			channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)
			embed, err := rmCryptoCommandHandler(i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, "", channelType)

			s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
				Type: discordgo.InteractionResponseChannelMessageWithSource,
				Data: &discordgo.InteractionResponseData{
					Content: "Alert Removed",
				},
			})

			time.Sleep(time.Second)
			if err != nil {
				log.Println(fmt.Errorf("error removing Crypto: %w", err))
				s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
					Type: discordgo.InteractionResponseChannelMessageWithSource,
					Data: &discordgo.InteractionResponseData{
						Flags:   1 << 6,
						Content: "Error removing Crypto - " + err.Error() + " try removing with /rmo. If that doesnt work, ping @<M1K#8125>",
					},
				})
				return
			}
			closing, _ := stonks.GetCrypto(ticker, false)

			s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
				Type: discordgo.InteractionResponseChannelMessageWithSource,
				Data: &discordgo.InteractionResponseData{
					Content: fmt.Sprintf("Crypto alert removed - **%v** @ $%.2f"+"@everyone", ticker, closing),
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
					Embeds: []*discordgo.MessageEmbed{embed},
				},
			},
			)

			var msg *discordgo.Message
			if msg, ok := componentMsgMap["c_"+ticker]; ok {
				str := fmt.Sprintf("This alert has been deleted - closed @ $%.2f", closing)
				s.ChannelMessageEditComplex(&discordgo.MessageEdit{
					Content:    &str,
					Components: []discordgo.MessageComponent{},
					ID:         msg.ID,
					Channel:    msg.ChannelID,
				})

				delete(componentMsgMap, "c_"+ticker)
			}

			var ms *discordgo.MessageSend

			if msg == nil {
				ms = &discordgo.MessageSend{
					Content: "@everyone",
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
				}
			} else {
				ms = &discordgo.MessageSend{
					Content: "@everyone",
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
					Reference: msg.Reference(),
				}
			}

			msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
			go func() {
				m := msg
				time.Sleep(time.Second * 10)
				s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
			}()

		} else if data.Values[0][:3] == "em_" {
			return
		}
	},
	"opt_stock": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		data := i.MessageComponentData()

		if len(data.Values) != 1 {
			log.Println("Passed values != 1")
			log.Println(len(data.Values))
			return
		}

		if data.Values[0][:3] == "rm_" {
			ticker := data.Values[0][3:]

			err := getStockAndCheckOwner(i.Interaction.GuildID, ticker, i.Member.User.ID)

			if err != nil {
				log.Println(fmt.Errorf("error button removing Stock: %w", err))
				s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
					Type: discordgo.InteractionResponseChannelMessageWithSource,
					Data: &discordgo.InteractionResponseData{
						Flags:   1 << 6,
						Content: "Error removing Stock - " + err.Error(),
					},
				})
				return
			}
			channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)
			embed, err := rmStocksCommandHandler(i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, "", channelType)
			if err != nil {
				log.Println(fmt.Errorf("error removing stock: %w", err))
				s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
					Type: discordgo.InteractionResponseChannelMessageWithSource,
					Data: &discordgo.InteractionResponseData{
						Flags:   1 << 6,
						Content: "Error removing stock - " + err.Error() + " try removing with /rms. If that doesnt work, ping @<M1K#8125>",
					},
				})
				return
			}
			closing, _ := stonks.GetStock(ticker)

			s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
				Type: discordgo.InteractionResponseChannelMessageWithSource,
				Data: &discordgo.InteractionResponseData{
					Content: fmt.Sprintf("Stock alert removed - **%v** @ $%.2f"+"@everyone", ticker, closing),
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
					Embeds: []*discordgo.MessageEmbed{embed},
				},
			},
			)
			var msg *discordgo.Message
			if msg, ok := componentMsgMap["s_"+ticker]; ok {
				str := fmt.Sprintf("This alert has been deleted - closed @ $%.2f", closing)
				s.ChannelMessageEditComplex(&discordgo.MessageEdit{
					Content:    &str,
					Components: []discordgo.MessageComponent{},
					ID:         msg.ID,
					Channel:    msg.ChannelID,
				})

				delete(componentMsgMap, "s_"+ticker)
			}

			var ms *discordgo.MessageSend

			if msg == nil {
				ms = &discordgo.MessageSend{
					Content: "@everyone",
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
				}
			} else {
				ms = &discordgo.MessageSend{
					Content: "@everyone",
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
					Reference: msg.Reference(),
				}
			}

			msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
			go func() {
				m := msg
				time.Sleep(time.Second * 10)
				s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
			}()

		} else if data.Values[0][:3] == "em_" {
			return
		}
	},
	"opt_short": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
		data := i.MessageComponentData()

		if len(data.Values) != 1 {
			log.Println("Passed values != 1")
			log.Println(len(data.Values))
			return
		}

		if data.Values[0][:3] == "rm_" {
			ticker := data.Values[0][3:]

			err := getShortAndCheckOwner(i.Interaction.GuildID, ticker, i.Member.User.ID)

			if err != nil {
				log.Println(fmt.Errorf("error button removing Short: %w", err))
				s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
					Type: discordgo.InteractionResponseChannelMessageWithSource,
					Data: &discordgo.InteractionResponseData{
						Flags:   1 << 6,
						Content: "Error removing Short - " + err.Error(),
					},
				})
				return
			}
			channelType := utils.GetChannelType(i.Interaction.GuildID, i.Interaction.ChannelID)
			embed, err := rmShortsCommandHandler(i.Interaction.GuildID, i.Interaction.ChannelID, i.Member.User.Mention(), ticker, "", channelType)

			if err != nil {
				log.Println(fmt.Errorf("error removing Short: %w", err))
				s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
					Type: discordgo.InteractionResponseChannelMessageWithSource,
					Data: &discordgo.InteractionResponseData{
						Flags:   1 << 6,
						Content: "Error removing Short - " + err.Error() + " try removing with /rmo. If that doesnt work, ping @<M1K#8125>",
					},
				})
				return
			}

			closing, _ := stonks.GetStock(ticker)

			s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
				Type: discordgo.InteractionResponseChannelMessageWithSource,
				Data: &discordgo.InteractionResponseData{
					Content: fmt.Sprintf("Short alert removed - **%v** @ $%.2f"+"@everyone", ticker, closing),
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
					Embeds: []*discordgo.MessageEmbed{embed},
				},
			},
			)
			var msg *discordgo.Message
			if msg, ok := componentMsgMap["sh_"+ticker]; ok {
				str := fmt.Sprintf("This alert has been deleted - closed @ $%.2f", closing)
				s.ChannelMessageEditComplex(&discordgo.MessageEdit{
					Content:    &str,
					Components: []discordgo.MessageComponent{},
					ID:         msg.ID,
					Channel:    msg.ChannelID,
				})

				delete(componentMsgMap, "sh_"+ticker)
			}

			var ms *discordgo.MessageSend

			if msg == nil {
				ms = &discordgo.MessageSend{
					Content: "@everyone",
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
				}
			} else {
				ms = &discordgo.MessageSend{
					Content: "@everyone",
					AllowedMentions: &discordgo.MessageAllowedMentions{
						Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeEveryone},
					},
					Reference: msg.Reference(),
				}
			}

			msg, _ = s.ChannelMessageSendComplex(i.Interaction.ChannelID, ms)
			go func() {
				m := msg
				time.Sleep(time.Second * 10)
				s.ChannelMessageDelete(i.Interaction.ChannelID, m.ID)
			}()

		} else if data.Values[0][:3] == "em_" {
			return
		}
	},
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL