How to solve a software problem like a pro

Published on
-
4 mins read
Authors

Warning: The following content is heavily directed towards software development. If you think it might bore you read my other posts.

Now, I am developing a piece of web software for an online shopping platform Roli Fashions. The website operates in India and hence shipping is provided only in India via a courier named The Professional Couriers. They're widely known in South India for being a Cheap and Reliable Courier. Unfortunately, they never caught up to the latest technologies for tracking data, and for the most part still use pen and paper, frankly because they havent felt the need to update so and hence I couldn't display tracking data to the customers of the site. The courier does have a webpage written in ASP.NET that provides tracking data but it is ugly AF and is not responsive which does not help me since 99% of the sites customer base is using a mobile browser.

My immediate thought and idea was to write a scraper, that scraped the webpage for tracking data and built a JSON for me. That is just dumb since it is too resource intensive at scale, and the page uses a POST request to fetch the data and the VIEW_STATE field sent with every POST is a problem with ASP.NET.

I had given up after some scripts with selenium-webdriver and nodejs. Their dumb site then gave me the solution I was looking for. To manually track a package I had to type in the Consignment Number and Press the Stupid Track Button instead of pressing the Return Key, ike any sane person would do to submit a form. The stupid site literally had its focus set to a small android icon on the top left. It downloaded their tracker APK when I hit Return Key. This I can work with. Obviously their tech isn't smart enough. They're definitely not using the ASP.NET for the app. There had to be a GET endpoint. Open random Java Decompiler on the Internet, Deconstruct the APK, get the source, inspect, and voila! The endpoint. All it needs is the tracking number as a query param named podno for it to spit out the tracking data in plain text.

Let's Gooo!

import axios from 'axios';

Do some serious parsing and build my beloved JSON and you have

{
"status": "Delivered",
"trackingNumber": "AKM1029237",
"activities": [
{
"timestamp": "28-12-2020 11:55",
"place": "Chennai",
"forwardingNumber": "DMAA15010074",
"activity": "Delivered - Area : Selaiyur"
},
{
"timestamp": "28-12-2020 10:30:00",
"place": "Chennai",
"forwardingNumber": "IMAA113228",
"activity": "Recieved at Chennai - Selaiyur"
},
{
"timestamp": "28-12-2020 08:51:00",
"place": "Chennai",
"forwardingNumber": "IMAA60200197",
"activity": "Despatched to Chennai - Selaiyur"
},
{
"timestamp": "28-12-2020 08:23:03",
"place": "Chennai",
"forwardingNumber": "MAKM685081 ",
"activity": "Received at Chennai"
},
{
"timestamp": "26-12-2020 19:45:39",
"place": "Chennai",
"forwardingNumber": "MAKM685081 ",
"activity": "Despatched to Chennai"
}
]
}

from this

AKM1029237 is delivered at Chennai
on Monday,December 28, 2020 at 11:55
and is acknowledged with signature
Forwarding Details :
28/12/2020 Time : 11:55
City : Chennai
Forwardingno : DMAA15010074
Activity : Delivered - Area : Selaiyur
28/12/2020 Time : 10:30:00
City : Chennai
Forwardingno : IMAA113228
Activity : Recieved at Chennai - Selaiyur
28/12/2020 Time : 08:51:00
City : Chennai
Forwardingno : IMAA60200197
Activity : Despatched to Chennai - Selaiyur
28/12/2020 Time : 08:23:03
City : Chennai
Forwardingno : MAKM685081
Activity : Received at Chennai
26/12/2020 Time : 19:45:39
City : Chennai
Forwardingno : MAKM685081
Activity : Despatched to Chennai

The endpoint is http://tpcindia.com/TPCWebService/TrackMobDe.ashx?podno=AKM1029237

The code like

import axios from 'axios'
export async function getTPCTrackingData(cno: string) {
const res = await axios.get(`http://tpcindia.com/TPCWebService/TrackMobDe.ashx?podno=${cno}`)
let data: string = res.data
let tracking: any = { trackingNumber: cno }
let status = data.split('Forwarding Details : \r\n ')
tracking = { status: status[0].includes('delivered') ? 'Delivered' : 'In Transit', ...tracking }
let activities = status[1].split(' \r\n \r\n ')
const actarray = []
for (let i = 0; i < activities.length; i++) {
const act = activities[i].split(' \r\n ')
actarray[i] = {
timestamp: act[0].split(' Time : ').join(' ').split('/').join('-'),
place: act[1].split(' : ')[1],
forwardingNumber: act[2].split(' : ')[1],
activity: act[3].slice(11),
}
}
tracking = { ...tracking, activities: actarray }
return tracking
}

Also I did some digging on their site. Nothing prohibiting me from doing this. Good for me I guess.