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) }