diff --git a/.gitignore b/.gitignore
index 03ad15e..83e4eeb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,12 @@ coverage.*
.idea/
.vscode/
.DS_Store
+manager/node_modules/
+manager/src/
+manager/package.json
+manager/package-lock.json
+manager/postcss.config.js
+manager/tailwind.config.ts
+manager/tsconfig*.json
+manager/vite.config.ts
+manager/index.html
diff --git a/Dockerfile b/Dockerfile
index 4c0c7d6..319b1f5 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -27,6 +27,7 @@ WORKDIR /app
COPY --from=build /build/server .
COPY --from=build /build/manager/dist ./manager/dist
+COPY --from=build /build/manager/dashboard ./manager/dashboard
COPY --from=build /build/VERSION ./VERSION
ENV TZ=America/Sao_Paulo
diff --git a/cmd/evolution-go/main.go b/cmd/evolution-go/main.go
index d9ad785..0ca3806 100644
--- a/cmd/evolution-go/main.go
+++ b/cmd/evolution-go/main.go
@@ -29,6 +29,7 @@ import (
community_service "github.com/EvolutionAPI/evolution-go/pkg/community/service"
config "github.com/EvolutionAPI/evolution-go/pkg/config"
"github.com/EvolutionAPI/evolution-go/pkg/core"
+ "github.com/EvolutionAPI/evolution-go/pkg/metrics"
producer_interfaces "github.com/EvolutionAPI/evolution-go/pkg/events/interfaces"
nats_producer "github.com/EvolutionAPI/evolution-go/pkg/events/nats"
rabbitmq_producer "github.com/EvolutionAPI/evolution-go/pkg/events/rabbitmq"
@@ -158,6 +159,7 @@ func setupRouter(db *gorm.DB, authDB *sql.DB, sqliteDB *sql.DB, config *config.C
}
instanceRepository := instance_repository.NewInstanceRepository(db)
+
messageRepository := message_repository.NewMessageRepository(db)
labelRepository := label_repository.NewLabelRepository(db)
@@ -201,6 +203,10 @@ func setupRouter(db *gorm.DB, authDB *sql.DB, sqliteDB *sql.DB, config *config.C
r := gin.Default()
+ metricsRegistry := metrics.New(version, instanceRepository)
+ r.Use(metricsRegistry.GinMiddleware())
+ r.GET("/metrics", gin.WrapH(metricsRegistry.Handler()))
+
// CORS middleware — must be before everything else
r.Use(func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
diff --git a/go.mod b/go.mod
index ef2a864..e3a5169 100644
--- a/go.mod
+++ b/go.mod
@@ -14,6 +14,7 @@ require (
github.com/minio/minio-go/v7 v7.0.80
github.com/nats-io/nats.go v1.39.0
github.com/patrickmn/go-cache v2.1.0+incompatible
+ github.com/prometheus/client_golang v1.20.5
github.com/rabbitmq/amqp091-go v1.10.0
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/swaggo/files v1.0.1
@@ -35,8 +36,10 @@ require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/beeper/argo-go v1.1.2 // indirect
+ github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.12.2 // indirect
github.com/bytedance/sonic/loader v0.2.0 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/coder/websocket v1.8.14 // indirect
@@ -70,11 +73,15 @@ require (
github.com/minio/md5-simd v1.1.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nats-io/nkeys v0.4.9 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 // indirect
+ github.com/prometheus/client_model v0.6.1 // indirect
+ github.com/prometheus/common v0.55.0 // indirect
+ github.com/prometheus/procfs v0.15.1 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/xid v1.6.0 // indirect
diff --git a/go.sum b/go.sum
index 4ec26f6..a99e7ae 100644
--- a/go.sum
+++ b/go.sum
@@ -10,11 +10,15 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/beeper/argo-go v1.1.2 h1:UQI2G8F+NLfGTOmTUI0254pGKx/HUU/etbUGTJv91Fs=
github.com/beeper/argo-go v1.1.2/go.mod h1:M+LJAnyowKVQ6Rdj6XYGEn+qcVFkb3R/MUpqkGR0hM4=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg=
github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
@@ -102,6 +106,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
@@ -126,6 +132,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nats-io/nats.go v1.39.0 h1:2/yg2JQjiYYKLwDuBzV0FbB2sIV+eFNkEevlRi4n9lI=
github.com/nats-io/nats.go v1.39.0/go.mod h1:MgRb8oOdigA6cYpEPhXJuRVH6UE/V4jblJ2jQ27IXYM=
github.com/nats-io/nkeys v0.4.9 h1:qe9Faq2Gxwi6RZnZMXfmGMZkg3afLLOtrU+gDZJ35b0=
@@ -143,6 +151,14 @@ github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741/go.mod h1:pxMtw7c
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
+github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
+github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
+github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
+github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
+github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
diff --git a/manager/dashboard/index.html b/manager/dashboard/index.html
new file mode 100644
index 0000000..ea4d4d0
--- /dev/null
+++ b/manager/dashboard/index.html
@@ -0,0 +1,258 @@
+
+
+
+
+
+ Evolution GO Manager
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Dashboard
+
Visão geral das instâncias WhatsApp
+
+
+
+
+
+
+
+
+
Total de Instâncias
+
+
+
…
+
registradas no sistema
+
+
+
+
+
+
+
…
+
aguardando reconexão
+
+
+
+
+
+
+
+
+
Instâncias
+
Atualizado automaticamente a cada 30s
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pkg/chat/handler/chat_handler.go b/pkg/chat/handler/chat_handler.go
index 8240bc7..bc84a6e 100644
--- a/pkg/chat/handler/chat_handler.go
+++ b/pkg/chat/handler/chat_handler.go
@@ -204,7 +204,7 @@ func (c *chatHandler) ChatUnarchive(ctx *gin.Context) {
// Mute a chat
// @Summary Mute a chat
-// @Description Mute a chat
+// @Description Mute a chat. Set duration to the number of seconds to mute (e.g. 28800 = 8 hours, 604800 = 1 week). Use 0 to mute forever.
// @Tags Chat
// @Accept json
// @Produce json
diff --git a/pkg/chat/service/chat_service.go b/pkg/chat/service/chat_service.go
index 0255c82..79aab6b 100644
--- a/pkg/chat/service/chat_service.go
+++ b/pkg/chat/service/chat_service.go
@@ -3,6 +3,7 @@ package chat_service
import (
"context"
"errors"
+ "fmt"
"time"
instance_model "github.com/EvolutionAPI/evolution-go/pkg/instance/model"
@@ -32,6 +33,8 @@ type chatService struct {
type BodyStruct struct {
Chat string `json:"chat"`
+ // Duration is used by mute operations: seconds to mute (0 = mute forever).
+ Duration int64 `json:"duration,omitempty"`
}
type HistorySyncRequestStruct struct {
@@ -170,12 +173,22 @@ func (c *chatService) ChatUnarchive(data *BodyStruct, instance *instance_model.I
return ts.String(), nil
}
+// maxMuteDurationSeconds caps mute at 1 year to avoid unreasonably large timestamps.
+const maxMuteDurationSeconds = 365 * 24 * 3600
+
func (c *chatService) ChatMute(data *BodyStruct, instance *instance_model.Instance) (string, error) {
client, err := c.ensureClientConnected(instance.Id)
if err != nil {
return "", err
}
+ if data.Duration < 0 {
+ return "", errors.New("duration must be >= 0 (0 = mute forever)")
+ }
+ if data.Duration > maxMuteDurationSeconds {
+ return "", fmt.Errorf("duration exceeds maximum allowed value of %d seconds (1 year)", maxMuteDurationSeconds)
+ }
+
var ts time.Time
recipient, ok := utils.ParseJID(data.Chat)
@@ -184,7 +197,9 @@ func (c *chatService) ChatMute(data *BodyStruct, instance *instance_model.Instan
return "", errors.New("invalid phone number")
}
- err = client.SendAppState(context.Background(), appstate.BuildMute(recipient, true, 1*time.Hour))
+ // duration=0 is passed as-is: BuildMute treats 0 as "mute forever" (sets timestamp to -1).
+ muteDuration := time.Duration(data.Duration) * time.Second
+ err = client.SendAppState(context.Background(), appstate.BuildMute(recipient, true, muteDuration))
if err != nil {
c.loggerWrapper.GetLogger(instance.Id).LogError("[%s] error mute chat: %v", instance.Id, err)
return "", err
diff --git a/pkg/instance/repository/instance_repository.go b/pkg/instance/repository/instance_repository.go
index cfb60b4..9450e7b 100644
--- a/pkg/instance/repository/instance_repository.go
+++ b/pkg/instance/repository/instance_repository.go
@@ -29,6 +29,7 @@ type InstanceRepository interface {
GetAllConnectedInstances() ([]*instance_model.Instance, error)
GetAllConnectedInstancesByClientName(clientName string) ([]*instance_model.Instance, error)
GetAll(clientName string) ([]*instance_model.Instance, error)
+ GetAllInstances() ([]*instance_model.Instance, error)
Delete(instanceId string) error
GetAdvancedSettings(instanceId string) (*instance_model.AdvancedSettings, error)
UpdateAdvancedSettings(instanceId string, settings *instance_model.AdvancedSettings) error
@@ -146,6 +147,12 @@ func (i *instanceRepository) GetAll(clientName string) ([]*instance_model.Instan
return instances, nil
}
+func (i *instanceRepository) GetAllInstances() ([]*instance_model.Instance, error) {
+ var instances []*instance_model.Instance
+ err := i.db.Find(&instances).Error
+ return instances, err
+}
+
func (i *instanceRepository) Delete(instanceId string) error {
return i.db.Transaction(func(tx *gorm.DB) error {
// Deleta todas as labels associadas à instância
diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go
new file mode 100644
index 0000000..9082629
--- /dev/null
+++ b/pkg/metrics/metrics.go
@@ -0,0 +1,155 @@
+package metrics
+
+import (
+ "net/http"
+ "strconv"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promhttp"
+
+ instance_repository "github.com/EvolutionAPI/evolution-go/pkg/instance/repository"
+)
+
+// Registry holds all Prometheus metrics for the application.
+type Registry struct {
+ reg *prometheus.Registry
+ httpRequests *prometheus.CounterVec
+ httpDuration *prometheus.HistogramVec
+}
+
+// New creates a Registry and registers all metrics.
+// version is embedded as a label in the build_info gauge.
+func New(version string, instanceRepo instance_repository.InstanceRepository) *Registry {
+ reg := prometheus.NewRegistry()
+
+ httpRequests := prometheus.NewCounterVec(prometheus.CounterOpts{
+ Name: "evolution_http_requests_total",
+ Help: "Total number of HTTP requests partitioned by method, path and status code.",
+ }, []string{"method", "path", "status"})
+
+ httpDuration := prometheus.NewHistogramVec(prometheus.HistogramOpts{
+ Name: "evolution_http_request_duration_seconds",
+ Help: "HTTP request latency in seconds partitioned by method and path.",
+ Buckets: prometheus.DefBuckets,
+ }, []string{"method", "path"})
+
+ buildInfo := prometheus.NewGaugeVec(prometheus.GaugeOpts{
+ Name: "evolution_build_info",
+ Help: "Build information. Always 1; use the 'version' label to read the value.",
+ }, []string{"version"})
+ buildInfo.WithLabelValues(version).Set(1)
+
+ startTime := time.Now()
+ uptimeGauge := prometheus.NewGaugeFunc(prometheus.GaugeOpts{
+ Name: "evolution_uptime_seconds",
+ Help: "Number of seconds since the server started.",
+ }, func() float64 {
+ return time.Since(startTime).Seconds()
+ })
+
+ reg.MustRegister(
+ httpRequests,
+ httpDuration,
+ buildInfo,
+ uptimeGauge,
+ newInstanceCollector(instanceRepo),
+ )
+
+ return &Registry{
+ reg: reg,
+ httpRequests: httpRequests,
+ httpDuration: httpDuration,
+ }
+}
+
+// Handler returns an http.Handler that serves the Prometheus metrics page.
+func (r *Registry) Handler() http.Handler {
+ return promhttp.HandlerFor(r.reg, promhttp.HandlerOpts{})
+}
+
+// GinMiddleware returns a Gin middleware that records HTTP request counts and latencies.
+// The /metrics path itself is excluded to avoid self-referential noise.
+func (r *Registry) GinMiddleware() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ if c.Request.URL.Path == "/metrics" {
+ c.Next()
+ return
+ }
+
+ start := time.Now()
+ c.Next()
+
+ // c.FullPath() returns the registered route pattern (e.g. /instance/:instanceId)
+ // which keeps cardinality bounded regardless of how many distinct IDs are used.
+ path := c.FullPath()
+ if path == "" {
+ path = "unmatched"
+ }
+
+ r.httpRequests.WithLabelValues(
+ c.Request.Method,
+ path,
+ strconv.Itoa(c.Writer.Status()),
+ ).Inc()
+
+ r.httpDuration.WithLabelValues(c.Request.Method, path).Observe(time.Since(start).Seconds())
+ }
+}
+
+// instanceCollector is a custom prometheus.Collector that queries the database at
+// scrape time so the gauge values are always current without requiring event hooks.
+type instanceCollector struct {
+ repo instance_repository.InstanceRepository
+ descTotal *prometheus.Desc
+ descConnected *prometheus.Desc
+ descDisconnected *prometheus.Desc
+}
+
+func newInstanceCollector(repo instance_repository.InstanceRepository) prometheus.Collector {
+ return &instanceCollector{
+ repo: repo,
+ descTotal: prometheus.NewDesc(
+ "evolution_instances_total",
+ "Total number of registered instances.",
+ nil, nil,
+ ),
+ descConnected: prometheus.NewDesc(
+ "evolution_instances_connected",
+ "Number of instances currently connected to WhatsApp.",
+ nil, nil,
+ ),
+ descDisconnected: prometheus.NewDesc(
+ "evolution_instances_disconnected",
+ "Number of instances currently disconnected from WhatsApp.",
+ nil, nil,
+ ),
+ }
+}
+
+func (c *instanceCollector) Describe(ch chan<- *prometheus.Desc) {
+ ch <- c.descTotal
+ ch <- c.descConnected
+ ch <- c.descDisconnected
+}
+
+func (c *instanceCollector) Collect(ch chan<- prometheus.Metric) {
+ instances, err := c.repo.GetAllInstances()
+ if err != nil {
+ // Emit nothing on error rather than stale data.
+ return
+ }
+
+ var connected float64
+ for _, inst := range instances {
+ if inst.Connected {
+ connected++
+ }
+ }
+ total := float64(len(instances))
+
+ ch <- prometheus.MustNewConstMetric(c.descTotal, prometheus.GaugeValue, total)
+ ch <- prometheus.MustNewConstMetric(c.descConnected, prometheus.GaugeValue, connected)
+ ch <- prometheus.MustNewConstMetric(c.descDisconnected, prometheus.GaugeValue, total-connected)
+}
diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go
index f51e7d9..3bf90b0 100644
--- a/pkg/routes/routes.go
+++ b/pkg/routes/routes.go
@@ -66,12 +66,13 @@ func (r *Routes) AssignRoutes(eng *gin.Engine) {
// Rotas para o gerenciador React (sem autenticação)
eng.Static("/assets", "./manager/dist/assets")
- // Ajuste nas rotas do manager para suportar client-side routing do React
- eng.GET("/manager/*any", func(c *gin.Context) {
- c.File("manager/dist/index.html")
+ // Dashboard com métricas reais (página standalone)
+ eng.GET("/manager", func(c *gin.Context) {
+ c.File("manager/dashboard/index.html")
})
- eng.GET("/manager", func(c *gin.Context) {
+ // Demais rotas do manager (instâncias, login, etc.) — bundle original
+ eng.GET("/manager/*any", func(c *gin.Context) {
c.File("manager/dist/index.html")
})
@@ -161,12 +162,12 @@ func (r *Routes) AssignRoutes(eng *gin.Engine) {
{
routes.Use(r.authMiddleware.Auth)
{
- routes.POST("/pin", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatPin) // TODO: not working
- routes.POST("/unpin", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatUnpin) // TODO: not working
- routes.POST("/archive", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatArchive) // TODO: not working
- routes.POST("/unarchive", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatUnarchive) // TODO: not working
- routes.POST("/mute", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatMute) // TODO: not working
- routes.POST("/unmute", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatUnmute) // TODO: not working
+ routes.POST("/pin", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatPin)
+ routes.POST("/unpin", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatUnpin)
+ routes.POST("/archive", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatArchive)
+ routes.POST("/unarchive", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatUnarchive)
+ routes.POST("/mute", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatMute)
+ routes.POST("/unmute", r.jidValidationMiddleware.ValidateNumberField(), r.chatHandler.ChatUnmute)
routes.POST("/history-sync", r.chatHandler.HistorySyncRequest)
}
}