149 lines
4.6 KiB
Go
149 lines
4.6 KiB
Go
package db
|
|
|
|
import (
|
|
"bytes"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
func (d *Database) NotifyClient(username string, commandID int, notifType, message string) error {
|
|
// Sauvegarder la notification dans Redis
|
|
notifKey := fmt.Sprintf("notifications:%s", username)
|
|
|
|
notification := map[string]interface{}{
|
|
"command_id": commandID,
|
|
"type": notifType,
|
|
"message": message,
|
|
"created_at": time.Now().Format(time.RFC3339),
|
|
"read": false,
|
|
}
|
|
|
|
notifJSON, _ := json.Marshal(notification)
|
|
Redis.LPush(RedisCtx, notifKey, notifJSON)
|
|
Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
|
|
|
|
// Envoyer push notification si le client a un token enregistré
|
|
pushToken, err := d.GetClientPushToken(username)
|
|
if err == nil && pushToken != "" {
|
|
go sendExpoPush(pushToken, "Uber Stup", message, commandID, notifType)
|
|
}
|
|
|
|
log.Printf("📬 Notification envoyée à %s: %s", username, message)
|
|
return nil
|
|
}
|
|
|
|
func sendExpoPush(token, title, body string, commandID int, notifType string) {
|
|
sendExpoPushWithChannel(token, title, body, commandID, notifType, "orders")
|
|
}
|
|
|
|
func sendExpoPushWithChannel(token, title, body string, commandID int, notifType, channelID string) {
|
|
payload := map[string]interface{}{
|
|
"to": token,
|
|
"title": title,
|
|
"body": body,
|
|
"channelId": channelID,
|
|
"data": map[string]interface{}{
|
|
"command_id": commandID,
|
|
"type": notifType,
|
|
},
|
|
"sound": "default",
|
|
}
|
|
|
|
jsonBody, err := json.Marshal(payload)
|
|
if err != nil {
|
|
log.Printf("❌ [EXPO_PUSH] Erreur marshal: %v", err)
|
|
return
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", "https://exp.host/--/api/v2/push/send", bytes.NewBuffer(jsonBody))
|
|
if err != nil {
|
|
log.Printf("❌ [EXPO_PUSH] Erreur création requête: %v", err)
|
|
return
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Accept", "application/json")
|
|
req.Header.Set("Accept-Encoding", "gzip, deflate")
|
|
|
|
client := &http.Client{Timeout: 10 * time.Second}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
log.Printf("❌ [EXPO_PUSH] Erreur envoi: %v", err)
|
|
return
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
log.Printf("✅ [EXPO_PUSH] Push envoyé à %s (channel: %s, status: %d)", token, channelID, resp.StatusCode)
|
|
}
|
|
|
|
// ============================================
|
|
// PUSH TOKEN - LIVREURS (table users)
|
|
// ============================================
|
|
|
|
// SaveUserPushToken sauvegarde le token push d'un livreur dans la table users
|
|
func (d *Database) SaveUserPushToken(username, token string) error {
|
|
_, err := d.Exec(`UPDATE users SET push_token = $1 WHERE username = $2`, token, username)
|
|
return err
|
|
}
|
|
|
|
// GetUserPushToken récupère le token push d'un livreur depuis la table users
|
|
func (d *Database) GetUserPushToken(username string) (string, error) {
|
|
var token sql.NullString
|
|
err := d.QueryRow(`SELECT push_token FROM users WHERE username = $1`, username).Scan(&token)
|
|
if err != nil || !token.Valid {
|
|
return "", err
|
|
}
|
|
return token.String, nil
|
|
}
|
|
|
|
// DeleteUserPushToken supprime le token push d'un livreur
|
|
func (d *Database) DeleteUserPushToken(username string) error {
|
|
_, err := d.Exec(`UPDATE users SET push_token = NULL WHERE username = $1`, username)
|
|
return err
|
|
}
|
|
|
|
// NotifyLivreur envoie une notification in-app (Redis) + push Expo à un livreur
|
|
func (d *Database) NotifyLivreur(username string, commandID int, notifType, message string) error {
|
|
notifKey := fmt.Sprintf("notifications:%s", username)
|
|
|
|
notification := map[string]interface{}{
|
|
"command_id": commandID,
|
|
"type": notifType,
|
|
"message": message,
|
|
"created_at": time.Now().Format(time.RFC3339),
|
|
"read": false,
|
|
}
|
|
|
|
notifJSON, _ := json.Marshal(notification)
|
|
Redis.LPush(RedisCtx, notifKey, notifJSON)
|
|
Redis.Expire(RedisCtx, notifKey, 7*24*time.Hour)
|
|
|
|
// Push notification si le livreur a un token enregistré
|
|
pushToken, err := d.GetUserPushToken(username)
|
|
if err == nil && pushToken != "" {
|
|
go sendExpoPushWithChannel(pushToken, "Nouvelle commande assignée", message, commandID, notifType, "deliveries")
|
|
}
|
|
|
|
log.Printf("📬 [LIVREUR_NOTIF] Notification envoyée à %s: %s", username, message)
|
|
return nil
|
|
}
|
|
|
|
// AddDeliveryRating ajoute une note pour un livreur
|
|
func (d *Database) AddDeliveryRating(livreurUsername string, commandID, rating int, comment string) error {
|
|
query := `
|
|
INSERT INTO delivery_ratings (livreur_username, command_id, rating, comment, created_at)
|
|
VALUES (?, ?, ?, ?, NOW())
|
|
`
|
|
_, err := d.Exec(query, livreurUsername, commandID, rating, comment)
|
|
if err != nil {
|
|
log.Printf("⚠️ Erreur sauvegarde note livreur: %v", err)
|
|
return err
|
|
}
|
|
|
|
log.Printf("⭐ Note %d/5 ajoutée pour livreur %s (commande %d)", rating, livreurUsername, commandID)
|
|
return nil
|
|
}
|