whatsapp-multi-devicewhatsapp-apiwhatsapprestgolanggogolang-whatsapp-apigolang-whatsappbotwhatsapp-web-multi-devicewhatsapp-api-gorest-api
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
5.1 KiB
171 lines
5.1 KiB
package services
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/aldinokemal/go-whatsapp-web-multidevice/config"
|
|
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
|
|
"github.com/aldinokemal/go-whatsapp-web-multidevice/utils"
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/h2non/bimg"
|
|
"go.mau.fi/whatsmeow"
|
|
waProto "go.mau.fi/whatsmeow/binary/proto"
|
|
"google.golang.org/protobuf/proto"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
type SendServiceImpl struct {
|
|
WaCli *whatsmeow.Client
|
|
}
|
|
|
|
func NewSendService(waCli *whatsmeow.Client) SendService {
|
|
return &SendServiceImpl{
|
|
WaCli: waCli,
|
|
}
|
|
}
|
|
|
|
func (service SendServiceImpl) SendText(_ *fiber.Ctx, request structs.SendMessageRequest) (response structs.SendMessageResponse, err error) {
|
|
utils.MustLogin(service.WaCli)
|
|
|
|
recipient, ok := utils.ParseJID(request.Phone)
|
|
if !ok {
|
|
return response, errors.New("invalid JID " + request.Phone)
|
|
}
|
|
msg := &waProto.Message{Conversation: proto.String(request.Message)}
|
|
ts, err := service.WaCli.SendMessage(recipient, "", msg)
|
|
if err != nil {
|
|
return response, err
|
|
} else {
|
|
response.Status = fmt.Sprintf("Message sent to %s (server timestamp: %s)", request.Phone, ts)
|
|
}
|
|
return response, nil
|
|
}
|
|
|
|
func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImageRequest) (response structs.SendImageResponse, err error) {
|
|
utils.MustLogin(service.WaCli)
|
|
|
|
// Resize image
|
|
oriImagePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.Image.Filename)
|
|
err = c.SaveFile(request.Image, oriImagePath)
|
|
if err != nil {
|
|
return response, err
|
|
}
|
|
openImageBuffer, err := bimg.Read(oriImagePath)
|
|
newImage, err := bimg.NewImage(openImageBuffer).Process(bimg.Options{Quality: 90, Width: 600, Height: 600, Embed: true})
|
|
if err != nil {
|
|
return response, err
|
|
}
|
|
|
|
newImagePath := fmt.Sprintf("%s/new-%s", config.PathSendItems, request.Image.Filename)
|
|
err = bimg.Write(newImagePath, newImage)
|
|
if err != nil {
|
|
return response, err
|
|
}
|
|
|
|
removeFile := func(paths ...string) {
|
|
time.Sleep(5 * time.Second)
|
|
for _, path := range paths {
|
|
err := os.Remove(path)
|
|
if err != nil {
|
|
fmt.Println("error when delete " + path)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Send to WA server
|
|
dataWaCaption := request.Caption
|
|
dataWaRecipient, ok := utils.ParseJID(request.Phone)
|
|
if !ok {
|
|
return response, errors.New("invalid JID " + request.Phone)
|
|
}
|
|
dataWaImage, err := os.ReadFile(newImagePath)
|
|
if err != nil {
|
|
return response, err
|
|
}
|
|
uploadedImage, err := service.WaCli.Upload(context.Background(), dataWaImage, whatsmeow.MediaImage)
|
|
if err != nil {
|
|
fmt.Printf("Failed to upload file: %v", err)
|
|
return response, err
|
|
}
|
|
|
|
msg := &waProto.Message{ImageMessage: &waProto.ImageMessage{
|
|
Caption: proto.String(dataWaCaption),
|
|
Url: proto.String(uploadedImage.URL),
|
|
DirectPath: proto.String(uploadedImage.DirectPath),
|
|
MediaKey: uploadedImage.MediaKey,
|
|
Mimetype: proto.String(http.DetectContentType(dataWaImage)),
|
|
FileEncSha256: uploadedImage.FileEncSHA256,
|
|
FileSha256: uploadedImage.FileSHA256,
|
|
FileLength: proto.Uint64(uint64(len(dataWaImage))),
|
|
ViewOnce: proto.Bool(request.ViewOnce),
|
|
}}
|
|
ts, err := service.WaCli.SendMessage(dataWaRecipient, "", msg)
|
|
go removeFile(oriImagePath, newImagePath)
|
|
if err != nil {
|
|
return response, err
|
|
} else {
|
|
response.Status = fmt.Sprintf("Message sent to %s (server timestamp: %s)", request.Phone, ts)
|
|
return response, nil
|
|
}
|
|
}
|
|
|
|
func (service SendServiceImpl) SendFile(c *fiber.Ctx, request structs.SendFileRequest) (response structs.SendFileResponse, err error) {
|
|
utils.MustLogin(service.WaCli)
|
|
|
|
// Resize image
|
|
oriFilePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.File.Filename)
|
|
err = c.SaveFile(request.File, oriFilePath)
|
|
if err != nil {
|
|
return response, err
|
|
}
|
|
|
|
removeFile := func(paths ...string) {
|
|
time.Sleep(5 * time.Second)
|
|
for _, path := range paths {
|
|
err := os.Remove(path)
|
|
if err != nil {
|
|
fmt.Println("error when delete " + path)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Send to WA server
|
|
dataWaRecipient, ok := utils.ParseJID(request.Phone)
|
|
if !ok {
|
|
return response, errors.New("invalid JID " + request.Phone)
|
|
}
|
|
dataWaFile, err := os.ReadFile(oriFilePath)
|
|
if err != nil {
|
|
return response, err
|
|
}
|
|
uploadedFile, err := service.WaCli.Upload(context.Background(), dataWaFile, whatsmeow.MediaDocument)
|
|
if err != nil {
|
|
fmt.Printf("Failed to upload file: %v", err)
|
|
return response, err
|
|
}
|
|
|
|
msg := &waProto.Message{DocumentMessage: &waProto.DocumentMessage{
|
|
Url: proto.String(uploadedFile.URL),
|
|
Mimetype: proto.String(http.DetectContentType(dataWaFile)),
|
|
Title: proto.String(request.File.Filename),
|
|
FileSha256: uploadedFile.FileSHA256,
|
|
FileLength: proto.Uint64(uploadedFile.FileLength),
|
|
MediaKey: uploadedFile.MediaKey,
|
|
FileName: proto.String(request.File.Filename),
|
|
FileEncSha256: uploadedFile.FileEncSHA256,
|
|
DirectPath: proto.String(uploadedFile.DirectPath),
|
|
}}
|
|
ts, err := service.WaCli.SendMessage(dataWaRecipient, "", msg)
|
|
go removeFile(oriFilePath)
|
|
if err != nil {
|
|
return response, err
|
|
} else {
|
|
response.Status = fmt.Sprintf("Message sent to %s (server timestamp: %s)", request.Phone, ts)
|
|
return response, nil
|
|
}
|
|
}
|