From 68b2639b5c6eb54ebb923bce112ace9d51bc13ae Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Thu, 4 Jul 2024 16:36:21 +0200 Subject: [PATCH] Send Prontogram message --- README.md | 1 + bpmn/acmesky.bpmn | 4 +- docker-compose.yml | 1 + internal/handlers/acmesky/st_prepare_offer.go | 8 +++ internal/handlers/acmesky/tm_send_offer.go | 2 +- .../prontogram/st_save_info_on_prontogram.go | 46 +++++++++++++++- internal/http/http.go | 52 +++++++++++++++++++ 7 files changed, 109 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0902118..d52190d 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ - POSTGRES_USER - POSTGRES_PASSWORD - OFFER_VALIDATION_TIME +- PRONTOGRAM_ENDPOINT - BANK_ENDPOINT - BANK_CALLBACK - BANK_PAYMENT_ENDPOINT diff --git a/bpmn/acmesky.bpmn b/bpmn/acmesky.bpmn index 541d961..33bb3d7 100644 --- a/bpmn/acmesky.bpmn +++ b/bpmn/acmesky.bpmn @@ -613,7 +613,7 @@ - + @@ -2118,4 +2118,4 @@ - \ No newline at end of file + diff --git a/docker-compose.yml b/docker-compose.yml index 33156d0..3c0f34c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -183,6 +183,7 @@ services: - SENTRY_DSN=${SENTRY_DSN} - DATABASE_DSN=${DATABASE_DSN} - OFFER_VALIDATION_TIME=${OFFER_VALIDATION_TIME} + - PRONTOGRAM_ENDPOINT=${PRONTOGRAM_ENDPOINT} - BANK_ENDPOINT=${BANK_ENDPOINT} - BANK_PAYMENT_ENDPOINT=${BANK_PAYMENT_ENDPOINT} - BANK_CALLBACK=${BANK_CALLBACK} diff --git a/internal/handlers/acmesky/st_prepare_offer.go b/internal/handlers/acmesky/st_prepare_offer.go index dd7ca21..2b3e971 100644 --- a/internal/handlers/acmesky/st_prepare_offer.go +++ b/internal/handlers/acmesky/st_prepare_offer.go @@ -89,6 +89,12 @@ func STPrepareOffer(client worker.JobClient, job entities.Job) { } } + // Preload user info + if err := db.Where("id = ?", offer.Id).Preload("User").First(&offer).Error; err != nil { + log.Errorf("[%s] [%d] Offer not found", job.Type, jobKey) + acmejob.FailJob(client, job) + return + } variables["offer"] = offer request, err := client.NewCompleteJobCommand().JobKey(jobKey).VariablesFromMap(variables) @@ -104,5 +110,7 @@ func STPrepareOffer(client worker.JobClient, job entities.Job) { } log.Infof("[%s] [%d] Successfully completed job", job.Type, jobKey) + acmejob.JobVariables[job.Type] <- variables + acmejob.JobStatuses.Close(job.Type, 0) } diff --git a/internal/handlers/acmesky/tm_send_offer.go b/internal/handlers/acmesky/tm_send_offer.go index 82ad4a5..cd70ff3 100644 --- a/internal/handlers/acmesky/tm_send_offer.go +++ b/internal/handlers/acmesky/tm_send_offer.go @@ -36,6 +36,6 @@ func TMSendOffer(client worker.JobClient, job entities.Job) { log.Infof("[%s] [%d] Successfully completed job", job.Type, jobKey) - acmejob.JobVariables[job.Type] <- variables["offer"].(map[string]interface{}) + acmejob.JobVariables[job.Type] <- variables acmejob.JobStatuses.Close(job.Type, 0) } diff --git a/internal/handlers/prontogram/st_save_info_on_prontogram.go b/internal/handlers/prontogram/st_save_info_on_prontogram.go index e48a01b..8620cc4 100644 --- a/internal/handlers/prontogram/st_save_info_on_prontogram.go +++ b/internal/handlers/prontogram/st_save_info_on_prontogram.go @@ -2,13 +2,22 @@ package handlers import ( "context" + "encoding/json" + "fmt" + "strconv" + "time" + "github.com/charmbracelet/log" + "github.com/acme-sky/workers/internal/config" + "github.com/acme-sky/workers/internal/http" acmejob "github.com/acme-sky/workers/internal/job" + "github.com/acme-sky/workers/internal/models" "github.com/camunda/zeebe/clients/go/v8/pkg/entities" "github.com/camunda/zeebe/clients/go/v8/pkg/worker" ) +// Service used to save info into Prontogram backend service. func STSaveInfoOnProntogram(client worker.JobClient, job entities.Job) { jobKey := job.GetKey() @@ -18,13 +27,46 @@ func STSaveInfoOnProntogram(client worker.JobClient, job entities.Job) { return } - request, err := client.NewCompleteJobCommand().JobKey(jobKey).VariablesFromMap(variables) + m := variables["offer"].(map[string]interface{}) + + jsonData, err := json.Marshal(m) + if err != nil { + fmt.Println("Error marshaling map to JSON:", err) + return + } + + var offer models.Offer + err = json.Unmarshal(jsonData, &offer) if err != nil { + fmt.Println("Error unmarshaling JSON to struct:", err) + return + } + + conf, _ := config.GetConfig() + endpoint := fmt.Sprintf("%s/sendMessage", conf.String("prontogram.endpoint")) + + fmt.Println(endpoint) + expirationInt, _ := strconv.ParseInt(offer.Expired, 10, 64) + expirationDate := time.Unix(expirationInt, 0) + payload := http.ProntogramMessageRequest{ + Message: offer.Message, + Expiration: expirationDate.Format("2006-01-02T15:04:05Z"), + Username: *offer.User.ProntogramUsername, + Sid: " ", + } + _, err = http.MakeProntogramRequest(endpoint, payload) + + if err != nil { + log.Errorf("[%s] [%d] Error for offer `%d`: %s", job.Type, jobKey, offer.Id, err.Error()) acmejob.FailJob(client, job) return } - log.Debug("Processing data:", variables) + request, err := client.NewCompleteJobCommand().JobKey(jobKey).VariablesFromMap(variables) + if err != nil { + acmejob.FailJob(client, job) + return + } ctx := context.Background() _, err = request.Send(ctx) diff --git a/internal/http/http.go b/internal/http/http.go index 6c99d37..e216321 100644 --- a/internal/http/http.go +++ b/internal/http/http.go @@ -49,6 +49,19 @@ type AirportInfoResponseBody struct { Longitude float32 `json:"longitude"` } +type ProntogramMessageRequest struct { + Message string `json:"message"` + Expiration string `json:"expiration"` + Username string `json:"username"` + Sid string `json:"sid"` +} + +type ProntogramMessageResponse struct { + Message string `json:"message"` + Sid string `json:"sid"` + Status int `json:"status"` +} + // Make a new request to an endpoint with a `body` and returns a response body // or an error. func MakeRequest(endpoint string, body map[string]interface{}) (*ResponseBody, error) { @@ -227,3 +240,42 @@ func GetAirportInfo(endpoint string) (*AirportInfoResponseBody, error) { return &responseBody, nil } + +// Make a new request for Prontogram and returns a ProntogramMessageResponse +func MakeProntogramRequest(endpoint string, body ProntogramMessageRequest) (*ProntogramMessageResponse, error) { + jsonBody, _ := json.Marshal(body) + bodyReader := bytes.NewReader(jsonBody) + + req, err := http.NewRequest(http.MethodPost, endpoint, bodyReader) + + if err != nil { + return nil, err + } + + httpClient := http.Client{ + Timeout: 30 * time.Second, + } + + req.Header.Add("Content-Type", "application/json") + + res, err := httpClient.Do(req) + if err != nil { + return nil, err + } + + resBody, err := io.ReadAll(res.Body) + if err != nil { + return nil, errors.New(fmt.Sprintf("Could not read response body: %s", err.Error())) + } + + if res.StatusCode != 200 { + return nil, errors.New(fmt.Sprintf("HTTP request returned a status %d and response `%s`", res.StatusCode, resBody)) + } + + var responseBody ProntogramMessageResponse + if err := json.Unmarshal(resBody, &responseBody); err != nil { + return nil, errors.New(fmt.Sprintf("Could not unmarshal response body: %s", err)) + } + + return &responseBody, nil +}