diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9c8a377 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module frozenverse/tmsg + +go 1.18 + +require github.com/gorilla/mux v1.8.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..5350288 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= diff --git a/tmsg.go b/tmsg.go new file mode 100644 index 0000000..52e0ac8 --- /dev/null +++ b/tmsg.go @@ -0,0 +1,160 @@ +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + + "github.com/gorilla/mux" +) + +var options struct { + MessageServerEndpoint string + MessageServer bool + MessageSender string + MessageContent string +} + +type MessageEvent struct { + Username string `json:"username"` + Message string `json:"message"` +} + +type APIResponse struct { + Code string `json:"code"` + Message string `json:"message"` +} + +func main() { + options.MessageServerEndpoint = "http://88.159.66.169:6969" + + flag.BoolVar(&options.MessageServer, "server", false, "Start this application as message server.") + flag.StringVar(&options.MessageSender, "username", "", "Set the username to be used.") + flag.StringVar(&options.MessageContent, "msg", "", "Message to send to server.") + flag.Parse() + + if len(options.MessageSender) >= 2 { + createUsernameFile() + return + } + + if options.MessageServer { + initMessageServer() + return + } + + readUsernameFile() + + if len(options.MessageContent) < 2 { + log.Fatal("Please enter a message using the --msg option. Ex: tmsg --msg \"put your message here...\"") + } + + sendMessage() +} + +func sendMessage() { + log.Printf("Sending message as: %s", options.MessageSender) + + payload, _ := json.Marshal(MessageEvent{ + Username: options.MessageSender, + Message: options.MessageContent, + }) + + payloadBuffer := bytes.NewBuffer(payload) + resp, err := http.Post(fmt.Sprintf("%s/msg", options.MessageServerEndpoint), "application/json", payloadBuffer) + + log.Printf("Message has been send to the server.\n") + + if err != nil { + log.Fatalf("Error occured sending message to server! Error: %s\n", err) + } + + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + + if err != nil { + log.Fatalf("Error occured parsing message request from server! Error: %s\n", err) + } + + apiResponse := APIResponse{} + json.Unmarshal(body, &apiResponse) + + if apiResponse.Code == "success" { + log.Printf("Server Response: %s\n", apiResponse.Message) + } else { + log.Printf("Server Response (%d): %s\n\n", resp.StatusCode, apiResponse.Message) + } +} + +func initMessageServer() { + router := mux.NewRouter().StrictSlash(true) + router.HandleFunc("/msg", handleIncomingMessage).Methods("POST") + log.Printf("Starting message server on port: 6969\n") + log.Printf("Waiting for incoming messages...\n") + log.Fatal(http.ListenAndServe(":6969", router)) +} + +func handleIncomingMessage(w http.ResponseWriter, r *http.Request) { + var messageEvent MessageEvent + + body, err := ioutil.ReadAll(r.Body) + if err != nil { + log.Fatalf("Error occured receiving message from client. Err: %s\n", err) + } + + json.Unmarshal(body, &messageEvent) + go appendMessage(messageEvent) + log.Printf("Received new message from client! Username: %s\n", messageEvent.Username) + + response := APIResponse{ + Code: "success", + Message: "Message has been received successfully!", + } + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(response) +} + +func appendMessage(message MessageEvent) { + f, err := os.OpenFile(fmt.Sprintf("%s.messages.log", message.Username), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println(err) + } + + defer f.Close() + if _, err := f.WriteString(fmt.Sprintf("%s\n", message.Message)); err != nil { + log.Println(err) + } +} + +func createUsernameFile() { + f, err := os.OpenFile(fmt.Sprintf(".tmsg-username"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + log.Println(err) + } + + defer f.Close() + if _, err := f.WriteString(options.MessageSender); err != nil { + log.Println(err) + } + + log.Printf("Username has been set to: %s\n", options.MessageSender) +} + +func readUsernameFile() { + content, err := ioutil.ReadFile(".tmsg-username") + + if err != nil { + log.Fatal("Please set a username first using the --username option. Ex: tmsg --username \"nick\"") + } + + if len(string(content)) < 1 { + log.Fatal("Please set a username first using the --username option. Ex: tmsg --username \"nick\"") + } + + options.MessageSender = string(content) +}