From c6d88f6abebcf09498544688135f676b62f7dfb7 Mon Sep 17 00:00:00 2001 From: bel Date: Fri, 10 Sep 2021 09:12:26 -0600 Subject: [PATCH] impl bofa payment --- scrape.go | 53 +++++++++++++++++------ scrape_test.go | 35 ++++++++++++++++ testdata/bofa.payment.txt | 88 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 13 deletions(-) create mode 100644 testdata/bofa.payment.txt diff --git a/scrape.go b/scrape.go index 62ff3a4..6a6e597 100755 --- a/scrape.go +++ b/scrape.go @@ -252,6 +252,9 @@ func (c *bankOfAmericaScraper) scrape(m *mail.Message) ([]*Transaction, error) { if strings.Contains(subject, "Credit card transaction") { return c.scrapeCharge(m) } + if strings.Contains(subject, "Credit Card Payment") { + return c.scrapePayment(m) + } return nil, errors.New("not impl") } @@ -260,22 +263,46 @@ func (c *bankOfAmericaScraper) scrapeCharge(m *mail.Message) ([]*Transaction, er if err != nil { return nil, err } - amount := "" - acc := "" - for _, line := range bytes.Split(b, []byte("\n")) { - if amount == "" && bytes.HasPrefix(line, []byte("Amount: $")) { - words := bytes.Split(bytes.TrimSpace(line), []byte(" ")) - lastword := words[len(words)-1][1:] - escapedfloat := bytes.TrimPrefix(lastword, []byte("$")) - fixEscape := bytes.ReplaceAll(escapedfloat, []byte("=2E"), []byte(".")) - amount = string(fixEscape) - } else if acc == "" && bytes.HasPrefix(line, []byte("Where: ")) { - acc = string(bytes.TrimSpace(bytes.TrimPrefix(line, []byte("Where: ")))) - } - } + + amount := c.findFloatAfter(b, "Amount: $") + acc := string(c.findLineAfter(b, "Where: ")) + if amount == "" || acc == "" { return nil, errors.New("no amount/account found") } transaction := NewTransaction(BankOfAmerica.String(), amount, acc, fmt.Sprint(m.Header["Date"]), BankOfAmerica) return []*Transaction{transaction}, nil } + +func (c *bankOfAmericaScraper) scrapePayment(m *mail.Message) ([]*Transaction, error) { + b, err := ioutil.ReadAll(m.Body) + if err != nil { + return nil, err + } + amount := "-" + c.findFloatAfter(b, "Payment: $") + acc := "Payment" + if amount == "" || acc == "" { + return nil, errors.New("no amount/account found") + } + transaction := NewTransaction(BankOfAmerica.String(), amount, acc, fmt.Sprint(m.Header["Date"]), BankOfAmerica) + return []*Transaction{transaction}, nil +} + +func (c *bankOfAmericaScraper) findFloatAfter(b []byte, prefix string) string { + amount := string(c.findLineAfter(b, prefix)) + words := strings.Split(amount, " ") + lastword := words[len(words)-1] + escapedfloat := strings.TrimPrefix(lastword, "$") + fixEscape := strings.ReplaceAll(escapedfloat, "=2E", ".") + amount = fixEscape + return amount +} + +func (c *bankOfAmericaScraper) findLineAfter(b []byte, prefix string) []byte { + for _, line := range bytes.Split(b, []byte("\n")) { + if bytes.HasPrefix(line, []byte(prefix)) { + return bytes.TrimSpace(bytes.TrimPrefix(line, []byte(prefix))) + } + } + return nil +} diff --git a/scrape_test.go b/scrape_test.go index f145fdb..0e91b7b 100644 --- a/scrape_test.go +++ b/scrape_test.go @@ -109,6 +109,41 @@ func TestScrapeChase2020(t *testing.T) { t.Logf("%+v", got) } +func TestScrapeBofAPayment(t *testing.T) { + b, err := ioutil.ReadFile("./testdata/bofa.payment.txt") + if err != nil { + t.Fatal(err) + } + message := &mail.Message{ + Header: map[string][]string{ + "Subject": []string{"Confirmation: Thanks for Your Credit Card Payment"}, + }, + Body: bytes.NewReader(b), + } + bofa := &bankOfAmericaScraper{} + + gots, err := bofa.scrape(message) + if err != nil { + t.Fatal(err) + } + + if len(gots) != 1 { + t.Fatal(len(gots)) + } + got := gots[0] + want := Transaction{ + ID: got.ID, + Bank: BankOfAmerica, + Amount: "-251.74", + Vendor: "Payment", + Date: "[]", + Account: BankOfAmerica.String(), + } + if *got != want { + t.Fatalf("want:\n\t%+v, got\n\t%+v", want, *got) + } +} + func TestScrapeBofACharge(t *testing.T) { b, err := ioutil.ReadFile("./testdata/bofa.charge.txt") if err != nil { diff --git a/testdata/bofa.payment.txt b/testdata/bofa.payment.txt new file mode 100644 index 0000000..4268473 --- /dev/null +++ b/testdata/bofa.payment.txt @@ -0,0 +1,88 @@ +Delivered-To: breellocaldev@gmail.com +Received: by 2002:a4f:f556:0:0:0:0:0 with SMTP id s22csp88584ivo; + Fri, 10 Sep 2021 03:09:37 -0700 (PDT) +X-Google-Smtp-Source: ABdhPJy5KOCCQILLhifnSPNnjMikzSGgZX0rSLKqSzdRkpjWyZAZB7Ml4gWSWxuiMPuJMUFQZPnF +X-Received: by 2002:a05:620a:15e8:: with SMTP id p8mr6940748qkm.27.1631268577237; + Fri, 10 Sep 2021 03:09:37 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1631268577; cv=none; + d=google.com; s=arc-20160816; + b=fRiwZLXmORGlNgDHdYZ3g7DbcggjP3zVkUX1gIVHo3z/c4SLgmwu1FVu4qiUr7M2+6 + 9Ez7xjq0rG3JCLUk77q4I2MJW9pWL5LZdcMtoP9bbu5KYoZ0JwLQldFuzUOFp1qyLICc + pegPsozU1lTG3WSr2fxAi4kGgvr1PQUGd5EaeztK+u7I9SNyyOdXsgavbx0Dr+XLFAyG + eGo1WzDGy7NG8TMstFxQu+cfZiWKKtEeTFUGEjcXAUxCm/jvqK8MT1fPTwac9c66cCls + 7bvBpXlmoSEmTz6NseH0DblgWZsdmGgkYZhIUS2cJaqIhGJUFxNqbMQswEXT29LrmnbG + zz0w== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=content-transfer-encoding:feedback-id:message-id:list-id:reply-to + :mime-version:date:subject:to:from:dkim-signature; + bh=RNAxijcTyDxYmdzbEHMEKXkbCbc/Wnnsez0HenNHbUA=; + b=KtJdTZ9LFxfJTwq0gldceho7ktEybby+DLrKgjgjI2yUlaS4u0IJC2nDvkA21HjV1w + R2HMT4UITrQVoi9xa/fTsbdVIfEDjBl2rdbvO+gOthaonsCvxAsiQGFRPhmKHlbb1IiE + 9GbgjYaf4qEZCO4nQUnMKTQPK+TalO1pX3UNPHf2/KTeAuXCUrySVKgierhZIxnkS3WQ + /GUsV4gDHMhmRKEQF8yxgLv3podfCm63iOBgOZ/CCITcKkQTFUByLQ2HdAmLo9TUXHNM + sJKv6pK7e05Dxp4ZeNKlm15c5xSo3OXoRqupvsXYCbzjvR2moBrVRSB7iwZHGL45zQXQ + OVug== +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@ealerts.bankofamerica.com header.s=200608 header.b=niVgyX92; + spf=pass (google.com: domain of bounce-29_html-819616257-1667962-73720-2833596@bounce.ealerts.bankofamerica.com designates 68.232.194.2 as permitted sender) smtp.mailfrom=bounce-29_HTML-819616257-1667962-73720-2833596@bounce.ealerts.bankofamerica.com; + dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bankofamerica.com +Return-Path: +Received: from mta5.ealerts.bankofamerica.com (mta5.ealerts.bankofamerica.com. [68.232.194.2]) + by mx.google.com with ESMTPS id a7si3031949qtn.85.2021.09.10.03.09.36 + for + (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); + Fri, 10 Sep 2021 03:09:37 -0700 (PDT) +Received-SPF: pass (google.com: domain of bounce-29_html-819616257-1667962-73720-2833596@bounce.ealerts.bankofamerica.com designates 68.232.194.2 as permitted sender) client-ip=68.232.194.2; +Authentication-Results: mx.google.com; + dkim=pass header.i=@ealerts.bankofamerica.com header.s=200608 header.b=niVgyX92; + spf=pass (google.com: domain of bounce-29_html-819616257-1667962-73720-2833596@bounce.ealerts.bankofamerica.com designates 68.232.194.2 as permitted sender) smtp.mailfrom=bounce-29_HTML-819616257-1667962-73720-2833596@bounce.ealerts.bankofamerica.com; + dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bankofamerica.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=200608; d=ealerts.bankofamerica.com; + h=From:To:Subject:Date:MIME-Version:Reply-To:List-ID:X-CSA-Complaints: + Message-ID:Content-Type:Content-Transfer-Encoding; + i=onlinebanking@ealerts.bankofamerica.com; + bh=RNAxijcTyDxYmdzbEHMEKXkbCbc/Wnnsez0HenNHbUA=; + b=niVgyX923ETmQwhHEaUcs91DEv/nznIH0c7CyqIgwu0h5KtgJZIKbkIw3inZNwLL9hF+/7lfV57q + ZYXmHQVV1aXIqJLQDD5RlAq2YZvghgLdglRBbq5N9cCDTsKIA3VlrKicwN+sAwDq2JlfBv4I8rzw + Vcmfup5eqf0vJnn6k9c= +Received: by mta5.ealerts.bankofamerica.com id h7cne22fmd4j for ; Fri, 10 Sep 2021 10:09:35 +0000 (envelope-from ) +From: "Bank of America" +To: +Subject: Confirmation: Thanks for Your Credit Card Payment +Date: Fri, 10 Sep 2021 04:09:32 -0600 +MIME-Version: 1.0 +Reply-To: "Bank of America" +List-ID: <71108.xt.local> +X-CSA-Complaints: whitelistcomplaints@eco.de +x-job: 73720_1667962 +Message-ID: <3fb2377b-699b-411c-9ea5-a3b8817aa853@las1s04mta1081.xt.local> +Feedback-ID: 73720:1667962:68.232.194.2:sfmktgcld +Content-Type: text/plain; + charset="iso-8859-1" +Content-Transfer-Encoding: 7bit + +Hi, BEL, we've received your credit card payment + +Payment: $251.74 +To: National Education Association World Mas ending in - 7522 +Date posted: September 09, 2021 + +Sign in to bankofamerica.com to view your account details. + +Thank you for being our customer. + +We'll never ask for your personal information such as SSN or ATM PIN in +email messages. If you get an email that looks suspicious or you are +not the intended recipient of this email, don't click on any links. +Instead, forward to abuse@bankofamerica.com then delete it. + +Please don't reply to this automatically generated service email. +Read our Privacy Notice https://www.bankofamerica.com/privacy/consumer-privacy-notice.go +Equal Housing Lender: https://www.bankofamerica.com/help/equalhousing.cfm +Bank of America, N.A. Member FDIC +(C) 2019 Bank of America Corporation + + + + +