github.com/companieshouse/lfp-pay-api@v0.0.0-20230203133422-0ca455cd79f9/service/email_service.go (about) 1 package service 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strconv" 8 "time" 9 10 "github.com/companieshouse/chs.go/avro" 11 "github.com/companieshouse/chs.go/avro/schema" 12 "github.com/companieshouse/chs.go/kafka/producer" 13 "github.com/companieshouse/filing-notification-sender/util" 14 "github.com/companieshouse/lfp-pay-api-core/models" 15 "github.com/companieshouse/lfp-pay-api/config" 16 ) 17 18 const lfpReceivedAppID = "lfp-pay-api.late_filing_penalty_received_email" 19 const lfpFilingDescription = "Late Filing Penalty" 20 const lfpMessageType = "late_filing_penalty_received_email" 21 22 // ProducerTopic is the topic to which the email-send kafka message is sent 23 const ProducerTopic = "email-send" 24 25 // ProducerSchemaName is the schema which will be used to send the email-send kafka message with 26 const ProducerSchemaName = "email-send" 27 28 // SendEmailKafkaMessage sends a kafka message to the email-sender to send an email 29 func SendEmailKafkaMessage(payableResource models.PayableResource, req *http.Request) error { 30 cfg, err := config.Get() 31 if err != nil { 32 err = fmt.Errorf("error getting config for kafka message production: [%v]", err) 33 return err 34 } 35 36 // Get a producer 37 kafkaProducer, err := producer.New(&producer.Config{Acks: &producer.WaitForAll, BrokerAddrs: cfg.BrokerAddr}) 38 if err != nil { 39 err = fmt.Errorf("error creating kafka producer: [%v]", err) 40 return err 41 } 42 emailSendSchema, err := schema.Get(cfg.SchemaRegistryURL, ProducerSchemaName) 43 if err != nil { 44 err = fmt.Errorf("error getting schema from schema registry: [%v]", err) 45 return err 46 } 47 producerSchema := &avro.Schema{ 48 Definition: emailSendSchema, 49 } 50 51 // Prepare a message with the avro schema 52 message, err := prepareKafkaMessage(*producerSchema, payableResource, req) 53 if err != nil { 54 err = fmt.Errorf("error preparing kafka message with schema: [%v]", err) 55 return err 56 } 57 58 // Send the message 59 partition, offset, err := kafkaProducer.Send(message) 60 if err != nil { 61 err = fmt.Errorf("failed to send message in partition: %d at offset %d", partition, offset) 62 return err 63 } 64 return nil 65 } 66 67 // prepareKafkaMessage generates the kafka message that is to be sent 68 func prepareKafkaMessage(emailSendSchema avro.Schema, payableResource models.PayableResource, req *http.Request) (*producer.Message, error) { 69 cfg, err := config.Get() 70 if err != nil { 71 err = fmt.Errorf("error getting config: [%v]", err) 72 return nil, err 73 } 74 75 // Access Company Name to be included in the email 76 companyName, err := GetCompanyName(payableResource.CompanyNumber, req) 77 if err != nil { 78 err = fmt.Errorf("error getting company name: [%v]", err) 79 return nil, err 80 } 81 82 // Access specific transaction that was paid for 83 payedTransaction, err := GetTransactionForPenalty(payableResource.CompanyNumber, payableResource.Transactions[0].TransactionID) 84 if err != nil { 85 err = fmt.Errorf("error getting transaction for LFP: [%v]", err) 86 return nil, err 87 } 88 89 // Convert madeUpDate and transactionDate to readable format for email 90 madeUpDate, err := time.Parse("2006-01-02", payedTransaction.MadeUpDate) 91 if err != nil { 92 err = fmt.Errorf("error parsing made up date: [%v]", err) 93 return nil, err 94 } 95 transactionDate, err := time.Parse("2006-01-02", payedTransaction.TransactionDate) 96 if err != nil { 97 err = fmt.Errorf("error parsing penalty date: [%v]", err) 98 return nil, err 99 } 100 101 // Set dataField to be used in the avro schema. 102 dataFieldMessage := models.DataField{ 103 PayableResource: payableResource, 104 TransactionID: payableResource.Transactions[0].TransactionID, 105 MadeUpDate: madeUpDate.Format("2 January 2006"), 106 TransactionDate: transactionDate.Format("2 January 2006"), 107 Amount: fmt.Sprintf("%g", payedTransaction.OriginalAmount), 108 CompanyName: companyName, 109 FilingDescription: lfpFilingDescription, 110 To: payableResource.CreatedBy.Email, 111 Subject: fmt.Sprintf("Confirmation of your Companies House penalty payment"), 112 CHSURL: cfg.CHSURL, 113 } 114 115 dataBytes, err := json.Marshal(dataFieldMessage) 116 if err != nil { 117 err = fmt.Errorf("error marshalling dataFieldMessage: [%v]", err) 118 return nil, err 119 } 120 121 messageID := "<" + payableResource.Reference + "." + strconv.Itoa(util.Random(0, 100000)) + "@companieshouse.gov.uk>" 122 123 emailSendMessage := models.EmailSend{ 124 AppID: lfpReceivedAppID, 125 MessageID: messageID, 126 MessageType: lfpMessageType, 127 Data: string(dataBytes), 128 EmailAddress: payableResource.CreatedBy.Email, 129 CreatedAt: time.Now().String(), 130 } 131 132 messageBytes, err := emailSendSchema.Marshal(emailSendMessage) 133 if err != nil { 134 err = fmt.Errorf("error marshalling email send message: [%v]", err) 135 return nil, err 136 } 137 138 producerMessage := &producer.Message{ 139 Value: messageBytes, 140 Topic: ProducerTopic, 141 } 142 return producerMessage, nil 143 }