diff --git a/config.go b/config.go index 1483acc..9b20b3d 100755 --- a/config.go +++ b/config.go @@ -44,7 +44,7 @@ func NewConfig() Config { as := args.NewArgSet() as.Append(args.STRING, "emailuser", "email username", "breellocaldev@gmail.com") - as.Append(args.STRING, "emailpass", "email password", "ML3WQRFSqe9rQ8qNkm") + as.Append(args.STRING, "emailpass", "email password", "diblloewfncwssof") as.Append(args.STRING, "emailimap", "email imap", "imap.gmail.com:993") as.Append(args.STRING, "uploader", "todo, ledger", "todo") diff --git a/scrape.go b/scrape.go index 2beadce..73e85e9 100755 --- a/scrape.go +++ b/scrape.go @@ -29,7 +29,7 @@ func Scrape(m *mail.Message, banks map[Bank]bool) ([]*Transaction, error) { func buildScraper(m *mail.Message, banks map[Bank]bool) (scraper, error) { subject := fmt.Sprint(m.Header["Subject"]) - if !containsAny(subject, "transaction", "report", "Transaction") { + if !containsAny(subject, "transaction", "report", "Transaction", "payment") { return nil, errors.New("cannot build scraper for subject " + subject) } from := fmt.Sprint(m.Header["From"]) @@ -75,6 +75,37 @@ func (c *chaseScraper) scrape(m *mail.Message) ([]*Transaction, error) { } func (c *chaseScraper) scrape2021(m *mail.Message) ([]*Transaction, error) { + if t, err := c.scrape2021Payment(m); err == nil { + return t, err + } + return c.scrape2021Charge(m) +} + +func (c *chaseScraper) scrape2021Payment(m *mail.Message) ([]*Transaction, error) { + re := regexp.MustCompile(`^We've received your .* payment$`) + if !re.Match([]byte(m.Header["Subject"][0])) { + return nil, errors.New("no match subject search") + } + + b, err := ioutil.ReadAll(m.Body) + if err != nil { + return nil, err + } + + re = regexp.MustCompile(`\$[0-9]+\.[0-9]{2}`) + amount := "-" + strings.TrimLeft(string(re.Find(b)), "$") + + vendor := "Payment" + + re = regexp.MustCompile(`\(\.\.\.[0-9]{4}\)`) + match := re.Find(b) + re = regexp.MustCompile(`[0-9]{4}`) + account := string(re.Find(match)) + + return []*Transaction{NewTransaction(account, amount, vendor, fmt.Sprint(m.Header["Date"]), Chase)}, nil +} + +func (c *chaseScraper) scrape2021Charge(m *mail.Message) ([]*Transaction, error) { re := regexp.MustCompile(`^Your \$(?P[0-9\.]*) transaction with (?P.*)$`) matches := re.FindSubmatch([]byte(m.Header["Subject"][0])) if len(matches) < 1 { diff --git a/scrape_test.go b/scrape_test.go index d1d4d53..a3f850c 100644 --- a/scrape_test.go +++ b/scrape_test.go @@ -7,6 +7,41 @@ import ( "testing" ) +func TestScrapeChase2021Payment(t *testing.T) { + b, err := ioutil.ReadFile("./testdata/chase.2021.payment.txt") + if err != nil { + t.Fatal(err) + } + message := &mail.Message{ + Header: map[string][]string{ + "Subject": []string{"We've received your AARP from Chase 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 != "8824" { + t.Fatalf("bad account: %v: %+v", got.Account, got) + } + if got.Amount != "100.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 TestScrapeChase2021(t *testing.T) { b, err := ioutil.ReadFile("./testdata/chase.2021.txt") if err != nil { diff --git a/testdata/chase.2021.payment.txt b/testdata/chase.2021.payment.txt new file mode 100644 index 0000000..6623010 --- /dev/null +++ b/testdata/chase.2021.payment.txt @@ -0,0 +1,411 @@ + + + + + + + +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.
+ + + + + + + + + +
+ + + + +
AccountAARP fro= +m Chase (...8824)
+ + + + +
Posted dateJul 30, = +2021
+ + + + +
Payment amount= +$100.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""/
+ + + + + + + + +