first
This commit is contained in:
commit
f87b057b85
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@ -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"]
|
||||
12
docker-compose.yml
Normal file
12
docker-compose.yml
Normal file
@ -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
|
||||
120
main.go
Normal file
120
main.go
Normal file
@ -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
|
||||
}
|
||||
12
public/login.html
Normal file
12
public/login.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>WhatsApp QR Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Scan QR to Login</h1>
|
||||
<p>Connect to WhatsApp Web from this device.</p>
|
||||
<p>QR will show in terminal output.</p>
|
||||
</body>
|
||||
</html>
|
||||
BIN
public/logo-merlo-cs-FR.jpg
Normal file
BIN
public/logo-merlo-cs-FR.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Loading…
Reference in New Issue
Block a user