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 ¶
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 ¶
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, }, }, }, }) }, }
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, }, }, }, }
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.