package main import ( "context" "time" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/template/html/v2" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) var mongoClient *mongo.Client type User struct { Username string Email string } type Message struct { ID primitive.ObjectID `bson:"_id"` Content string `bson:"message"` Role string `bson:"role"` Date time.Time `bson:"date"` } type Conversation struct { ID string Messages []Message } func connectToMongoDB(uri string) { serverAPI := options.ServerAPI(options.ServerAPIVersion1) opts := options.Client().ApplyURI(uri).SetServerAPIOptions(serverAPI) client, err := mongo.Connect(context.TODO(), opts) if err != nil { panic(err) } mongoClient = client if err := mongoClient.Ping(context.TODO(), nil); err != nil { panic(err) } } func main() { // Create new Fiber instance. Can use any framework. I use fiber for speed and simplicity engine := html.New("./layouts", ".html") app := fiber.New(fiber.Config{ Views: engine, AppName: "JADE 2.0", EnablePrintRoutes: true, }) // Initialize go connectToMongoDB("mongodb://localhost:27017") // Add default logger app.Use(logger.New()) // Add static files app.Static("/", "./static") // Add routes app.Get("/", indexHandler) app.Get("/isMongoDBConnected", isMongoDBConnectedHandler) app.Get("/chat", chatPageHandler) // Complete chat page app.Put("/chat", addMessageHandler) // Add message app.Delete("/chat", deleteMessageHandler) // Delete message // Start server app.Listen(":3000") } func indexHandler(c *fiber.Ctx) error { return c.Render("base", fiber.Map{}, "welcome") } func chatPageHandler(c *fiber.Ctx) error { return c.Render("base", nil, "chat") } func addMessageHandler(c *fiber.Ctx) error { message := c.FormValue("message") collection := mongoClient.Database("chat").Collection("messages") collection.InsertOne(context.Background(), bson.M{"message": message, "role": "user", "date": time.Now()}) collection.InsertOne(context.Background(), bson.M{"message": "I did something!", "role": "bot", "date": time.Now()}) return generateChatHTML(c) } func deleteMessageHandler(c *fiber.Ctx) error { messageId := c.FormValue("messageId") // Convert the string ID to a MongoDB ObjectID objID, err := primitive.ObjectIDFromHex(messageId) if err != nil { // If the conversion fails, return an error response return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid message ID format", }) } // Delete messages in the database. This one and all the following ones collection := mongoClient.Database("chat").Collection("messages") // Get the date of the message var message Message err = collection.FindOne(context.TODO(), bson.M{"_id": objID}).Decode(&message) if err != nil { if err == mongo.ErrNoDocuments { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ "error": "Message not found", }) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to find message", }) } // Delete the message and all messages with a date after the specified date filter := bson.M{ "$or": []bson.M{ {"_id": objID}, {"date": bson.M{"$gt": message.Date}}, }, } _, err = collection.DeleteMany(context.TODO(), filter) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to delete messages", }) } return generateChatHTML(c) } func generateChatHTML(c *fiber.Ctx) error { // Get the messages from the database collection := mongoClient.Database("chat").Collection("messages") // Get all messages cursor, err := collection.Find(context.TODO(), bson.D{}) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to find messages", }) } // Convert the cursor to an array of messages var messages []Message if err = cursor.All(context.TODO(), &messages); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to convert cursor to array", }) } // Render the HTML template with the messages return c.Render("chat", fiber.Map{ "messages": messages, }) } func isMongoDBConnectedHandler(c *fiber.Ctx) error { if mongoClient != nil { return c.SendString("

Connected

") } return c.SendString("

Not connected

") }