From 510091bbfa4777cb3272531c6c847ec8b1224970 Mon Sep 17 00:00:00 2001 From: Aaron Johnon Date: Tue, 3 Dec 2024 21:40:22 -0600 Subject: [PATCH] Functional incomplete --- tbotsend.go | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 tbotsend.go diff --git a/tbotsend.go b/tbotsend.go new file mode 100644 index 0000000..3b3ba70 --- /dev/null +++ b/tbotsend.go @@ -0,0 +1,186 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "path/filepath" + "strings" + "strconv" + "time" + + "github.com/spf13/pflag" + "gopkg.in/yaml.v2" +) + +type Config struct { + ChatID string `yaml:"CHATID"` + Token string `yaml:"TOKEN"` + Timeout int `yaml:"TIMEOUT"` +} + +var ( + configFile string + chatID string + token string + timeout int + silent bool +) + +func init() { + pflag.StringVarP(&configFile, "config", "f", "", "Configuration file path") + pflag.StringVarP(&chatID, "chatid", "c", "", "Chat ID value") + pflag.StringVarP(&token, "token", "k", "", "Bot token value") + pflag.IntVarP(&timeout, "timeout", "t", 10, "Timeout value (defaults to 10)") + pflag.BoolVarP(&silent, "silent", "s", false, "Disable notification") +} + +func main() { + pflag.Parse() + args := pflag.Args() + message := strings.Join(args, " ") + + // Print the date and time for logging purposes + fmt.Println(" -- " + time.Now().Format("2006-01-02 15:04:05")) + + var config Config + configUsed := "" + + // Check configuration + if (chatID != "" || token != "") && configFile != "" { + printError("Cannot use both configuration file and configuration flags") + os.Exit(2) + } else if chatID != "" && token != "" { + // Use configuration flags + config.ChatID = chatID + config.Token = token + config.Timeout = timeout + configUsed = "MANUAL" + } else { + // Use configuration file + if configFile == "" { + // Use default config file at ${HOME}/.config/tbotsend.yaml + homeDir, err := os.UserHomeDir() + if err != nil { + printError(fmt.Sprintf("Failed to get user home directory: %v", err)) + os.Exit(2) + } + configFile = filepath.Join(homeDir, ".config", "tbotsend.yaml") + } + + // Read configuration file + data, err := ioutil.ReadFile(configFile) + if err != nil { + // Try secondary configuration file at ${HOME}/.tbotsend.yaml + if configFile == filepath.Join(os.Getenv("HOME"), ".config", "tbotsend.yaml") { + secondaryConfigFile := filepath.Join(os.Getenv("HOME"), ".tbotsend.yaml") + data, err = ioutil.ReadFile(secondaryConfigFile) + if err != nil { + printError(fmt.Sprintf("Failed to read configuration file '%s' or '%s': %v", configFile, secondaryConfigFile, err)) + os.Exit(2) + } + configFile = secondaryConfigFile + } else { + printError(fmt.Sprintf("Failed to read configuration file '%s': %v", configFile, err)) + os.Exit(2) + } + } + + // Parse YAML + err = yaml.Unmarshal(data, &config) + if err != nil { + printError(fmt.Sprintf("Failed to parse configuration file '%s': %v", configFile, err)) + os.Exit(2) + } + // Set default timeout if not set + if config.Timeout == 0 { + config.Timeout = 10 + } + configUsed = configFile + } + + // Validate configuration + if config.ChatID == "" || config.Token == "" { + printError("Configuration is missing ChatID or Token") + os.Exit(2) + } + + // Ensure message is provided + if message == "" { + printError("No message provided") + os.Exit(2) + } + + // Prepare to send the message + urlStr := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", config.Token) + + data := url.Values{} + data.Set("chat_id", config.ChatID) + data.Set("disable_web_page_preview", "1") + if silent { + data.Set("disable_notification", "true") + } + data.Set("text", message) + + client := &http.Client{ + Timeout: time.Duration(config.Timeout) * time.Second, + } + + // Send the POST request + resp, err := client.PostForm(urlStr, data) + if err != nil { + printFailure(err.Error()) + os.Exit(13) + } + defer resp.Body.Close() + + // Read the response body + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + printFailure(err.Error()) + os.Exit(13) + } + + // Parse the response to check for success + type TelegramResponse struct { + Ok bool `json:"ok"` + Description string `json:"description"` + } + + var telegramResp TelegramResponse + err = json.Unmarshal(body, &telegramResp) + if err != nil { + printFailure(err.Error()) + os.Exit(13) + } + + if !telegramResp.Ok { + printFailure(telegramResp.Description) + os.Exit(13) + } + + // Print the required information + fmt.Printf("\033[1mConfig Used:\033[0m %s\n", configUsed) + fmt.Printf("\033[1mChat ID:\033[0m %s\n", config.ChatID) + fmt.Printf("\033[1mSilent:\033[0m %s\n", strconv.FormatBool(silent)) + fmt.Printf("\033[1mMessage:\033[0m %s\n", message) + + // Print SUCCESS in bold green text + printSuccess() +} + +func printError(msg string) { + fmt.Fprintf(os.Stderr, "[\033[1;31mERROR\033[0m] %s\n", msg) +} + +func printFailure(msg string) { + fmt.Fprintf(os.Stderr, "\033[1mResult:\033[0m [\033[1;31mFAILURE\033[0m]: %s\n\n", msg) +} + +func printSuccess() { + fmt.Fprintf(os.Stdout, "\033[1mResult:\033[0m [\033[1;32mSUCCESS\033[0m]\n\n") +} +