kekkek
This commit is contained in:
parent
2aa1739b3f
commit
13151f6fe5
@ -422,4 +422,60 @@ func DeleteUser(db *gorm.DB) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HandleTemplateTest(db *gorm.DB) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
val := r.Context().Value("ssoid")
|
||||||
|
ssoid, ok := val.(string)
|
||||||
|
if !ok || ssoid == "" {
|
||||||
|
http.Error(w, "Non authentifié", http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
http.Error(w, "Form invalide", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
to := r.FormValue("to")
|
||||||
|
templateName := r.FormValue("template_name")
|
||||||
|
lang := r.FormValue("language")
|
||||||
|
|
||||||
|
var params []string
|
||||||
|
for i := 1; i <= 5; i++ {
|
||||||
|
val := r.FormValue(fmt.Sprintf("param%d", i))
|
||||||
|
if val != "" {
|
||||||
|
params = append(params, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var user models.User
|
||||||
|
if err := db.Where("sso_id = ?", ssoid).First(&user).Error; err != nil || user.ID == 0 {
|
||||||
|
http.Error(w, "Utilisateur introuvable", http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
message := models.NewTemplateMessage(to, templateName, lang, params)
|
||||||
|
jsonBody, _ := json.MarshalIndent(message, "", " ")
|
||||||
|
|
||||||
|
apiURL := fmt.Sprintf("https://graph.facebook.com/v22.0/%s/messages", user.WhatsappPhoneNumberID)
|
||||||
|
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonBody))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Requête WhatsApp échouée", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", "Bearer "+user.WhatsappToken)
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Échec de l'appel API WhatsApp", http.StatusBadGateway)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
io.Copy(w, resp.Body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -59,6 +59,25 @@ type MonthlyConsumption struct {
|
|||||||
Month string `gorm:"type:char(7);index;not null"` // Format YYYY-MM
|
Month string `gorm:"type:char(7);index;not null"` // Format YYYY-MM
|
||||||
TotalUsed uint `gorm:"not null"` // Crédits utilisés ce mois
|
TotalUsed uint `gorm:"not null"` // Crédits utilisés ce mois
|
||||||
}
|
}
|
||||||
|
type Template struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Language TemplateLanguage `json:"language"`
|
||||||
|
Components []TemplateComponent `json:"components"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TemplateLanguage struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TemplateComponent struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Parameters []TemplateParameter `json:"parameters"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TemplateParameter struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
type WhatsappMessage struct {
|
type WhatsappMessage struct {
|
||||||
MessagingProduct string `json:"messaging_product"` // always "whatsapp"
|
MessagingProduct string `json:"messaging_product"` // always "whatsapp"
|
||||||
@ -76,6 +95,7 @@ type WhatsappMessage struct {
|
|||||||
Contacts []Contact `json:"contacts,omitempty"`
|
Contacts []Contact `json:"contacts,omitempty"`
|
||||||
Interactive *Interactive `json:"interactive,omitempty"`
|
Interactive *Interactive `json:"interactive,omitempty"`
|
||||||
Reaction *Reaction `json:"reaction,omitempty"`
|
Reaction *Reaction `json:"reaction,omitempty"`
|
||||||
|
Template *Template `json:"template,omitempty"` // ✅ Ajoute ce champ
|
||||||
}
|
}
|
||||||
|
|
||||||
type Address struct {
|
type Address struct {
|
||||||
@ -376,3 +396,45 @@ func BuildMessageFromPayload(payload map[string]interface{}) (interface{}, error
|
|||||||
|
|
||||||
return nil, fmt.Errorf("failed to build message")
|
return nil, fmt.Errorf("failed to build message")
|
||||||
}
|
}
|
||||||
|
func NewTemplateMessage(to, name, lang string, params []string) WhatsappMessage {
|
||||||
|
paramList := make([]TemplateParameter, len(params))
|
||||||
|
for i, p := range params {
|
||||||
|
paramList[i] = TemplateParameter{
|
||||||
|
Type: "text",
|
||||||
|
Text: p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WhatsappMessage{
|
||||||
|
MessagingProduct: "whatsapp",
|
||||||
|
To: to,
|
||||||
|
Type: "template",
|
||||||
|
Template: &Template{
|
||||||
|
Name: name,
|
||||||
|
Language: TemplateLanguage{Code: lang},
|
||||||
|
Components: []TemplateComponent{
|
||||||
|
{
|
||||||
|
Type: "body",
|
||||||
|
Parameters: paramList,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enregistre une erreur de statut dans la table Conversation
|
||||||
|
func SaveMessageStatusError(db *gorm.DB, userID uint, recipient, msgID, status, errorMsg string) error {
|
||||||
|
conv := Conversation{
|
||||||
|
UserID: userID,
|
||||||
|
From: "system",
|
||||||
|
To: recipient,
|
||||||
|
MessageID: msgID,
|
||||||
|
Type: "status",
|
||||||
|
Content: errorMsg,
|
||||||
|
Direction: "outbound",
|
||||||
|
Status: status,
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
}
|
||||||
|
return db.Create(&conv).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,7 @@ func RoutesProtected(r *mux.Router, db *gorm.DB) {
|
|||||||
r.HandleFunc("/admin/user/new", renders.AdminUserCreate()).Methods("GET")
|
r.HandleFunc("/admin/user/new", renders.AdminUserCreate()).Methods("GET")
|
||||||
r.HandleFunc("/dashboard", renders.Dashboard(db))
|
r.HandleFunc("/dashboard", renders.Dashboard(db))
|
||||||
r.HandleFunc("/test/send", renders.TestMessagesPages)
|
r.HandleFunc("/test/send", renders.TestMessagesPages)
|
||||||
|
r.HandleFunc("/api/message/send", handlers.HandleTemplateTest(db)).Methods("POST")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
52
frontend/templates/test-send.pages.tmpl
Normal file
52
frontend/templates/test-send.pages.tmpl
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
{{ define "test-send.pages.tmpl" }}
|
||||||
|
{{ template "head" . }}
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<section class="section">
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="title">📤 Test envoi de message WhatsApp - Template</h1>
|
||||||
|
|
||||||
|
<form hx-post="/api/message/send" hx-trigger="submit" hx-target="#template-result" hx-swap="innerHTML">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Numéro WhatsApp</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="to" placeholder="ex: 33612345678" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Nom du template</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="template_name" value="rappel_demande_info" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Langue</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="language" value="fr" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Paramètre 1</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="param1" value="Jean">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Paramètre 2 (optionnel)</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="param2">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="button is-link" type="submit">Envoyer le template</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="template-result" class="mt-4"></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
{{ end }}
|
||||||
Loading…
Reference in New Issue
Block a user