gowhatsapp-multi-devicewhatsapp-apiwhatsapprestgolangwhatsapp-web-multi-devicewhatsapp-api-gorest-apigolang-whatsapp-apigolang-whatsappbot
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.
181 lines
4.5 KiB
181 lines
4.5 KiB
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/PuerkitoBio/goquery"
|
|
"github.com/aldinokemal/go-whatsapp-web-multidevice/config"
|
|
)
|
|
|
|
// RemoveFile is removing file with delay
|
|
func RemoveFile(delaySecond int, paths ...string) error {
|
|
if delaySecond > 0 {
|
|
time.Sleep(time.Duration(delaySecond) * time.Second)
|
|
}
|
|
|
|
for _, path := range paths {
|
|
if path != "" {
|
|
err := os.Remove(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CreateFolder create new folder and sub folder if not exist
|
|
func CreateFolder(folderPath ...string) error {
|
|
for _, folder := range folderPath {
|
|
newFolder := filepath.Join(".", folder)
|
|
err := os.MkdirAll(newFolder, os.ModePerm)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// PanicIfNeeded is panic if error is not nil
|
|
func PanicIfNeeded(err any, message ...string) {
|
|
if err != nil {
|
|
if fmt.Sprintf("%s", err) == "record not found" && len(message) > 0 {
|
|
panic(message[0])
|
|
} else {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func StrToFloat64(text string) float64 {
|
|
var result float64
|
|
if text != "" {
|
|
result, _ = strconv.ParseFloat(strings.TrimSpace(text), 64)
|
|
}
|
|
return result
|
|
}
|
|
|
|
type Metadata struct {
|
|
Title string
|
|
Description string
|
|
Image string
|
|
ImageThumb []byte
|
|
}
|
|
|
|
func GetMetaDataFromURL(url string) (meta Metadata) {
|
|
// Send an HTTP GET request to the website
|
|
response, err := http.Get(url)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer response.Body.Close()
|
|
|
|
// Parse the HTML document
|
|
document, err := goquery.NewDocumentFromReader(response.Body)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
document.Find("meta[name='description']").Each(func(index int, element *goquery.Selection) {
|
|
meta.Description, _ = element.Attr("content")
|
|
})
|
|
|
|
// find title
|
|
document.Find("title").Each(func(index int, element *goquery.Selection) {
|
|
meta.Title = element.Text()
|
|
})
|
|
|
|
document.Find("meta[property='og:image']").Each(func(index int, element *goquery.Selection) {
|
|
meta.Image, _ = element.Attr("content")
|
|
})
|
|
|
|
// If an og:image is found, download it and store its content in ImageThumb
|
|
if meta.Image != "" {
|
|
imageResponse, err := http.Get(meta.Image)
|
|
if err != nil {
|
|
log.Printf("Failed to download image: %v", err)
|
|
} else {
|
|
defer imageResponse.Body.Close()
|
|
imageData, err := io.ReadAll(imageResponse.Body)
|
|
if err != nil {
|
|
log.Printf("Failed to read image data: %v", err)
|
|
} else {
|
|
meta.ImageThumb = imageData
|
|
}
|
|
}
|
|
}
|
|
|
|
return meta
|
|
}
|
|
|
|
// ContainsMention is checking if message contains mention, then return only mention without @
|
|
func ContainsMention(message string) []string {
|
|
// Regular expression to find all phone numbers after the @ symbol
|
|
re := regexp.MustCompile(`@(\d+)`)
|
|
matches := re.FindAllStringSubmatch(message, -1)
|
|
|
|
var phoneNumbers []string
|
|
// Loop through the matches and extract the phone numbers
|
|
for _, match := range matches {
|
|
if len(match) > 1 {
|
|
phoneNumbers = append(phoneNumbers, match[1])
|
|
}
|
|
}
|
|
return phoneNumbers
|
|
}
|
|
|
|
func DownloadImageFromURL(url string) ([]byte, string, error) {
|
|
client := &http.Client{
|
|
Timeout: 30 * time.Second,
|
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
if len(via) >= 10 {
|
|
return fmt.Errorf("too many redirects")
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
response, err := client.Get(url)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
defer response.Body.Close()
|
|
contentType := response.Header.Get("Content-Type")
|
|
if !strings.HasPrefix(contentType, "image/") {
|
|
return nil, "", fmt.Errorf("invalid content type: %s", contentType)
|
|
}
|
|
// Check content length if available
|
|
if contentLength := response.ContentLength; contentLength > int64(config.WhatsappSettingMaxImageSize) {
|
|
return nil, "", fmt.Errorf("image size %d exceeds maximum allowed size %d", contentLength, config.WhatsappSettingMaxImageSize)
|
|
}
|
|
// Limit the size from config
|
|
reader := io.LimitReader(response.Body, int64(config.WhatsappSettingMaxImageSize))
|
|
// Extract the file name from the URL and remove query parameters if present
|
|
segments := strings.Split(url, "/")
|
|
fileName := segments[len(segments)-1]
|
|
fileName = strings.Split(fileName, "?")[0]
|
|
// Check if the file extension is supported
|
|
allowedExtensions := map[string]bool{
|
|
".jpg": true,
|
|
".jpeg": true,
|
|
".png": true,
|
|
".webp": true,
|
|
}
|
|
extension := strings.ToLower(filepath.Ext(fileName))
|
|
if !allowedExtensions[extension] {
|
|
return nil, "", fmt.Errorf("unsupported file type: %s", extension)
|
|
}
|
|
imageData, err := io.ReadAll(reader)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
return imageData, fileName, nil
|
|
}
|