Major refactor to library
This commit is contained in:
72
pkg/utils/phone.go
Normal file
72
pkg/utils/phone.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FormatPhoneToJID converts a phone number to WhatsApp JID format
|
||||
// If the number already contains @, it returns as-is
|
||||
// Otherwise, applies formatting rules:
|
||||
// - If starts with 0, assumes no country code and replaces 0 with country code
|
||||
// - If starts with +, assumes it already has country code
|
||||
// - Otherwise adds country code if not present
|
||||
// - Adds @s.whatsapp.net suffix
|
||||
func FormatPhoneToJID(phone string, defaultCountryCode string) string {
|
||||
// If already in JID format, return as-is
|
||||
if strings.Contains(phone, "@") {
|
||||
return phone
|
||||
}
|
||||
|
||||
// Remove all non-digit characters
|
||||
cleaned := strings.Map(func(r rune) rune {
|
||||
if r >= '0' && r <= '9' {
|
||||
return r
|
||||
}
|
||||
return -1
|
||||
}, phone)
|
||||
|
||||
// If empty after cleaning, return original
|
||||
if cleaned == "" {
|
||||
return phone
|
||||
}
|
||||
|
||||
// If number starts with 0, it definitely doesn't have a country code
|
||||
// Replace the leading 0 with the country code
|
||||
if strings.HasPrefix(cleaned, "0") && defaultCountryCode != "" {
|
||||
countryCode := strings.TrimPrefix(defaultCountryCode, "+")
|
||||
cleaned = countryCode + strings.TrimLeft(cleaned, "0")
|
||||
return fmt.Sprintf("%s@s.whatsapp.net", cleaned)
|
||||
}
|
||||
|
||||
// Remove all leading zeros
|
||||
cleaned = strings.TrimLeft(cleaned, "0")
|
||||
|
||||
// If original phone started with +, it already has country code
|
||||
if strings.HasPrefix(phone, "+") {
|
||||
return fmt.Sprintf("%s@s.whatsapp.net", cleaned)
|
||||
}
|
||||
|
||||
// Add country code if provided and number doesn't start with it
|
||||
if defaultCountryCode != "" {
|
||||
countryCode := strings.TrimPrefix(defaultCountryCode, "+")
|
||||
if !strings.HasPrefix(cleaned, countryCode) {
|
||||
cleaned = countryCode + cleaned
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s@s.whatsapp.net", cleaned)
|
||||
}
|
||||
|
||||
// IsGroupJID checks if a JID is a group JID
|
||||
func IsGroupJID(jid string) bool {
|
||||
return strings.HasSuffix(jid, "@g.us")
|
||||
}
|
||||
|
||||
// IsValidJID checks if a string is a valid WhatsApp JID
|
||||
func IsValidJID(jid string) bool {
|
||||
return strings.Contains(jid, "@") &&
|
||||
(strings.HasSuffix(jid, "@s.whatsapp.net") ||
|
||||
strings.HasSuffix(jid, "@g.us") ||
|
||||
strings.HasSuffix(jid, "@broadcast"))
|
||||
}
|
||||
200
pkg/utils/phone_test.go
Normal file
200
pkg/utils/phone_test.go
Normal file
@@ -0,0 +1,200 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFormatPhoneToJID(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
phone string
|
||||
defaultCountryCode string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "Already in JID format",
|
||||
phone: "27834606792@s.whatsapp.net",
|
||||
defaultCountryCode: "27",
|
||||
want: "27834606792@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "Plain number with leading zero",
|
||||
phone: "0834606792",
|
||||
defaultCountryCode: "27",
|
||||
want: "27834606792@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "Number with country code",
|
||||
phone: "27834606792",
|
||||
defaultCountryCode: "27",
|
||||
want: "27834606792@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "Number with plus sign",
|
||||
phone: "+27834606792",
|
||||
defaultCountryCode: "27",
|
||||
want: "27834606792@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "Number without country code config",
|
||||
phone: "0834606792",
|
||||
defaultCountryCode: "",
|
||||
want: "834606792@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "Number with spaces and dashes",
|
||||
phone: "083-460-6792",
|
||||
defaultCountryCode: "27",
|
||||
want: "27834606792@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "Number with parentheses",
|
||||
phone: "(083) 460 6792",
|
||||
defaultCountryCode: "27",
|
||||
want: "27834606792@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "US number with leading 1",
|
||||
phone: "12025551234",
|
||||
defaultCountryCode: "1",
|
||||
want: "12025551234@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "US number with area code",
|
||||
phone: "202-555-1234",
|
||||
defaultCountryCode: "1",
|
||||
want: "12025551234@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "Group JID unchanged",
|
||||
phone: "123456789-1234567890@g.us",
|
||||
defaultCountryCode: "27",
|
||||
want: "123456789-1234567890@g.us",
|
||||
},
|
||||
{
|
||||
name: "Number with different country code via plus sign",
|
||||
phone: "+12025551234",
|
||||
defaultCountryCode: "27",
|
||||
want: "12025551234@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "Country code with plus in config",
|
||||
phone: "0834606792",
|
||||
defaultCountryCode: "+27",
|
||||
want: "27834606792@s.whatsapp.net",
|
||||
},
|
||||
{
|
||||
name: "Empty phone number",
|
||||
phone: "",
|
||||
defaultCountryCode: "27",
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "Multiple leading zeros",
|
||||
phone: "00834606792",
|
||||
defaultCountryCode: "27",
|
||||
want: "27834606792@s.whatsapp.net",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := FormatPhoneToJID(tt.phone, tt.defaultCountryCode)
|
||||
if got != tt.want {
|
||||
t.Errorf("FormatPhoneToJID(%q, %q) = %q, want %q",
|
||||
tt.phone, tt.defaultCountryCode, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsGroupJID(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
jid string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "Individual JID",
|
||||
jid: "27834606792@s.whatsapp.net",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Group JID",
|
||||
jid: "123456789-1234567890@g.us",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Empty string",
|
||||
jid: "",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Invalid JID",
|
||||
jid: "notajid",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := IsGroupJID(tt.jid)
|
||||
if got != tt.want {
|
||||
t.Errorf("IsGroupJID(%q) = %v, want %v", tt.jid, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidJID(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
jid string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "Valid individual JID",
|
||||
jid: "27834606792@s.whatsapp.net",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Valid group JID",
|
||||
jid: "123456789-1234567890@g.us",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Valid broadcast JID",
|
||||
jid: "123456789@broadcast",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid - no @ symbol",
|
||||
jid: "27834606792",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Invalid - wrong suffix",
|
||||
jid: "27834606792@invalid.com",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Empty string",
|
||||
jid: "",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Just @ symbol",
|
||||
jid: "@",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := IsValidJID(tt.jid)
|
||||
if got != tt.want {
|
||||
t.Errorf("IsValidJID(%q) = %v, want %v", tt.jid, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user