diff --git a/database.go b/database.go index 25abe4e..42453f0 100644 --- a/database.go +++ b/database.go @@ -311,10 +311,11 @@ func db_get_card_from_card_id(card_id int) (*card, error) { } defer db.Close() - sqlStatement := `SELECT card_id, k2_cmac_key, uid,` + - ` last_counter_value, lnurlw_request_timeout_sec,` + - ` lnurlw_enable, tx_limit_sats, day_limit_sats, email_enable, email_address` + - ` FROM cards WHERE card_id=$1;` + sqlStatement := `SELECT card_id, k2_cmac_key, uid, ` + + `last_counter_value, lnurlw_request_timeout_sec, ` + + `lnurlw_enable, tx_limit_sats, day_limit_sats, ` + + `email_enable, email_address, card_name ` + + `FROM cards WHERE card_id=$1;` row := db.QueryRow(sqlStatement, card_id) err = row.Scan( &c.card_id, @@ -326,7 +327,8 @@ func db_get_card_from_card_id(card_id int) (*card, error) { &c.tx_limit_sats, &c.day_limit_sats, &c.email_enable, - &c.email_address) + &c.email_address, + &c.card_name) if err != nil { return &c, err } @@ -593,8 +595,62 @@ func db_get_card_totals(card_id int) (int, error) { return day_total_sats, nil } -//TODO: -//func db_get_card_txs(card_id int) ([]transaction, error) { +func db_get_card_txs(card_id int) ([]transaction, error) { + // open the database + + db, err := db_open() + + if err != nil { + return nil, err + } + + defer db.Close() + + // query the database + +//TODO: LIMIT 10 + COUNT + sqlStatement := `SELECT card_id, ` + + `card_payments.card_payment_id AS tx_id, 'payment' AS tx_type, ` + + `amount_msats as tx_amount_msats, ` + + `TO_CHAR(payment_status_time, 'DD/MM/YYYY HH:MI:SS') AS tx_time ` + + `FROM card_payments WHERE card_id = $1 AND payment_status != 'FAILED' ` + + `AND amount_msats != 0 UNION SELECT card_id, card_receipts.card_receipt_id AS tx_id, ` + + `'receipt' AS tx_type, amount_msats as tx_amount_msats, ` + + `TO_CHAR(receipt_status_time, 'DD/MM/YYYY HH:MI:SS') AS tx_time ` + + `FROM card_receipts WHERE card_id = $1 ` + + `AND receipt_status = 'SETTLED' ORDER BY tx_time DESC` + + rows, err := db.Query(sqlStatement, card_id) + + if err != nil { + return nil, err + } + + defer rows.Close() + + // prepare the results + + var transactions []transaction + + // Loop through rows, using Scan to assign column data to struct fields. + for rows.Next() { + var t transaction + err := rows.Scan(&t.card_id, &t.tx_id, &t.tx_type, &t.tx_amount_msats, &t.tx_time) + + if err != nil { + return transactions, err + } + transactions = append(transactions, t) + } + + err = rows.Err() + + if err != nil { + return transactions, err + } + + return transactions, nil +} func db_get_card_total(card_id int) (int, error) { diff --git a/email.go b/email.go index 2d141e6..203ecc2 100644 --- a/email.go +++ b/email.go @@ -9,19 +9,65 @@ import ( log "github.com/sirupsen/logrus" "os" "strconv" + "strings" ) func send_balance_email(recipient_email string, card_id int) { + + c, err := db_get_card_from_card_id(card_id) + if err != nil { + log.Warn(err.Error()) + return + } + card_total_sats, err := db_get_card_total(card_id) if err != nil { log.Warn(err.Error()) return } + txs, err := db_get_card_txs(card_id) + if err != nil { + log.Warn(err.Error()) + return + } + + subject := c.card_name + " balance = " + strconv.Itoa(card_total_sats) + " sats" + + // add transactions to the email body + + var html_body_sb strings.Builder + var text_body_sb strings.Builder + + html_body_sb.WriteString("") + + html_body_sb.WriteString("

transactions

") + text_body_sb.WriteString("transactions\n\n") + + for _, tx := range txs { + + html_body_sb.WriteString( + "" + + "" + + "" + + "" + + "") + + text_body_sb.WriteString(tx.tx_type + + " " + strconv.Itoa(tx.tx_amount_msats / 1000)) + } + + html_body_sb.WriteString("
dateactionamount
" + tx.tx_time + "" + tx.tx_type + "" + strconv.Itoa(tx.tx_amount_msats / 1000) + "
") + + html_body := html_body_sb.String() + text_body := text_body_sb.String() + send_email(recipient_email, - "bolt card balance: " + strconv.Itoa(card_total_sats) + " sats", - "html body", - "text body") + subject, + html_body, + text_body) } // https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/ses-example-send-email.html