In today's fast-paced digital marketplace, tracking competitors' pricing strategies is essential for maintaining a competitive edge. This article will guide you through setting up an automated price monitoring system using Airtop's AI capabilities and TypeScript.
What You'll Learn
How to set up the Airtop TypeScript SDK
Creating a script to monitor competitors' pricing pages
Automating price change detection
Implementing a system that compares new pricing with historical data
Prerequisites
Node.js 14+
Basic TypeScript knowledge
A free Airtop API Key
Setting Up Your Environment
First, you'll need to install the Airtop TypeScript SDK:
npm install @airtop/sdk
# or
yarn add @airtop/sdk
Creating the Price Monitoring Script
Let's break down the process of creating a TypeScript script that monitors competitor pricing pages:
Step 1: Import Required Libraries
import { AirtopClient, AirtopError } from "@airtop/sdk";
import type { AirtopSessionConfigV1 } from "@airtop/sdk/wrapper/AirtopSessions";
Step 2: Configure Your Airtop Client
const AIRTOP_API_KEY = "";
Step 3: Create the Main Function
async function run() {
let client: AirtopClient | null = null;
let sessionId: string | null = null;
const profileName = undefined;
try {
if (!AIRTOP_API_KEY) {
throw new Error("AIRTOP_API_KEY is not set");
}
client = new AirtopClient({
apiKey: AIRTOP_API_KEY,
});
const configuration: AirtopSessionConfigV1 = {
profileName,
timeoutMinutes: 10,
};
const session = await client.sessions.create({ configuration });
if (!session || session.errors) {
throw Error("Failed to create session");
}
sessionId = session.data.id;
if (profileName) {
console.log("Using profile:", profileName);
await client.sessions.saveProfileOnTermination(sessionId, profileName);
}
Step 4: Open the Target Pricing Page
const window = await client.windows.create(session.data.id, { url: "https://www.descript.com/pricing" });
if (!window.data) {
throw Error("Failed to create window");
}
await new Promise((resolve) => setTimeout(resolve, 5000));
const { windowId } = window.data;
Step 5: Query the Page with AI
This is where the magic happens. We'll use Airtop's AI capabilities to analyze the pricing page:
const promptResponse = await client.windows.pageQuery(sessionId, windowId, {
prompt: `[YOUR_PROMPT]`,
});
if (promptResponse.errors && promptResponse.errors.length > 0) {
throw Error("Failed to prompt content");
}
console.log("Prompt results", promptResponse.data.modelResponse);
As a prompt for the above, we could use the following:
This is a pricing page. Please summarize it concisely by including every plan. For each plan, list the price and the top 3 features it includes. Compare the current plan to the previous plan described below:
This is a pricing page. Please summarize it concisely by including every plan.
For each plan, list the price and the top 3 features it includes.
Compare the current plan to the previous plan described below:
Free Plan: $0 - Includes text-based editing, AI tools trial, and 1 hour of transcription per month.
Hobbyist Plan: $10 per person/month (annual) or $24 (monthly) - Offers 10 transcription hours/month, 1080p export, and 20 uses/month of Basic AI suite.
Creator Plan: $22 per person/month (annual) or $39 (monthly) - Provides 30 transcription hours/month, 4k export, and unlimited use of Basic and Advanced AI suite.
Business Plan: $55 per person/month (annual) or $70 (monthly) - Includes 40 transcription hours/month, free Basic seats for collaboration, and unlimited access to Professional AI suite.
Enterprise Plan: Custom pricing - Tailored solutions with enterprise-grade security.
RETURN ONLY 3 FIELDS:
1. TEXT - A textual description of the pricing, including the plan's name, price, and top 3 features.
2. TEXT - If there are significant differences in the PRICES between the previous plan and the current one,
summarize the differences concisely in a textual description, focusing only on the changes in prices.
3. STATUS - In a status field, return [DIFF] if the new plan is substantially different from the previous one,
[SIMILAR] if they are similar, or [NEW] if the previous pricing is empty.
- important, do not guess or estimate, just report things that are clearly mentioned in pricing page
Step 6: Handle Errors and Clean Up
} catch (err) {
if (err instanceof AirtopError) {
console.log(err.statusCode);
console.log(err.message);
console.log(err.body);
} else {
console.log(err);
}
throw err;
} finally {
if (client != null && sessionId != null) {
await client.sessions.terminate(sessionId);
}
}
}
run().catch((err) => {
process.exit(1);
});
How It Works
Session Creation: The script initializes an Airtop session with your API key.
Browser Automation: It opens a browser window and navigates to the competitor's pricing page.
AI Analysis: Airtop's AI capabilities analyze the pricing page content.
Comparison: The AI compares the current pricing with previously stored pricing data.
Change Detection: It identifies if there are significant changes in pricing or features.
Customizing the Script
Monitor Multiple Competitors
You can easily modify the script to monitor multiple competitors by creating an array of URLs and processing them sequentially:
const competitorUrls = [
"https://www.competitor1.com/pricing",
"https://www.competitor2.com/pricing",
"https://www.competitor3.com/pricing"
];
for (const url of competitorUrls) {
const window = await client.windows.create(sessionId, { url });
}
Scheduling Regular Checks
For regular monitoring, you can use scheduling libraries like node-cron:
import cron from 'node-cron';
cron.schedule('0 9 * * *', () => {
console.log('Running price monitoring job');
run().catch(console.error);
});
(optional) Storing and Analyzing Results
To make this system truly useful, you'll want to store the results in a database for historical comparison. You can use any database system for that; for this example, we’ll be using Prisma.
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function storeResults(competitorName: string, pricingData: string, status: string) {
await prisma.pricingHistory.create({
data: {
competitor: competitorName,
pricingData,
status,
timestamp: new Date()
}
});
}
You'll need to set up a Prisma schema first:
model PricingHistory {
id Int @id @default(autoincrement())
competitor String
pricingData String @db.Text
status String
timestamp DateTime @default(now())
}
(optional) Setting Up Notifications
You can add notifications to alert you when price changes are detected. For this example, we'll be using Nodemailer, but you can use any notification system you like and customize it to fit your needs:
import nodemailer from 'nodemailer';
async function sendNotification(subject: string, message: string) {
const transporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 587,
secure: false,
auth: {
user: 'your-email@example.com',
pass: 'your-password'
}
});
await transporter.sendMail({
from: 'your-email@example.com',
to: 'recipient@example.com',
subject,
text: message
});
}
(optional) Integrating with Slack
For team-wide notifications, you might want to integrate with Slack:
import axios from 'axios';
async function sendSlackNotification(message: string) {
const webhookUrl = 'YOUR_SLACK_WEBHOOK_URL';
await axios.post(webhookUrl, {
text: message
});
}
Creating a Complete Monitoring System
Let's put it all together to create a complete monitoring system:
async function monitorCompetitor(url: string, competitorName: string, previousData?: string) {
const client = new AirtopClient({
apiKey: AIRTOP_API_KEY,
});
let sessionId: string | null = null;
try {
const session = await client.sessions.create({
configuration: { timeoutMinutes: 10 }
});
sessionId = session.data.id;
const window = await client.windows.create(sessionId, { url });
const { windowId } = window.data;
await new Promise((resolve) => setTimeout(resolve, 5000));
const promptResponse = await client.windows.pageQuery(sessionId, windowId, {
prompt: `This is a pricing page. Please summarize it concisely by including every plan. For each plan, list the price and the top 3 features it includes. Compare the current plan to the previous plan described below:
"${previousData || ''}"
RETURN ONLY 3 FIELDS:
1. TEXT - A textual description of the pricing, including the plan's name, price, and top 3 features.
2. TEXT - If there are significant differences in the PRICES between the previous plan and the current one, summarize the differences concisely in a textual description, focusing only on the changes in prices.
3. STATUS - In a status field, return [DIFF] if the new plan is substantially different from the previous one, [SIMILAR] if they are similar, or [NEW] if the previous pricing is empty.
`
});
const result = promptResponse.data.modelResponse;
const statusMatch = result.match(/STATUS: \[(.*?)\]/);
const status = statusMatch ? statusMatch[1] : 'UNKNOWN';
await storeResults(competitorName, result, status);
if (status === 'DIFF') {
await sendNotification(
`Price Change Detected: ${competitorName}`,
`A price change has been detected for ${competitorName}.\n\nDetails:\n${result}`
);
await sendSlackNotification(
`🚨 *Price Change Alert*: ${competitorName}\n\n${result}`
);
}
return result;
} finally {
if (sessionId) {
await client.sessions.terminate(sessionId);
}
}
}
Conclusion
With this TypeScript script, you've created an automated system that monitors your competitors' pricing pages and alerts you to any changes. This allows you to stay competitive in the market and make informed pricing decisions.
By leveraging Airtop's AI capabilities, you can extract structured data from unstructured web pages without complex web scraping or HTML parsing. This makes the system more robust and less prone to breaking when the website layout changes.
When monitoring competitor websites, remember to comply with all legal and ethical considerations, including respecting robots.txt files and terms of service.
Try this script today and never miss a competitor's price change again!
Next Steps
Add support for capturing screenshots of pricing pages
Implement a simple dashboard to visualize pricing changes over time
Expand the AI prompt to capture more detailed information about feature changes
Set up a CI/CD pipeline to run your monitoring script automatically
Happy monitoring!