2025-05-06 16:16:42 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
2025-05-06 16:41:05 +00:00
|
|
|
"fmt"
|
|
|
|
|
"log"
|
|
|
|
|
"net/http"
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"time"
|
|
|
|
|
"context"
|
2025-05-06 16:42:30 +00:00
|
|
|
|
2025-05-06 16:41:05 +00:00
|
|
|
"github.com/gorilla/mux"
|
|
|
|
|
"go.mau.fi/whatsmeow"
|
|
|
|
|
waProto "go.mau.fi/whatsmeow/binary/proto"
|
|
|
|
|
"go.mau.fi/whatsmeow/store/sqlstore"
|
|
|
|
|
"go.mau.fi/whatsmeow/types"
|
|
|
|
|
"go.mau.fi/whatsmeow/types/events"
|
|
|
|
|
waLog "go.mau.fi/whatsmeow/util/log"
|
|
|
|
|
"google.golang.org/protobuf/proto"
|
2025-05-06 16:16:42 +00:00
|
|
|
)
|
|
|
|
|
|
2025-05-06 16:41:05 +00:00
|
|
|
var client *whatsmeow.Client
|
2025-05-06 16:16:42 +00:00
|
|
|
|
|
|
|
|
func main() {
|
2025-05-06 16:41:05 +00:00
|
|
|
// Initialisation du routeur
|
|
|
|
|
r := mux.NewRouter()
|
|
|
|
|
|
|
|
|
|
// Routes
|
|
|
|
|
r.HandleFunc("/", loginHandler).Methods("GET")
|
|
|
|
|
r.HandleFunc("/send", sendMessageHandler).Methods("POST")
|
|
|
|
|
r.HandleFunc("/qr", qrHandler).Methods("GET")
|
|
|
|
|
|
|
|
|
|
// Serveur de fichiers statiques
|
|
|
|
|
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("public"))))
|
|
|
|
|
|
|
|
|
|
// Configuration du serveur
|
|
|
|
|
srv := &http.Server{
|
|
|
|
|
Handler: r,
|
2025-05-06 16:42:30 +00:00
|
|
|
Addr: "0.0.0.0:3002",
|
2025-05-06 16:41:05 +00:00
|
|
|
WriteTimeout: 15 * time.Second,
|
|
|
|
|
ReadTimeout: 15 * time.Second,
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-06 16:42:30 +00:00
|
|
|
log.Println("Serveur démarré sur http://localhost:3002")
|
2025-05-06 16:41:05 +00:00
|
|
|
log.Fatal(srv.ListenAndServe())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func loginHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
http.ServeFile(w, r, "public/login.html")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func sendMessageHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
phone := r.FormValue("phone")
|
|
|
|
|
message := r.FormValue("message")
|
|
|
|
|
|
|
|
|
|
if client == nil || !client.IsConnected() {
|
|
|
|
|
http.Error(w, "Client WhatsApp non connecté", http.StatusBadRequest)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
recipient, err := types.ParseJID(phone)
|
|
|
|
|
if err != nil {
|
|
|
|
|
http.Error(w, "Numéro de téléphone invalide", http.StatusBadRequest)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
msg := &waProto.Message{
|
|
|
|
|
Conversation: proto.String(message),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, err = client.SendMessage(context.Background(), recipient, msg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
http.Error(w, fmt.Sprintf("Erreur d'envoi: %v", err), http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(w, "Message envoyé avec succès à %s", phone)
|
2025-05-06 16:16:42 +00:00
|
|
|
}
|
|
|
|
|
|
2025-05-06 16:41:05 +00:00
|
|
|
func qrHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
// Initialisation du client WhatsApp si ce n'est pas déjà fait
|
|
|
|
|
if client == nil {
|
|
|
|
|
initWhatsAppClient(r.Context(), w)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ici vous devriez implémenter la logique pour afficher/générer le QR code
|
|
|
|
|
// Ceci est un exemple simplifié
|
|
|
|
|
fmt.Fprint(w, "QR code endpoint - à implémenter")
|
2025-05-06 16:16:42 +00:00
|
|
|
}
|
2025-05-06 16:41:05 +00:00
|
|
|
|
|
|
|
|
func initWhatsAppClient(ctx context.Context, w http.ResponseWriter) {
|
|
|
|
|
// Configuration du stockage
|
|
|
|
|
storeDir := "sessions"
|
|
|
|
|
if os.Getenv("WHATSAPP_SESSION_DIR") != "" {
|
|
|
|
|
storeDir = os.Getenv("WHATSAPP_SESSION_DIR")
|
|
|
|
|
}
|
|
|
|
|
os.MkdirAll(storeDir, os.ModePerm)
|
|
|
|
|
|
|
|
|
|
container, err := sqlstore.New("sqlite3", "file:"+filepath.Join(storeDir, "whatsapp.db")+"?_foreign_keys=on", waLog.Noop)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deviceStore, err := container.GetFirstDevice()
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client = whatsmeow.NewClient(deviceStore, waLog.Noop)
|
|
|
|
|
client.AddEventHandler(eventHandler)
|
|
|
|
|
|
|
|
|
|
if client.Store.ID == nil {
|
|
|
|
|
// Pas de session enregistrée, besoin de s'authentifier
|
|
|
|
|
qrChan, _ := client.GetQRChannel(ctx)
|
|
|
|
|
err = client.Connect()
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for evt := range qrChan {
|
|
|
|
|
if evt.Event == "code" {
|
|
|
|
|
// Afficher le QR code à l'utilisateur
|
|
|
|
|
fmt.Fprintf(w, "QR code: %s", evt.Code)
|
|
|
|
|
} else {
|
|
|
|
|
fmt.Fprintf(w, "Événement de connexion: %s", evt.Event)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Déjà connecté
|
|
|
|
|
err = client.Connect()
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func eventHandler(evt interface{}) {
|
|
|
|
|
switch v := evt.(type) {
|
|
|
|
|
case *events.Message:
|
|
|
|
|
fmt.Println("Message reçu de", v.Info.Sender, ":", v.Message.GetConversation())
|
|
|
|
|
}
|
|
|
|
|
}
|