2026-01-25 01:12:30 -07:00

106 lines
2.4 KiB
Go

package main
import (
"encoding/csv"
"fmt"
"io"
"slices"
"strings"
"github.com/therootcompany/golib/net/smsgw"
)
func GetFieldIndex(header []string, name string) int {
for i, h := range header {
if strings.EqualFold(strings.TrimSpace(h), name) {
return i
}
}
return -1
}
type CSVWarn struct {
Index int
Code string
Message string
Record []string
}
func (w CSVWarn) Error() string {
return w.Message
}
func (cfg *MainConfig) LaxParseCSV(csvr *csv.Reader) (messages []smsgw.Message, warns []CSVWarn, err error) {
header, err := csvr.Read()
if err != nil {
return nil, nil, fmt.Errorf("header could not be parsed: %w", err)
}
FIELD_NAME := GetFieldIndex(header, "Name")
FIELD_PHONE := GetFieldIndex(header, "Phone")
FIELD_MESSAGE := GetFieldIndex(header, "Message")
if FIELD_NAME == -1 || FIELD_PHONE == -1 || FIELD_MESSAGE == -1 {
return nil, nil, fmt.Errorf("header is missing one or more of 'Name', 'Phone', and/or 'Message'")
}
FIELD_MIN := 1 + slices.Max([]int{FIELD_NAME, FIELD_PHONE, FIELD_MESSAGE})
rowIndex := 1 // 1-index, start at header
for {
rowIndex++
rec, err := csvr.Read()
if err == io.EOF {
break
}
if err != nil {
return nil, nil, fmt.Errorf("failed to parse row %d (and all following rows): %w", rowIndex, err)
}
if len(rec) < FIELD_MIN {
warns = append(warns, CSVWarn{
Index: rowIndex,
Code: "TooFewFields",
Message: fmt.Sprintf("ignoring row %d: too few fields (want %d, have %d)", rowIndex, FIELD_MIN, len(rec)),
Record: rec,
})
continue
}
vars := make(map[string]string)
n := min(len(header), len(rec))
for i := range n {
switch i {
case FIELD_NAME, FIELD_PHONE, FIELD_MESSAGE:
continue
default:
key := header[i]
val := rec[i]
vars[key] = val
}
}
message := smsgw.Message{
// Index: rowIndex,
Name: strings.TrimSpace(rec[FIELD_NAME]),
Number: strings.TrimSpace(rec[FIELD_PHONE]),
Template: strings.TrimSpace(rec[FIELD_MESSAGE]),
Vars: vars,
}
message.Number = smsgw.StripFormatting(message.Number)
message.Number, err = smsgw.PrefixUS10Digit(message.Number)
if err != nil {
warns = append(warns, CSVWarn{
Index: rowIndex,
Code: "PhoneInvalid",
Message: fmt.Sprintf("ignoring row %d (%s): %s", rowIndex, message.Name, err.Error()),
Record: rec,
})
continue
}
messages = append(messages, message)
}
return messages, warns, nil
}