-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'gabrielolivrp-refactor/architecture'
- Loading branch information
Showing
70 changed files
with
2,994 additions
and
2,620 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
ENV=development | ||
ENVIRONMENT=development | ||
PORT=:8900 | ||
REDIS_ADDR=localhost:6379 | ||
REDIS_PASSWORD= | ||
DATABASE_PATH=data.db | ||
STORAGE_PATH=storage | ||
DATABASE_PATH=.zapmeow/zapmeow.db | ||
STORAGE_PATH=.zapmeow/storage | ||
WEBHOOK_URL=http://localhost:3000/api/whatsapp/message |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,4 @@ storage | |
.env | ||
.env.production | ||
main | ||
zapmeow | ||
.zapmeow |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,58 +4,58 @@ ZapMeow is a versatile API that allows developers to interact with WhatsApp usin | |
|
||
### Features | ||
|
||
- **Multi-Instance Support**: Seamlessly manage and interact with multiple WhatsApp instances concurrently. | ||
- **Message Sending**: Send text, image, and audio messages to WhatsApp contacts and groups. | ||
- **Phone Number Verification**: Check if phone numbers are registered on WhatsApp. | ||
- **Contact Information**: Obtain contact information. | ||
- **Profile Information**: Obtain profile information. | ||
- **QR Code Generation**: Generate QR codes to initiate WhatsApp login. | ||
- **Instance Status**: Retrieve the connection status of a specific instance of WhatsApp. | ||
- **Multi-Instance Support**: Seamlessly manage and interact with multiple WhatsApp instances concurrently. | ||
- **Message Sending**: Send text, image, and audio messages to WhatsApp contacts and groups. | ||
- **Phone Number Verification**: Check if phone numbers are registered on WhatsApp. | ||
- **Contact Information**: Obtain contact information. | ||
- **Profile Information**: Obtain profile information. | ||
- **QR Code Generation**: Generate QR codes to initiate WhatsApp login. | ||
- **Instance Status**: Retrieve the connection status of a specific instance of WhatsApp. | ||
|
||
### Getting Started | ||
|
||
To get started with the ZapMeow API, follow these simple steps: | ||
|
||
1. **Clone the Repository**: Clone this repository to your local machine using the following command: | ||
|
||
```sh | ||
git clone [email protected]:capsulbrasil/zapmeow.git | ||
``` | ||
```sh | ||
git clone [email protected]:capsulbrasil/zapmeow.git | ||
``` | ||
|
||
2. **Configuration**: Set up your project configuration by copying the provided `.env.example` file and updating the environment variables. | ||
|
||
- Navigate to the project directory: | ||
- Navigate to the project directory: | ||
|
||
```sh | ||
cd zapmeow | ||
``` | ||
```sh | ||
cd zapmeow | ||
``` | ||
|
||
- Create a copy of the `.env.example` file as `.env`: | ||
- Create a copy of the `.env.example` file as `.env`: | ||
|
||
```sh | ||
cp .env.example .env | ||
``` | ||
```sh | ||
cp .env.example .env | ||
``` | ||
|
||
- Open the `.env` file using your preferred text editor and update the necessary environment variables. | ||
- Open the `.env` file using your preferred text editor and update the necessary environment variables. | ||
|
||
3. **Install Dependencies**: Install the project dependencies using the following command: | ||
|
||
```sh | ||
go mod tidy | ||
``` | ||
```sh | ||
go mod tidy | ||
``` | ||
|
||
4. **Start the API**: Run the API server by executing the following command: | ||
|
||
```sh | ||
go run main.go | ||
``` | ||
```sh | ||
./zapmeow | ||
``` | ||
|
||
5. **Access Swagger Documentation**: You can access the Swagger documentation by visiting the following URL in your web browser: | ||
|
||
``` | ||
http://localhost:8900/api/swagger/index.html | ||
``` | ||
``` | ||
http://localhost:8900/api/swagger/index.html | ||
``` | ||
|
||
The Swagger documentation provides detailed information about the available API endpoints, request parameters, and response formats. | ||
The Swagger documentation provides detailed information about the available API endpoints, request parameters, and response formats. | ||
|
||
Now, your ZapMeow API is up and running, ready for you to start interacting with WhatsApp instances programmatically. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package handler | ||
|
||
import ( | ||
"net/http" | ||
"zapmeow/api/response" | ||
"zapmeow/api/service" | ||
"zapmeow/pkg/whatsapp" | ||
|
||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
type getCheckPhonesBody struct { | ||
Phones []string `json:"phones"` | ||
} | ||
|
||
type getCheckPhonesResponse struct { | ||
Phones []whatsapp.IsOnWhatsAppResponse `json:"phones"` | ||
} | ||
|
||
type checkPhonesHandler struct { | ||
whatsAppService service.WhatsAppService | ||
} | ||
|
||
func NewCheckPhonesHandler( | ||
whatsAppService service.WhatsAppService, | ||
) *checkPhonesHandler { | ||
return &checkPhonesHandler{ | ||
whatsAppService: whatsAppService, | ||
} | ||
} | ||
|
||
// Check Phones on WhatsApp | ||
// | ||
// @Summary Check Phones on WhatsApp | ||
// @Description Verifies if the phone numbers in the provided list are registered WhatsApp users. | ||
// @Tags WhatsApp Phone Verification | ||
// @Param instanceId path string true "Instance ID" | ||
// @Param data body getCheckPhonesBody true "Phone list" | ||
// @Accept json | ||
// @Produce json | ||
// @Success 200 {object} getCheckPhonesResponse "List of verified numbers" | ||
// @Router /{instanceId}/check/phones [post] | ||
func (h *checkPhonesHandler) Handler(c *gin.Context) { | ||
var body getCheckPhonesBody | ||
if err := c.ShouldBindJSON(&body); err != nil { | ||
response.ErrorResponse(c, http.StatusBadRequest, "Error trying to validate infos. ") | ||
return | ||
} | ||
|
||
instanceID := c.Param("instanceId") | ||
instance, err := h.whatsAppService.GetInstance(instanceID) | ||
if err != nil { | ||
response.ErrorResponse(c, http.StatusInternalServerError, err.Error()) | ||
return | ||
} | ||
|
||
phones, err := h.whatsAppService.IsOnWhatsApp(instance, body.Phones) | ||
if err != nil { | ||
response.ErrorResponse(c, http.StatusInternalServerError, err.Error()) | ||
return | ||
} | ||
|
||
response.Response(c, http.StatusOK, getCheckPhonesResponse{ | ||
Phones: phones, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package handler | ||
|
||
import ( | ||
"net/http" | ||
"zapmeow/api/helper" | ||
"zapmeow/api/response" | ||
"zapmeow/api/service" | ||
"zapmeow/pkg/whatsapp" | ||
|
||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
type contactInfoResponse struct { | ||
Info whatsapp.ContactInfo `json:"info"` | ||
} | ||
|
||
type getContactInfoHandler struct { | ||
whatsAppService service.WhatsAppService | ||
} | ||
|
||
func NewGetContactInfoHandler( | ||
whatsAppService service.WhatsAppService, | ||
) *getContactInfoHandler { | ||
return &getContactInfoHandler{ | ||
whatsAppService: whatsAppService, | ||
} | ||
} | ||
|
||
// Get Contact Information | ||
// | ||
// @Summary Get Contact Information | ||
// @Description Retrieves contact information. | ||
// @Tags WhatsApp Contact | ||
// @Param instanceId path string true "Instance ID" | ||
// @Param phone query string true "Phone" | ||
// @Accept json | ||
// @Produce json | ||
// @Success 200 {object} contactInfoResponse "Contact Information" | ||
// @Router /{instanceId}/contact/info [get] | ||
func (h *getContactInfoHandler) Handler(c *gin.Context) { | ||
instanceID := c.Param("instanceId") | ||
instance, err := h.whatsAppService.GetInstance(instanceID) | ||
if err != nil { | ||
response.ErrorResponse(c, http.StatusInternalServerError, err.Error()) | ||
return | ||
} | ||
|
||
if !h.whatsAppService.IsAuthenticated(instance) { | ||
response.ErrorResponse(c, http.StatusUnauthorized, "unautenticated") | ||
return | ||
} | ||
|
||
phone := c.Query("phone") | ||
jid, ok := helper.MakeJID(phone) | ||
if !ok { | ||
response.ErrorResponse(c, http.StatusBadRequest, "Error trying to validate infos. ") | ||
return | ||
} | ||
|
||
info, err := h.whatsAppService.GetContactInfo(instance, jid) | ||
if err != nil || info == nil { | ||
response.ErrorResponse(c, http.StatusInternalServerError, err.Error()) | ||
return | ||
} | ||
|
||
response.Response(c, http.StatusOK, contactInfoResponse{ | ||
Info: *info, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package handler | ||
|
||
import ( | ||
"net/http" | ||
"zapmeow/api/response" | ||
"zapmeow/api/service" | ||
|
||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
type getMessagesBody struct { | ||
Phone string `json:"phone"` | ||
} | ||
|
||
type getMessagesResponse struct { | ||
Messages []response.Message `json:"messages"` | ||
} | ||
|
||
type getMessagesHandler struct { | ||
whatsAppService service.WhatsAppService | ||
messageService service.MessageService | ||
} | ||
|
||
func NewGetMessagesHandler( | ||
whatsAppService service.WhatsAppService, | ||
messageService service.MessageService, | ||
) *getMessagesHandler { | ||
return &getMessagesHandler{ | ||
whatsAppService: whatsAppService, | ||
messageService: messageService, | ||
} | ||
} | ||
|
||
// Get WhatsApp Chat Messages | ||
// | ||
// @Summary Get WhatsApp Chat Messages | ||
// @Description Returns chat messages from the specified WhatsApp instance. | ||
// @Tags WhatsApp Chat | ||
// @Param instanceId path string true "Instance ID" | ||
// @Param data body getMessagesBody true "Phone" | ||
// @Accept json | ||
// @Produce json | ||
// @Success 200 {object} getMessagesResponse "List of chat messages" | ||
// @Router /{instanceId}/chat/messages [post] | ||
func (h *getMessagesHandler) Handler(c *gin.Context) { | ||
instanceID := c.Param("instanceId") | ||
instance, err := h.whatsAppService.GetInstance(instanceID) | ||
if err != nil { | ||
response.ErrorResponse(c, http.StatusInternalServerError, err.Error()) | ||
return | ||
} | ||
|
||
if !h.whatsAppService.IsAuthenticated(instance) { | ||
response.ErrorResponse(c, http.StatusUnauthorized, "unautenticated") | ||
return | ||
} | ||
|
||
var body getMessagesBody | ||
if err := c.ShouldBindJSON(&body); err != nil { | ||
response.ErrorResponse(c, http.StatusBadRequest, "Error trying to validate infos. ") | ||
return | ||
} | ||
|
||
messages, err := h.messageService.GetChatMessages( | ||
instanceID, | ||
body.Phone, | ||
) | ||
if err != nil { | ||
response.ErrorResponse(c, http.StatusInternalServerError, err.Error()) | ||
return | ||
} | ||
|
||
response.Response(c, http.StatusOK, getMessagesResponse{ | ||
Messages: response.NewMessagesResponse(messages), | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package handler | ||
|
||
import ( | ||
"net/http" | ||
"zapmeow/api/helper" | ||
"zapmeow/api/response" | ||
"zapmeow/api/service" | ||
"zapmeow/pkg/whatsapp" | ||
|
||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
type getProfileInfoResponse struct { | ||
Info whatsapp.ContactInfo `json:"info"` | ||
} | ||
|
||
type getProfileInfoHandler struct { | ||
whatsAppService service.WhatsAppService | ||
} | ||
|
||
func NewGetProfileInfoHandler( | ||
whatsAppService service.WhatsAppService, | ||
) *getProfileInfoHandler { | ||
return &getProfileInfoHandler{ | ||
whatsAppService: whatsAppService, | ||
} | ||
} | ||
|
||
// Get Profile Information | ||
// | ||
// @Summary Get Profile Information | ||
// @Description Retrieves profile information. | ||
// @Tags WhatsApp Profile | ||
// @Param instanceId path string true "Instance ID" | ||
// @Accept json | ||
// @Produce json | ||
// @Success 200 {object} getProfileInfoResponse "Profile Information" | ||
// @Router /{instanceId}/profile [get] | ||
func (h *getProfileInfoHandler) Handler(c *gin.Context) { | ||
instanceID := c.Param("instanceId") | ||
instance, err := h.whatsAppService.GetInstance(instanceID) | ||
if err != nil { | ||
response.ErrorResponse(c, http.StatusInternalServerError, err.Error()) | ||
return | ||
} | ||
|
||
if !h.whatsAppService.IsAuthenticated(instance) { | ||
response.ErrorResponse(c, http.StatusUnauthorized, "unautenticated") | ||
return | ||
} | ||
|
||
jid, ok := helper.MakeJID(instance.Client.Store.ID.User) | ||
if !ok { | ||
response.ErrorResponse(c, http.StatusBadRequest, "Error trying to validate infos. ") | ||
return | ||
} | ||
|
||
info, err := h.whatsAppService.GetContactInfo(instance, jid) | ||
if err != nil || info == nil { | ||
response.ErrorResponse(c, http.StatusInternalServerError, err.Error()) | ||
return | ||
} | ||
|
||
response.Response(c, http.StatusOK, getProfileInfoResponse{ | ||
Info: *info, | ||
}) | ||
} |
Oops, something went wrong.