From f87b057b856f540e40409319735e1972c0309523 Mon Sep 17 00:00:00 2001 From: cangui Date: Tue, 6 May 2025 18:16:42 +0200 Subject: [PATCH] first --- Dockerfile | 16 +++++ docker-compose.yml | 12 ++++ main.go | 120 ++++++++++++++++++++++++++++++++++++ public/login.html | 12 ++++ public/logo-merlo-cs-FR.jpg | Bin 0 -> 20829 bytes 5 files changed, 160 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 main.go create mode 100644 public/login.html create mode 100644 public/logo-merlo-cs-FR.jpg diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..64af1af --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM golang:1.20-alpine AS builder +WORKDIR /app + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -o sender main.go + +FROM alpine:latest +WORKDIR /root/ +COPY --from=builder /app/sender . +COPY public ./public + +EXPOSE 3000 +CMD ["./sender"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c64d411 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3.8' +services: + whatsapp-sender: + build: . + container_name: whatsapp_sender + ports: + - "3000:3000" + volumes: + - ./public:/root/public:ro + environment: + - PORT=3000 + restart: unless-stopped diff --git a/main.go b/main.go new file mode 100644 index 0000000..b6cdf93 --- /dev/null +++ b/main.go @@ -0,0 +1,120 @@ +package main + +import ( + "encoding/json" + "log" + "net/http" + "os" + "time" + + whatsapp "github.com/Rhymen/go-whatsapp" + "github.com/Rhymen/go-whatsapp/binary/proto" + "github.com/Rhymen/go-whatsapp/binary/proto/text" +) + +type interactiveReq struct { + Phone string `json:"phone"` + Caption string `json:"caption"` + URL1 string `json:"url1"` + URL2 string `json:"url2"` +} + +func main() { + wac, err := whatsapp.NewConn(20 * time.Second) + if err != nil { + log.Fatalf("Error creating connection: %v", err) + } + + qrChan := make(chan string) + go func() { + log.Println("Scan the QR code at http://localhost:3000/login") + log.Printf("QR Code: %s", <-qrChan) + }() + _, err = wac.Login(qrChan) + if err != nil { + log.Fatalf("Login failed: %v", err) + } + log.Println("✅ Connected to WhatsApp Web") + + http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/login.html") + }) + + http.HandleFunc("/sendInteractive", func(w http.ResponseWriter, r *http.Request) { + var req interactiveReq + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "Invalid JSON payload", http.StatusBadRequest) + return + } + + imageUrl := getBaseURL(r) + "/static/logo-merlo-cs-FR.jpg" + header := &proto.InteractiveMessage_Header{ + HasMediaAttachment: proto.Bool(true), + ImageMessage: &proto.ImageMessage{ + Url: &imageUrl, + Mimetype: proto.String("image/jpeg"), + }, + Media: proto.String("imageMessage"), + } + + body := &proto.InteractiveMessage_Body{Text: &req.Caption} + footer := &proto.InteractiveMessage_Footer{Text: proto.String("Pied de page")} + + buttons := []*proto.InteractiveMessage_ButtonParameters{ + { + Name: proto.String("cta_url"), + ButtonParamsJson: proto.String(text.Stringify(&proto.InteractiveMessage_URLButton{ + DisplayText: proto.String("📄 Proposition"), + Url: &req.URL1, + })), + }, + { + Name: proto.String("cta_url"), + ButtonParamsJson: proto.String(text.Stringify(&proto.InteractiveMessage_URLButton{ + DisplayText: proto.String("🔧 Spécifications"), + Url: &req.URL2, + })), + }, + } + nativeFlow := &proto.InteractiveMessage_NativeFlowMessage{Buttons: buttons} + + interactive := &proto.InteractiveMessage{ + Header: header, + Body: body, + Footer: footer, + NativeFlowMessage: nativeFlow, + } + + wmi := &proto.WebMessageInfo{ + Key: &proto.MessageKey{RemoteJid: proto.String(req.Phone + "@s.whatsapp.net")}, + Message: &proto.WebMessageInfo_InteractiveMessage{InteractiveMessage: interactive}, + } + + if _, err := wac.Send(wmi); err != nil { + log.Printf("Error sending message: %v", err) + http.Error(w, "Failed to send message", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"success":true}`)) + }) + + fs := http.FileServer(http.Dir("public")) + http.Handle("/static/", http.StripPrefix("/static/", fs)) + + port := os.Getenv("PORT") + if port == "" { + port = "3002" + } + log.Printf("Server running on :%s", port) + log.Fatal(http.ListenAndServe(":"+port, nil)) +} + +func getBaseURL(r *http.Request) string { + scheme := "http" + if r.TLS != nil { + scheme = "https" + } + return scheme + "://" + r.Host +} diff --git a/public/login.html b/public/login.html new file mode 100644 index 0000000..03a27b7 --- /dev/null +++ b/public/login.html @@ -0,0 +1,12 @@ + + + + + WhatsApp QR Login + + +

Scan QR to Login

+

Connect to WhatsApp Web from this device.

+

QR will show in terminal output.

+ + diff --git a/public/logo-merlo-cs-FR.jpg b/public/logo-merlo-cs-FR.jpg new file mode 100644 index 0000000000000000000000000000000000000000..416892e99951f5b00415d15c4cb5b30b7166ef8b GIT binary patch literal 20829 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 literal 0 HcmV?d00001