← All work PRICE-LIST PARSER ←01 / 07→RU

A price list
out of chat messages

An electronics store buys from seventeen suppliers. Each one sends prices over WhatsApp — plain messages, in no particular order, all day long. The program reads those messages, builds one master price list from them, compares it with competitors’ prices and publishes it to customers on its own.

Price listTodaySuppliersReviewMarkupsCompetitors admin
Search: iPhone 17 Category: All ☑ Current only Items 2 930USD rate 81.4 ₽
Supp.ProductRegionSIMStorageColourQtyPrice $With markupStatus
S-03iPhone 17 Pro MaxJapaneSIM256GBCosmic Orange241 2851 32511:34
S-03iPhone 17 ProUSAeSIM256GBDeep Blue91 1051 14511:34
S-07iPhone 17 AirUAEeSIM512GBSky Blue411 1901 24011:02
S-01iPhone 16 ProChinaDual128GBBlack Titanium684588510:48
S-04MacBook Pro 14 M4EU—16GB/512GBSpace Black31 6901 76009:57
S-07iPad Pro 13 M4HKLTE1TBSilver51 5401 600yesterday
S-02Galaxy S26 UltraUAEDual512GBTitanium Gray181 0601 11011:12
S-05AirPods Pro 2UAE——White6016818210:31
S-06iPhone 17India1 SIM256GBLavender24915oddcheck
WhatsApp link: up· Last price list parsed at 11:34· Awaiting review: 7· Competitor snapshot: today

The working screen · sample figures, supplier names hidden

For whom

A wholesale electronics store: 17 suppliers write their prices in WhatsApp

What was done

The program reads the chats, builds a master price list, works out the markup by weight and route and publishes to the channels

Result

The manager’s morning is free, 1,300+ items update themselves, competitors’ prices are compared every day

Film · 36 seconds, no sound, in Russian · one supplier line from WhatsApp to the channel

Every morning started with retyping prices

Every morning a manager opened seventeen chats, picked the fresh prices out of everyday conversation and retyped them into a spreadsheet. Then from the spreadsheet into posts for customers. Every day, weekends included.

The cost of a mistake is simple. Miss a message and a customer does not buy in time. Mistype a digit and the company loses margin. And asking twenty suppliers to write “properly, in a set format” is pointless: each writes the way they always have.

How suppliers write
S-03🇯🇵 17 Pro Max 256 Cosmic Orange — 1285$ (24pcs)
17 Pro 256 Deep Blue USA — 1105 (9)
S-07iPhone 17 Air 512 sky blue uae esim 1190 in stock 41
S-02galaxy s26 ultra 512 titan grey
1060 dubai, 18 pcs
→
What the store gets
S-03iPhone 17 Pro MaxJapan · eSIM · 256GB · Cosmic Orange24 · 1 285 $
S-03iPhone 17 ProUSA · eSIM · 256GB · Deep Blue9 · 1 105 $
S-07iPhone 17 AirUAE · eSIM · 512GB · Sky Blue41 · 1 190 $
S-02Galaxy S26 UltraUAE · Dual · 512GB · Titanium Gray18 · 1 060 $

Sample messages · three different suppliers on one morning

What makes it hard

Putting prices into one table sounds simple — until you see what those messages actually look like.

01

Even one supplier writes differently each time

Today a tidy list, tomorrow a wall of text with country flags, the day after three messages in a row and a one-line correction chasing them. Every supplier has their own format, and each one changes it from day to day. The program parses all of it by itself and brings it to one form.

02

Mistakes are not an option

People buy and sell on these numbers. Anything suspicious — a price half the market rate, an item with no model, an odd discount — never reaches customers; it goes to a separate list for a human to check.

03

Thinking is expensive

Parsing a message with an AI model costs money, and dozens of price lists arrive a day, often differing by a single digit. So the system first tries to cope on its own and calls the model only when a message is genuinely new.

A day in the system

The system runs on the market’s schedule. Nobody starts anything by hand.

from 7:00 Price lists arrive Suppliers in Dubai start their day and send prices. Each message is checked, parsed and lands in the master table within a minute.
morning Competitor snapshot Two competitors’ price lists come in, get parsed and sit next to our prices in one table.
10:40 and 11:30 Morning files Twice each morning the system builds the very document that used to be made by hand: the list of groups and today’s price lists verbatim. The second file holds only what came in after the first.
10:30–16:00 Publishing to customers Channel posts update as prices arrive — edited in place, not re-sent. Outside working hours the system stays quiet so notifications do not wake anyone.
17:00 Cut-off Anything that arrives later no longer counts as today’s price: a late price in the morning list is more dangerous than a missing one. Sundays are skipped entirely.

What counts
as a
price list

Supplier chats are full of ordinary conversation: orders, questions, photos, “good morning”. Messages with prices are a small share, and the program has to tell them apart from everything else before spending time and money on parsing.

Parser11:52
Looks like a price list, but not sure. Group S-06, sender not on the list:iphone 17 256 lavender 915 india, 24 pcs, fresh
ParseSkip
01 Known senders only In every group the system knows by name which members send prices. A message from anyone else is not parsed — but not lost either: the morning file shows a line noting it was there.
02 An order is not a price list Customer orders and everyday chat are recognised as what they are and never change prices. Orders go to a separate bot, which attaches purchase prices to each line.
03 Repeats do not count If a supplier sends exactly the same text as yesterday, the system does not parse it again — it just marks the prices as confirmed.
04 When unsure, it asks If a message looks like a price list but the system is not sure, it forwards it to Telegram with two buttons: “parse” or “skip”. The human’s decision is remembered.
How a message becomes a price listA supplier message passes checks of sender, type, repetition and confidence before the AI model and the master table.YESPRICESNEWSURENOORDER, CHATYESNOT SUREPARSE ITMessage in a group17 suppliers · WhatsAppKnown sender?Is it a price list?Same textas yesterday?Confident?The AI model parses itonly new text · costs moneyMaster price tablewithin a minuteNot a price listlisted in the morning filePrices confirmedno second parseA person decides“parse” / “skip” buttonsstart and enddecisionactionkey stepsometimes / loop back

A message’s path to the master table

→ the diagram scrolls sideways

The markup
is calculated

The easiest thing is to add one flat percentage to everything. But that loses money: earphones and a laptop ship very differently, and the same surcharge means the store is certainly losing on something. So every product has its own markup, its own weight and its own shipping cost — more than thirteen hundred products in all.

What is left of a $40 markup

Markup on the item + 40,00 $
Shippingweight 0.45 kg × $20 per kilogram − 9,00 $
Currency exchange lossat the rates of the route the goods travel − 1,20 $
Net profit 29,80 $

Sample figures. Weight, cost per kilogram and route differ for every item — and all three change.

01 Weight and cost per kilogram are set per item Earphones weigh grams, a laptop weighs kilograms, and each ships at its own cost. The system stores the item’s weight and the per-kilogram rate for its route, and recalculates shipping for every line separately.
02 Each route adds its own loss Money does not reach the supplier directly, and every conversion loses a percentage. Each route has its own rates, each item is tied to a route — and that loss is deducted from profit automatically instead of living in someone’s head.
03 Settings change on the fly Markups are edited in an ordinary Google Sheet — easier for the person who works with them; the system checks it every ten minutes and picks up changes. If the exchange rate moves, every stored price is recalculated. Change a markup and the channels update in the next working window, with no manual recalculation.
04 A floor the price never drops below The old safeguard was a two-dollar minimum markup — and it did not safeguard anything: at 0.3 kg, shipping alone eats six. There was a day when, of thirty-nine items priced against a competitor, twenty went negative, as low as minus fourteen dollars on one. Now the floor is set on net profit: three dollars is the line below which the system will not drop a price, even if a competitor is cheaper.

Two competitors,
every day

Knowing your own price is not enough — you need to know whether it is above or below the competition. Two competitors’ price lists arrive every day: one as a file, the other as text in a chat. The program parses them just like supplier messages.

ProductCompetitor 1Competitor 2Our priceDecision
iPhone 17 Pro Max 256GB109 900 ₽110 400 ₽109 800 ₽100 ₽ cheaper
iPhone 17 Air 512GB101 200 ₽—101 100 ₽100 ₽ cheaper
AirPods Pro 215 400 ₽15 600 ₽15 900 ₽lower = loss
Galaxy S26 Ultra 512GB92 700 ₽93 100 ₽92 600 ₽100 ₽ cheaper

The comparison view · sample prices

→ the table scrolls sideways
01 A simple rule, with a limit Be a hundred roubles cheaper than the competitor — as long as the item still clears at least three dollars net. If it does not, the system leaves the price alone: it is better to let the competitor have that order than to sell at a loss.
02 New markups apply with one button The system never changes prices silently. It shows the finished calculation: how many lines were parsed, how many matched our stock, where the price will drop and by how much. The owner looks and presses “apply” — or does not.
03 A separate daily report Items where we are noticeably below the market go out as a separate Telegram message — a ready-made sales argument.
DetailsThree more sections: exchange rates, reconciliation with the books, what happens when the connection dropsExpand ↓Collapse ↑

Rates
move —
so do prices

Some suppliers price in dollars, some in dirhams, customers pay in roubles. While rates hold, nothing shows; once they move, yesterday’s price becomes a loss-making deal.

So current rates are pulled in automatically, and when they change the system recalculates every stored price, not just new ones. Before this was fixed, some items lived for months at the rate of the day they were parsed.

01 Google Sheet The master price list is exported to the sheet people are used to: it can be opened on a phone, sent, printed.
02 Telegram channels and groups Five separate feeds: wholesale, retail, price comparison, the competitor snapshot, and a direct-message digest of good deals.
03 Two bots for people One answers “how much is it” in a second; the other takes a customer’s order and attaches purchase prices to it.

One product —
one code
in the books

The price list and the inventory system must refer to the same product. Until they do, one model lives in the books under two codes, stock levels drift from reality, and the customer app shows duplicate cards — with nobody able to say which is real.

Sorting it out once is not enough: suppliers send new items every day. So beyond the reconciliation itself there are now rules for how it is done, and checks that keep things in order afterwards.

01 Part numbers are normalised The same product is written differently across documents: part numbers carry regional suffixes and spelling variants. Matching uses the stable part of the code, not however it was typed on a given line.
02 A code is assigned only on an unambiguous match If one part number points to different codes in the catalogues, the system does not guess — it leaves the line to a human. It never touches codes already set, and never infers from colour or name.
03 Duplicates are hunted separately A regular check looks for one code spread across different products, one product with two codes, and items left without a category. The bulk of these collisions was cleaned up by hand; from then on a watchdog catches them — and never fixes anything silently, only reports.
04 Disputed items live on an exceptions list Sometimes the code is formally correct but the record itself is contradictory: a 44 mm watch carries the weight of the 46 mm version. Such items are listed with a note on why they are left alone — otherwise the nightly reconciliation would bring them back every night, and a person would go over the same thing in circles.
05 Reconciliation runs at night and can “show without doing” Once a day the system goes through a fresh export from the books and fills in empty codes. There is a mode where it only reports what it is about to do — used after every major catalogue edit.
One product, one codeA part number is normalised, a code is assigned only on an unambiguous match, disputed lines go to a person and the exceptions list, a nightly check and a duplicate watchdog keep order.ONE0 OR MANYDISPUTEDEMPTY CODESCOLLISIONSPart number from a price lista new supplier lineThe stable part of the coderegional suffixes droppedMatchesin the catalogues?Code assignedonly on an unambiguous matchDuplicate watchdogchanges nothing silentlyOne product, one codein the price list and the booksA person sorts the line outno guessing by colour or nameExceptions listwith a note on why it is left aloneNightly checkonce a day · empty codesstart and enddecisionactionkey stepsometimes / loop back

How a price-list line gets its catalogue code

→ the diagram scrolls sideways

Watches
over itself

The program sits between suppliers and customers: if it stops, the store is blind to prices. The most dangerous failure is the one nobody notices. In August the WhatsApp link dropped, while monitoring watched only the website — which kept responding as if nothing had happened. Prices went stale for two days.

After that the monitoring was rewritten: the system now checks not that it is running, but that it is actually doing its job.

Monitor11:42
WhatsApp link lost. Price lists are not being read.
12:12 · Link still down.
12:31 · Link restored. Catching up: 14 messages from the last 49 minutes.

Sample notifications

01 Keeps reminding until it is fixed A dropped link triggers not one alert but a repeating one — and a separate message once everything is back.
02 Notices silence A separate check looks at the outcome: if no price lists arrive during working hours, it says so, even when the connection is formally fine.
03 Catches up on what it missed After any downtime the system reads back the whole working day’s messages on its own and parses what it missed. A server restart never loses a price list.
04 Keeps backups The database is backed up on a schedule and supplier messages are kept in their original form — any day can be revisited and its price list rebuilt from scratch.

The outcome

The manager’s morning is entirely free. The price list assembles itself, compares itself with competitors and reaches customers by itself. The person does purchasing, not retyping numbers.

01 · WhatsApp17 suppliers write as they always have
→
02 · Parsing and checksOne shape for allanything suspicious goes to a human
→
03 · Master price listMarkup by weight and routea profit floor on every item
→
04 · CompetitorsTwo price lists every daynew prices with one button
→
05 · PublishingFive channels and a Google Sheetwith no human involved
17 suppliers read automatically, without a single request to change their format
2 competitors compared daily, with new prices applied by one button
1 326 items with their own markup that updates itself
5 channels updated with no human involved

Built with: Node.js, SQLite, Claude, Express, Google Sheets, Telegram.
27,240 lines of code · in daily use since April 2026 · my role: architecture, development, support.

Message me on Telegram → ← All work Next project · 02 / 07Smart store →
Message