Scripting Access to America First Credit Union

Here’s a little script I thought might be useful for others out there. I run it each morning using a cron job. It logs in to my account at America First Credit Union and sends me a summary of recent account activity. (You’ll need to change some of the variables if you decide to use it.)

NOTE: storing your account number, PIN, etc. in plain text is a bad idea. Don’t do it. That being said, here’s the script where you might want to…

#!/usr/bin/perl

# Some modules to help things get started (available from http://search.cpan.org)
use Date::Calc qw(Today);
use Mail::Sender;
use WWW::Mechanize;
use Data::Dumper;

##################################################################
# User settings...
#
# Enter your account number here:
$user_id = '12345678';
# Enter your PIN here:
$user_pin = '1234';
# Replace with your security questions & answers: several questions could have been
# selected during the registration process. You'll need to edit the regular expressions
# and the corresponding answers so they match those from your account registration.
$secure_qa = {'favorite TV show' => 'Show Title',
'favorite movie' => 'Movie Title',
'favorite activity' => 'Activity Name'};
# One more piece of security...your passphrase which you supplied when registering.
# The browser will show this to you so you know you're contacting the correct site.
$pass_phrase = 'YOUR PHRASE HERE';
# Email configuration. Enter what works for your environment...
$smtp_server = 'mail.myhost.com';
$smtp_user = 'username';
$smtp_pwd = 'password';
$email_from = 'me@myself.com';
$email_to = 'me@myself.com';
$email_cc_list = 'wife@something.com',
# End of user settings
##################################################################


$email_summary = '';

# Setup mech object
$browser = new WWW::Mechanize;
$browser->agent_alias('Linux Mozilla');

# Load the AFCU login screen, enter the account # and click the button...
$browser->get("https://webaccess.americafirst.com/jsp/login.jsp");
$browser->form_number(2);
$browser->field("user_id", $user_id);
$browser->click_button(name => 'login_button');

# The login procedure bounces around a few pages before getting to the PIN...
$content = 'transactiontype=loginBean&USERID='.$user_id;
$browser->get("https://webaccess.americafirst.com/servlet/pmservlet?tranType=login&".$content);
$browser->get("https://verifiedaccess.americafirst.com/passmark/signin.do?&detect=0");
$res = $browser->content;

# If this is the first time running from the current environment, the system will
# ask to answer a security question.
if ($res =~ m/not recognized/i) {
$browser->form_number(1);
$found_answer = 0;
for (keys %$secure_qa) {
if ($res =~ m/$_/i) {
$browser->field("answer", $secure_qa->{$_});
$found_answer++;
}
}
die $res."\nCannot register computer" unless $found_answer > 0;
$browser->field("doBind", "true");
$browser->submit();
}

# Check the pass phrase & enter the PIN
unless ($browser->content =~ m/$pass_phrase/i) {
die $browser->content."\n Incorrect security phrase.";
}
$browser->form(1);
$browser->field("PARAM_PASSWORD", $user_pin);
$browser->submit();

# Now we're logged in, so let's snag some info from the screen for our email
$account_summary = parse_summary($browser->content);
$email_summary .= "BANK SUMMARY:\n\n".summarize($account_summary)."\n=============\n";

$browser->get($account_summary->{Deposit}{Checking}{link});
$email_summary .= "LAST 20 TRANSACTIONS:\n\n".parse_checking($browser->content);

# Now, let's send the email...
$sender = new Mail::Sender;
$sender->MailMsg({
smtp => $smtp_server,
auth => 'LOGIN',
authid => $smtp_user,
authpwd => $smtp_pwd,
from => $email_from,
to => $email_to,
cc => $email_cc_list,
subject => 'Bank Summary',
msg => $email_summary,
});
exit;

sub parse_summary {
my $page = shift;
my $data = {};
$page =~ s/.+<\!-- Deposit processing -->//si;
$page =~ s/\<\/BLOCKQUOTE\>.+$//si;
$page =~ s/\*//g;
my @block = split(/<\!-- \w* processing -->/, $page);
foreach my $chunk (@block) {
my $type = "";
$chunk =~ s/.+<table[\w\s\"\=]*\>+//si;
$chunk =~ s/<\/table.*$//si;
$chunk =~ s/<tr>//sig;
$chunk =~ s/<td[\w\s\"\=]*\>//sig;
$chunk =~ s/\ \;//sig;
my @rows = split(/<\/tr>/, $chunk);
my $i = 0;
foreach my $row (@rows) {
my @rowdata = split(/<\/td>/, $row);
if ($i == 0) {
($type) = $rowdata[0] =~ m/\s?(\w*) Accounts/i;
} else {
my ($link) = $rowdata[0] =~ m/HREF=\"(.*)\"+/i;
my ($acc) = $rowdata[0] =~ m/\>(.*)<+/i;
$acc =~ s/<\/U>//i;
my ($bal) = $rowdata[1] =~ m/([\d\,]*\.+\d{2})/;
$bal =~ s/[^\d\.]//g;
$data->{$type}{$acc}{link} = $link;
$data->{$type}{$acc}{balance} = $bal;
}
$i++;
}
}
return $data;
}

sub summarize {
my $data = shift;
my $summary = "";
foreach $type (sort(keys %$data)) {
$summary .= uc($type)." Accounts:\n";
$summary .= "-----------------\n";
foreach $acc (keys %{$data->{$type}}) {
next if $acc =~ m/^\s?$/;
$summary .= "$acc\t\t$data->{$type}{$acc}{balance}\n";
$data->{$type}{total} += $data->{$type}{$acc}{balance};
}
$summary .= "-----------------\n";
$summary .= "total:\t\t$data->{$type}{total}\n\n";
}
return $summary;
}

sub parse_checking {
my $page = shift;
$checking = "";
$page =~ s/.+<\!-- Register Information -->//si;
$page =~ s/.+<input type=hidden name=ChkImgURL value="\S*\"+\>+//si;
$page =~ s/\<\/BLOCKQUOTE\>.+$//s;
$page =~ s/\<\/table\>.+$//si;
$page =~ s/\ \;//ig;
$page =~ s/<tr>//ig;
$page =~ s/style=\"font-weight\: bold\;\"//ig;
$page =~ s/\s{2,}/ /ig;
$page =~ s/<td CLASS=\"\w*\"( nowrap)?\>//ig;
$page =~ s/\r\n|\r|\n//g;
my @rows = split(/<\/tr>/, $page);
my $i = 0;
foreach (@rows) {
$i++;
my @values = split(/<\/td>/, $_);
next if !$values[0] && !$values[2] && !$values[3];
$values[0] =~ s/\s*//g;
$values[3] =~ s/\$//g;
push(@data, $record);
$checking .= "$values[0]\t$values[2]\t$values[3]\n";
last if $i >= 20;
}
return $checking;
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: