import { IapticAPI } from '../iaptic-api.js';
interface SchemaProperties {
[key: string]: {
type: string;
description: string;
};
}
interface InputSchema {
type: string;
properties: SchemaProperties;
required?: string[];
}
export class CustomerTools {
constructor(private api: IapticAPI) {}
getTools() {
const appInfo = this.api.getCurrentAppInfo();
const appNameRequired = appInfo.usingMasterKey;
const baseSchema: InputSchema = {
type: "object",
properties: {
limit: {
type: "number",
description: "Maximum number of customers to return (default: 100)"
},
offset: {
type: "number",
description: "Number of customers to skip for pagination"
}
}
};
// When using master key, appName is required for all tools
if (appNameRequired) {
baseSchema.properties = {
...baseSchema.properties,
appName: {
type: "string",
description: "Name of the app to fetch data from. Required when using master key."
}
};
baseSchema.required = ["appName"];
}
return [
{
name: "customer_list",
description: `List customers from your Iaptic account.
- Returns a paginated list of customers with their purchase status
- Each customer includes:
- Application username
- Last purchase information
- Subscription status (active/lapsed)
- Renewal intent
- Trial/introductory period status
- Use limit and offset for pagination (default: 100 customers per page)
- Results are ordered by creation date (newest first)${appNameRequired ? '\n- Requires appName parameter when using master key' : ''}`,
inputSchema: baseSchema
},
{
name: "customer_get",
description: `Get detailed information about a specific customer.
- Returns complete customer profile including:
- Application username
- Purchase history
- Active and expired subscriptions
- Last purchase details
- Subscription renewal status
- Trial and introductory period information
- Required: customerId parameter${appNameRequired ? '\n- Requires appName parameter when using master key' : ''}`,
inputSchema: {
type: "object",
properties: {
customerId: {
type: "string",
description: "Unique identifier of the customer"
},
...(appNameRequired ? {
appName: {
type: "string",
description: "Name of the app to fetch data from. Required when using master key."
}
} : {})
},
required: appNameRequired ? ["customerId", "appName"] : ["customerId"]
}
},
{
name: "customer_add_purchase",
description: `Manually associate a customer with a purchase.
- Links a purchase to a specific customer
- Takes priority over receipt validation links
- Useful for manual purchase management
- Purchase format should be "platform:purchaseId", for example apple:123109519983
- Required: customerId and purchaseId${appNameRequired ? '\n- Requires appName parameter when using master key' : ''}`,
inputSchema: {
type: "object",
properties: {
customerId: {
type: "string",
description: "Application username of the customer"
},
purchaseId: {
type: "string",
description: "ID of the purchase to associate"
},
...(appNameRequired ? {
appName: {
type: "string",
description: "Name of the app to fetch data from. Required when using master key."
}
} : {})
},
required: appNameRequired ? ["customerId", "purchaseId", "appName"] : ["customerId", "purchaseId"]
}
},
{
name: "customer_subscription",
description: `Get customer's subscription status.
- Returns active subscription details if any
- Includes:
- Subscription status and expiry
- Payment and renewal information
- Trial/introductory period status
- Simpler alternative to customer_get for subscription-only apps${appNameRequired ? '\n- Requires appName parameter when using master key' : ''}`,
inputSchema: {
type: "object",
properties: {
customerId: {
type: "string",
description: "Application username of the customer"
},
...(appNameRequired ? {
appName: {
type: "string",
description: "Name of the app to fetch data from. Required when using master key."
}
} : {})
},
required: appNameRequired ? ["customerId", "appName"] : ["customerId"]
}
},
{
name: "customer_transactions",
description: `Get customer's transaction history.
- Returns list of all transactions
- Includes:
- Payment details
- Transaction status
- Associated purchases
- Timestamps${appNameRequired ? '\n- Requires appName parameter when using master key' : ''}`,
inputSchema: {
type: "object",
properties: {
customerId: {
type: "string",
description: "Application username of the customer"
},
...(appNameRequired ? {
appName: {
type: "string",
description: "Name of the app to fetch data from. Required when using master key."
}
} : {})
},
required: appNameRequired ? ["customerId", "appName"] : ["customerId"]
}
}
];
}
async handleTool(name: string, args: any) {
const appInfo = this.api.getCurrentAppInfo();
// If using master key and appName is provided, temporarily switch app
if (appInfo.usingMasterKey && args.appName) {
const currentApp = appInfo.appName;
// Switch to the requested app
this.api.switchApp('dummy-api-key', args.appName);
try {
// Execute the tool with the requested app
const result = await this._handleTool(name, args);
// Switch back to the original app
this.api.switchApp('dummy-api-key', currentApp);
return result;
} catch (error) {
// Make sure to switch back even if there's an error
this.api.switchApp('dummy-api-key', currentApp);
throw error;
}
}
return this._handleTool(name, args);
}
// Internal method to handle the tool after any app switching
private async _handleTool(name: string, args: any) {
switch (name) {
case 'customer_list':
const customers = await this.api.getCustomers(args);
return {
content: [{
type: "text",
text: JSON.stringify(customers, null, 2)
}]
};
case 'customer_get':
const customer = await this.api.getCustomer(args.customerId);
return {
content: [{
type: "text",
text: JSON.stringify(customer, null, 2)
}]
};
default:
throw new Error(`Unknown customer tool: ${name}`);
}
}
}