Skip to content
Akram Moussaoui
CV PDF

call-tracking

A service that replaces the dealers’ phone number with a tracked number, produces their call and SMS statistics with Iovox, and adds an AI voicemail.

Employer
Groupe La Centrale
Role
Contributor, then lead
Period
Stack
  • TypeScript
  • AWS Lambda
  • Serverless Framework
  • Step Functions
  • DynamoDB
  • DynamoDB Streams
  • OpenSearch
  • SQS
  • SNS
  • Kinesis
  • Firehose
  • SES
  • CDK
  • CloudFormation
  • CodePipeline

Context and problem

On La Centrale, a buyer who wants to reach a dealer calls them from their listing. The service replaces the dealer's number with a tracked number that forwards to their real one.

The telephony runs on Iovox. The service produces the call and SMS statistics of 8,000 dealers and adds an AI voicemail.

My role

I joined the project as a contributor, then became its lead. I led the rotating tracking-number feature: every call a dealer receives carries the reference of the listing it came from.

I designed the service's options with Iovox, working directly with their engineers. I also wrote the browser SDK that assigns a number to each visit, set up how long numbers live and when they are released, and integrated the AI voicemail: scoping with the partner, then recordings, transcripts and summaries in the call history.

Architecture

call-tracking architecture The call: a buyer calls the tracked number provided by Iovox, drawn from a rotating pool, which forwards to the dealer's real number; the call can end on Iovox's AI voicemail. Processing on AWS: every call event carries the listing reference to TypeScript Lambdas orchestrated by Step Functions, which manage the pools of rotating numbers in DynamoDB and its Streams and index the calls in OpenSearch; a Lambda retrieves the voicemail data. Delivery: SQS, SNS, Kinesis and Firehose carry the events all the way to the SES emails sent to dealers. The infrastructure is mixed, CDK and legacy CloudFormation, deployed by CodePipeline per environment branch. THE CALL AWS PROCESSING DELIVERY Buyer calls the listing Tracked number Iovox · rotating Dealer their real number AI voicemail Iovox · voicemail Lambdas TS Serverless Framework Step Functions orchestration DynamoDB + Streams rotating pools OpenSearch indexed calls Lambda AI voicemail SQS · SNS queues and topics Kinesis then Firehose SES emails to dealers call event + listing ref. voicemail data INFRASTRUCTURE Mixed IaC: CDK (storage, certificates, OpenSearch) and legacy CloudFormation · CodePipeline per environment branch
Diagram redrawn for this site. In blue, the parts of the rotating tracker; dashed, the telephony partner. Internal services are not named.

The architecture is serverless, on AWS:

  • TypeScript Lambdas, deployed with the Serverless Framework and orchestrated by Step Functions, receive the call events from Iovox.
  • The pools of rotating numbers live in DynamoDB; DynamoDB Streams carries their changes.
  • Call events, with the listing reference, are indexed in OpenSearch.
  • SQS, SNS, Kinesis and Firehose carry the events all the way to the emails SES sends to dealers.
  • A Lambda retrieves the voicemail data of the AI voicemail.

Part of the infrastructure is written in CDK (storage, certificates, OpenSearch), the rest in legacy CloudFormation. CodePipeline deploys each environment branch.

Key decisions

A rotating tracker that carries the listing reference

Context

A buyer calls a dealer from a specific listing. The tracked number counts calls, but a number tied to the dealer alone does not say which listing the call came from.

Choice

A rotating tracker: tracked numbers are drawn from pools managed in DynamoDB. Every call carries context data, including the reference of the listing.

Rejected alternative

The default option: one tracked number per dealer, counting their calls without tying them to a listing.

Consequence

Every call a dealer receives carries the reference of its listing, and call events are indexed with it in OpenSearch.

A browser SDK instead of a direct call from each front end

Context

To tie a call to one visit, each listing page must request a number as it renders, with the visit's context: site, page type, device.

Choice

A TypeScript SDK published on npm holds the call, input validation, context collection (device and bot detection included) and a 400 ms timeout. It is covered by 43 unit tests.

Rejected alternative

The default option: each front end calls the endpoint itself and collects context its own way.

Consequence

The rules live and are tested in one place. If allocation is slow, the page still shows a number.

Design the options with Iovox, directly

Context

The tracked numbers, the forwarding, the call and SMS statistics and the AI voicemail all run on Iovox's telephony service.

Choice

The service's options are designed with Iovox, working directly with their engineers.

Rejected alternative

The default option: plug in the provider's offer as it is, without designing it with them.

Consequence

The options are designed with the partner that runs them, instead of being fitted to its offer after the fact.

Results

8,000 dealers

The service is in production for 8,000 dealers. Every call they receive carries the reference of the listing it came from. Each pool number lives 30 minutes, and unused pools are released to stop their billing.

AI in the product

The service adds an AI voicemail, provided by Iovox. I scoped its integration with the partner, then added each message's recording, transcript and AI summary to the call history, its statistics, and missed-call notifications.

Limits and what I would do differently

  • The service depends on a partner: the numbers, the forwarding and the voicemail all rely on Iovox's telephony service.
  • The infrastructure is mixed. Part of it is written in CDK, the rest in legacy CloudFormation: any infrastructure change starts with finding out which side it lives on.