diff --git a/docs/wiki/guias-api/api-groups.md b/docs/wiki/guias-api/api-groups.md index de41ed7..7acaae8 100644 --- a/docs/wiki/guias-api/api-groups.md +++ b/docs/wiki/guias-api/api-groups.md @@ -6,6 +6,7 @@ Documentação completa dos endpoints para gerenciar grupos WhatsApp. - [Listar Grupos](#listar-grupos) - [Informações do Grupo](#informações-do-grupo) +- [Informações via Link de Convite](#informações-via-link-de-convite) - [Link de Convite](#link-de-convite) - [Criar Grupo](#criar-grupo) - [Gerenciar Participantes](#gerenciar-participantes) @@ -141,11 +142,57 @@ curl -X POST http://localhost:4000/group/info \ "groupJid": "120363XXXXXXXXXX@g.us" }' ``` +--- + +## Informações via Link de Convite + +Obtém informações de um grupo através de um link de convite sem precisar entrar nele. + +**Endpoint**: `POST /group/invite-info` + +**Body**: +```json +{ +"code": "https://chat.whatsapp.com/ABCDEFGHIJKLMNOP" +} +``` + +**Parâmetros**: + +| Campo | Tipo | Obrigatório | Descrição | +|-------|------|-------------|-----------| +| `code` | string | ✅ Sim | Código do link ou URL completa | + +**Resposta de Sucesso (200)**: +```json +{ +"message": "success", +"data": { + "JID": "120363XXXXXXXXXX@g.us", + "OwnerJID": "5511999999999@s.whatsapp.net", + "GroupName": { + "Name": "Nome do Grupo", + "NameSetAt": "2025-01-15T10:30:00Z", + "NameSetBy": "5511999999999@s.whatsapp.net" + }, + "GroupCreated": "2025-01-15T10:00:00Z" +} +} +``` + +**Exemplo cURL**: +```bash +curl -X POST http://localhost:4000/group/invite-info \ +-H "Content-Type: application/json" \ +-H "apikey: SUA-CHAVE-API" \ +-d '{ + "code": "https://chat.whatsapp.com/ABCDEFGHIJKLMNOP" +}' +``` --- ## Link de Convite - Obtém ou regenera o link de convite do grupo. **Endpoint**: `POST /group/invitelink` diff --git a/pkg/group/handler/group_handler.go b/pkg/group/handler/group_handler.go index 4136266..ad4cef6 100644 --- a/pkg/group/handler/group_handler.go +++ b/pkg/group/handler/group_handler.go @@ -12,6 +12,7 @@ type GroupHandler interface { ListGroups(ctx *gin.Context) GetGroupInfo(ctx *gin.Context) GetGroupInviteLink(ctx *gin.Context) + GetGroupInfoFromInviteLink(ctx *gin.Context) SetGroupPhoto(ctx *gin.Context) SetGroupName(ctx *gin.Context) SetGroupDescription(ctx *gin.Context) @@ -135,6 +136,47 @@ func (g *groupHandler) GetGroupInviteLink(ctx *gin.Context) { ctx.JSON(http.StatusOK, gin.H{"message": "success", "data": resp}) } +// Get group info from invite link +// @Summary Get group info from invite link +// @Description Get group info from invite link +// @Tags Group +// @Accept json +// @Produce json +// @Param message body group_service.GetGroupInfoFromInviteLinkStruct true "Group Invite Data" +// @Success 200 {object} gin.H "success" +// @Failure 400 {object} gin.H "Error on validation" +// @Failure 500 {object} gin.H "Internal server error" +// @Router /group/invite-info [post] +func (g *groupHandler) GetGroupInfoFromInviteLink(ctx *gin.Context) { + getInstance := ctx.MustGet("instance") + + instance, ok := getInstance.(*instance_model.Instance) + if !ok { + ctx.JSON(http.StatusInternalServerError, gin.H{"error": "instance not found"}) + return + } + + var data group_service.GetGroupInfoFromInviteLinkStruct + err := ctx.ShouldBindBodyWithJSON(&data) + if err != nil { + ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + if data.Code == "" { + ctx.JSON(http.StatusBadRequest, gin.H{"error": "code is required"}) + return + } + + resp, err := g.groupService.GetGroupInfoFromInviteLink(&data, instance) + if err != nil { + ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + ctx.JSON(http.StatusOK, gin.H{"message": "success", "data": resp}) +} + // Set group photo // @Summary Set group photo // @Description Set group photo diff --git a/pkg/group/service/group_service.go b/pkg/group/service/group_service.go index 227fef2..5a2d03c 100644 --- a/pkg/group/service/group_service.go +++ b/pkg/group/service/group_service.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "net/http" + "net/url" "strings" "time" @@ -23,6 +24,7 @@ type GroupService interface { ListGroups(instance *instance_model.Instance) ([]*types.GroupInfo, error) GetGroupInfo(data *GetGroupInfoStruct, instance *instance_model.Instance) (*types.GroupInfo, error) GetGroupInviteLink(data *GetGroupInviteLinkStruct, instance *instance_model.Instance) (string, error) + GetGroupInfoFromInviteLink(data *GetGroupInfoFromInviteLinkStruct, instance *instance_model.Instance) (*types.GroupInfo, error) SetGroupPhoto(data *SetGroupPhotoStruct, instance *instance_model.Instance) (string, error) SetGroupName(data *SetGroupNameStruct, instance *instance_model.Instance) error SetGroupDescription(data *SetGroupDescriptionStruct, instance *instance_model.Instance) error @@ -60,6 +62,10 @@ type GetGroupInviteLinkStruct struct { Reset bool `json:"reset"` } +type GetGroupInfoFromInviteLinkStruct struct { + Code string `json:"code"` +} + type SetGroupPhotoStruct struct { GroupJID string `json:"groupJid"` Image string `json:"image"` @@ -222,6 +228,37 @@ func (g *groupService) GetGroupInviteLink(data *GetGroupInviteLinkStruct, instan return resp, nil } +func extractInviteCode(code string) string { + code = strings.TrimSpace(code) + if strings.Contains(code, "chat.whatsapp.com/") { + u, err := url.Parse(code) + if err == nil { + pathParts := strings.Split(strings.Trim(u.Path, "/"), "/") + if len(pathParts) > 0 { + return pathParts[len(pathParts)-1] + } + } + } + return code +} + +func (g *groupService) GetGroupInfoFromInviteLink(data *GetGroupInfoFromInviteLinkStruct, instance *instance_model.Instance) (*types.GroupInfo, error) { + client, err := g.ensureClientConnected(instance.Id) + if err != nil { + return nil, err + } + + code := extractInviteCode(data.Code) + + resp, err := client.GetGroupInfoFromLink(context.Background(), code) + if err != nil { + g.loggerWrapper.GetLogger(instance.Id).LogError("[%s] error getting group info from link: %v", instance.Id, err) + return nil, err + } + + return resp, nil +} + func (g *groupService) SetGroupPhoto(data *SetGroupPhotoStruct, instance *instance_model.Instance) (string, error) { client, err := g.ensureClientConnected(instance.Id) if err != nil { @@ -443,7 +480,8 @@ func (g *groupService) JoinGroupLink(data *JoinGroupStruct, instance *instance_m return err } - _, err = client.JoinGroupWithLink(context.Background(), data.Code) + code := extractInviteCode(data.Code) + _, err = client.JoinGroupWithLink(context.Background(), code) if err != nil { g.loggerWrapper.GetLogger(instance.Id).LogError("[%s] error create group: %v", instance.Id, err) return err diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index 0064014..e3daa8e 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -175,6 +175,7 @@ func (r *Routes) AssignRoutes(eng *gin.Engine) { routes.GET("/list", r.groupHandler.ListGroups) routes.POST("/info", r.jidValidationMiddleware.ValidateNumberField(), r.groupHandler.GetGroupInfo) routes.POST("/invitelink", r.jidValidationMiddleware.ValidateNumberField(), r.groupHandler.GetGroupInviteLink) + routes.POST("/invite-info", r.groupHandler.GetGroupInfoFromInviteLink) routes.POST("/photo", r.jidValidationMiddleware.ValidateNumberField(), r.groupHandler.SetGroupPhoto) routes.POST("/name", r.jidValidationMiddleware.ValidateNumberField(), r.groupHandler.SetGroupName) routes.POST("/description", r.jidValidationMiddleware.ValidateNumberField(), r.groupHandler.SetGroupDescription)