modified: .env

modified:   bot.db
	modified:   db/db.go
	modified:   handlers/webhook.go
	modified:   services/whatsapp.go
This commit is contained in:
2026-03-01 08:40:30 -03:00
parent e47b12b0d9
commit 9ff021879f
5 changed files with 146 additions and 9 deletions

View File

@@ -1,17 +1,38 @@
package handlers
import (
"fmt"
"net/http"
"whatsapp-bot/db"
"whatsapp-bot/services"
"github.com/gin-gonic/gin"
)
// Meta verification
func VerifyWebhook(c *gin.Context) {
challenge := c.Query("hub.challenge")
token := c.Query("hub.verify_token")
// Structs to parse incoming WhatsApp Webhook JSON
type WebhookPayload struct {
Entry []struct {
Changes []struct {
Value struct {
Messages []struct {
From string `json:"from"`
Text struct {
Body string `json:"body"`
} `json:"text"`
Type string `json:"type"`
} `json:"messages"`
} `json:"value"`
} `json:"changes"`
} `json:"entry"`
}
if token == "YOUR_SECRET_TOKEN" {
// VerifyWebhook (Keep this as is)
func VerifyWebhook(c *gin.Context) {
mode := c.Query("hub.mode")
token := c.Query("hub.verify_token")
challenge := c.Query("hub.challenge")
if mode == "subscribe" && token == "YOUR_SECRET_TOKEN" { // CHANGE THIS to match your Meta setup
c.String(http.StatusOK, challenge)
} else {
c.Status(http.StatusForbidden)
@@ -19,7 +40,61 @@ func VerifyWebhook(c *gin.Context) {
}
func HandleMessage(c *gin.Context) {
// You should bind your WhatsApp types here
// go services.Process(...)
c.Status(http.StatusOK)
var payload WebhookPayload
if err := c.BindJSON(&payload); err != nil {
// WhatsApp sends other events (statuses) that might not match. Ignore errors.
c.Status(200)
return
}
// 1. Loop through messages (usually just one)
for _, entry := range payload.Entry {
for _, change := range entry.Changes {
for _, msg := range change.Value.Messages {
// We only handle text for now
if msg.Type != "text" {
continue
}
userPhone := msg.From
userText := msg.Text.Body
fmt.Printf("📩 Received from %s: %s\n", userPhone, userText)
// 2. Identify the Chat Logic
chatID := db.GetOrCreateChatByPhone(userPhone)
// 3. Save User Message
db.Conn.Exec("INSERT INTO messages (chat_id, role, content) VALUES (?, 'user', ?)", chatID, userText)
// 4. Get AI Response
// Fetch history
rows, _ := db.Conn.Query("SELECT role, content FROM messages WHERE chat_id = ? ORDER BY created_at ASC", chatID)
var history []services.Message
for rows.Next() {
var m services.Message
rows.Scan(&m.Role, &m.Content)
history = append(history, m)
}
rows.Close()
// Call AI (We don't need the stream callback here, just the final string)
aiResponse, _ := services.StreamAIResponse(history, func(chunk string) {
// We can't stream to WhatsApp, so we do nothing here.
})
// 5. Save & Send Response
if aiResponse != "" {
db.Conn.Exec("INSERT INTO messages (chat_id, role, content) VALUES (?, 'assistant', ?)", chatID, aiResponse)
err := services.SendWhatsAppMessage(userPhone, aiResponse)
if err != nil {
fmt.Println("❌ Error sending to WhatsApp:", err)
}
}
}
}
}
c.Status(200)
}