diff --git a/scrape.go b/scrape.go index cfc6df5..12a8610 100755 --- a/scrape.go +++ b/scrape.go @@ -100,9 +100,10 @@ func (c *chaseScraper) scrape2021Payment(m *mail.Message) ([]*Transaction, error return nil, err } - re = regexp.MustCompile(`\$[0-9]+\.[0-9]{2}`) + re = regexp.MustCompile(`\$[0-9,]+\.[0-9]{2}`) amount := "-" + strings.TrimLeft(string(re.Find(b)), "$") amount = strings.TrimLeft(string(re.Find(b)), "$") + amount = strings.ReplaceAll(amount, ",", "") vendor := "Payment" @@ -115,12 +116,13 @@ func (c *chaseScraper) scrape2021Payment(m *mail.Message) ([]*Transaction, error } func (c *chaseScraper) scrape2021Charge(m *mail.Message) ([]*Transaction, error) { - re := regexp.MustCompile(`^Your \$(?P[0-9\.]*) transaction with (?P.*)$`) + re := regexp.MustCompile(`^Your \$(?P[,0-9\.]*) transaction with (?P.*)$`) matches := re.FindSubmatch([]byte(m.Header["Subject"][0])) if len(matches) < 1 { return nil, errors.New("no match subject search") } amount := string(matches[1]) + amount = strings.ReplaceAll(amount, ",", "") vendor := string(matches[2]) b, _ := ioutil.ReadAll(m.Body) @@ -168,60 +170,21 @@ func (c *citiScraper) scrape(m *mail.Message) ([]*Transaction, error) { if err != nil { return nil, err } - re := regexp.MustCompile(`Citi Alert: A \$[0-9][0-9]*\.[0-9][0-9] transaction was made at .* on card ending in`) + re := regexp.MustCompile(`Citi Alert: A \$[,0-9][,0-9]*\.[0-9][0-9] transaction was made at .* on card ending in`) match := re.Find(b) if len(match) == 0 { return nil, nil } - rePrice := regexp.MustCompile(`[0-9][0-9]*\.[0-9][0-9]`) + rePrice := regexp.MustCompile(`[0-9][0-9,]*\.[0-9][0-9]`) price := rePrice.Find(match) + price = []byte(strings.ReplaceAll(string(price), ",", "")) vendor := bytes.Split(bytes.Split(match, []byte(" on card ending in"))[0], []byte("transaction was made at "))[1] transaction := NewTransaction(Citi.String(), string(price), string(vendor), date, Citi) return []*Transaction{transaction}, nil - //Citi Alert: A $598.14 transaction was made at REMIX MUSIC SPRINGDA on card ending in 3837 - /* - b, err := ioutil.ReadAll(m.Body) - if err != nil { - return nil, err - } - targetLineRegexp := regexp.MustCompile(`Account #: XXXX[0-9]{4} .*`) - targetMatches := targetLineRegexp.FindAll(b, -1) - if len(targetMatches) == 0 { - return nil, errors.New("no lines with transactions found") - } - - results := make(map[string][]string) - for _, b := range targetMatches { - // Account #: XXXX3837 $137.87 at AMZN Mktp US Amzn.com/bill WA on 04/03/2020, 09:05 PM ET - regexp := regexp.MustCompile(`Account #: XXXX[0-9]{4} \$(?P[0-9]+\.[0-9]*) at (?P[^,]*)`) - matches := regexp.FindSubmatch(b) - if len(matches) < 2 { - return nil, fmt.Errorf("no full matches found: %s", b) - } - for i, name := range regexp.SubexpNames() { - if i != 0 && name != "" { - if name == "account" { - matches[i] = bytes.Split(matches[i], []byte(" on "))[0] - } - results[name] = append(results[name], string(matches[i])) - } - } - if len(results) != 2 || len(results["amount"]) != len(results["account"]) { - return nil, fmt.Errorf("unexpected matches found looking for transactions: %+v", results) - } - } - - transactions := make([]*Transaction, len(results["amount"])) - for i := range results["amount"] { - transactions[i] = NewTransaction(Citi.String(), results["amount"][i], results["account"][i], fmt.Sprint(m.Header["Date"]), Citi) - } - - return transactions, nil - */ } func (c *uccuScraper) scrape(m *mail.Message) ([]*Transaction, error) { diff --git a/scrape_test.go b/scrape_test.go index 0e91b7b..ef7a43c 100644 --- a/scrape_test.go +++ b/scrape_test.go @@ -7,6 +7,41 @@ import ( "testing" ) +func TestScrapeChase202112Payment(t *testing.T) { + b, err := ioutil.ReadFile("./testdata/chase.2021.12.payment.txt") + if err != nil { + t.Fatal(err) + } + message := &mail.Message{ + Header: map[string][]string{ + "Subject": []string{"We've received your Chase Freedom Unlimited payment"}, + }, + Body: bytes.NewReader(b), + } + + chase := &chaseScraper{} + + gots, err := chase.scrape2021(message) + if err != nil { + t.Fatal(err) + } + if len(gots) != 1 { + t.Fatal(gots) + } + got := gots[0] + + if got.Account != "1049" { + t.Fatalf("bad account: %v: %+v", got.Account, got) + } + if got.Amount != "1750.00" { + t.Fatalf("bad amount: %v: %+v", got.Amount, got) + } + if got.Vendor != "Payment" { + t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) + } + t.Logf("%+v", got) +} + func TestScrapeChase2021Payment(t *testing.T) { b, err := ioutil.ReadFile("./testdata/chase.2021.payment.txt") if err != nil { diff --git a/testdata/chase.2021.12.payment.txt b/testdata/chase.2021.12.payment.txt new file mode 100644 index 0000000..00c6a1a --- /dev/null +++ b/testdata/chase.2021.12.payment.txt @@ -0,0 +1,408 @@ + + + + + +This payment has been applied to your account. + + + + + + + + + + + + +
+ +
+ + + + + +
3D""/ + + + +
+ +
This payment has been applied to your account.
+ + + +
 ‌ ‌ ‌ ‌ &zwn= +j; ‌ ‌ ‌ ‌ ‌ ‌&= +nbsp;‌ ‌  ‌ ‌ ‌ &zwn= +j; ‌ ‌ ‌ ‌ ‌ ‌&= +nbsp;‌ ‌ ‌ ‌ ‌ ‌&nbs= +p;‌ ‌ ‌ ‌ ‌ ‌ &= +zwnj; ‌ ‌ ‌ ‌ ‌ &zwn= +j; ‌ ‌ ‌ ‌ ‌ ‌&= +nbsp;‌ ‌ ‌ ‌ ‌ ‌&nbs= +p;‌ ‌ ‌ ‌ ‌ ‌ &= +zwnj; ‌ ‌ ‌ ‌  ‌&nbs= +p;‌ ‌ ‌ ‌ ‌ ‌ &= +zwnj; ‌ ‌ ‌ ‌ ‌ &zwn= +j; ‌ ‌ ‌ ‌ ‌ ‌&= +nbsp;‌ ‌ ‌ ‌ ‌ ‌&nbs= +p;‌ ‌ ‌ ‌ ‌ ‌ &= +zwnj; ‌ ‌ ‌ ‌ ‌ &zwn= +j; 
+ + + + + + + + + + +
+ + + +
3D"Chase
+ + + +
+ + + +
Payment received
+ + + +
+ + + + +
3D""= +We've received your credit card payment
3D""/
+ + + + + + + + + + +
3D""/ + + + + + + + + + + + + + +
This payment has been applied to you= +r account.
+ + + + + + + + + +
+ + + + +
AccountChase Fr= +eedom Unlimited (...1049)
+ + + + +
Posted dateDec 9, 2= +021
+ + + + +
Payment amount= +$1,750.00
Find more informat= +ion about the credit card payments process.
+
+ + + +
+ + + +
See payment activity
Securely access your accounts with = +the Chase Mobile® app or chase.com.
+ + + +
About this message
+
+ Chase Mobile® app is available for se= +lect mobile devices. Message and data rates may apply.
+
+ This service email was sent based on your ale= +rt settings. Use the Chase Mobile app or visit chase.com/alerts to view or manage your settings.
+
+ Chase cannot guarantee the delivery of alerts= + and notifications. Wireless or internet service provider outages or other = +circumstances could delay them. You can always check chase.com or the Chase Mobile app for the status of your accounts including= + your latest account balances and transaction details.
+
+ To protect your personal information, please = +don't reply to this message. Chase won't ask for confidential information i= +n an email.
+
+ If you have concerns about the authenticity o= +f this message or have questions about your account visit chase.com= +/CustomerService for ways to contact us.
+
+ Your privacy is important to us. See our onli= +ne Security Center to learn how to protect your infor= +mation.
+
+ © 2021 JPMorgan Chase & Co.
3D""/
+ + + + + + + +