Sync your system into collections
Mirror a catalog, an inventory or a price list inside Meteor so your Mets can read it without you writing an endpoint per question.
Your Met answers better when it knows your business. A collection is a workspace table the Met reads and writes on its own: mirror your catalog, your inventory or your price list there, and stop writing an endpoint for every question someone might ask.
This recipe syncs an external system into a collection, nightly, without duplicating anything.
Before you start
Your key needs collections:write, items:read and items:write.
1. Create the collection and its fields
Once. Each field's name is the key the value lives under inside the item and never changes; the label is what shows on screen and you can change it.
import Met from '@meteor.ia/sdk';
const met = new Met(process.env.MET_API_KEY!, {
workspaceId: Number(process.env.MET_WORKSPACE_ID),
});
const catalog = await met.collections.create({ name: 'Catalog' });
for (const field of [
{ name: 'sku', label: 'SKU', type: 'text', required: true },
{ name: 'name', label: 'Name', type: 'text', required: true },
{ name: 'price', label: 'Price', type: 'currency' },
{ name: 'stock', label: 'Stock', type: 'number' },
{ name: 'active', label: 'Active', type: 'boolean' },
] as const) {
await met.collections.addField(catalog.id, field);
}
The available types are text, number, currency, email, date, datetime, boolean, url, select, prompt, usuario, contact, page, sitio, image and file.
2. Sync without duplicating
The collection won't enforce uniqueness for you. The pattern that works is to pull what's already there, index it by your own business key — the sku here — and decide between create and update.
// What already lives in Meteor, indexed by SKU.
const bySku = new Map<string, number>();
for await (const item of met.items.iterate(catalog.id)) {
bySku.set(item.data.sku, item.id);
}
for (const product of await pullFromYourSystem()) {
const existing = bySku.get(product.sku);
if (!existing) {
await met.items.create(catalog.id, {
sku: product.sku,
name: product.name,
price: product.price,
stock: product.stock,
active: true,
});
continue;
}
// Only what moves often: one patch per field avoids stomping on
// whatever someone edited by hand in the dashboard.
await met.items.patchField(catalog.id, existing, 'price', product.price);
await met.items.patchField(catalog.id, existing, 'stock', product.stock);
bySku.delete(product.sku);
}
// Whatever is left in the map is gone from your system.
for (const [, itemId] of bySku) {
await met.items.patchField(catalog.id, itemId, 'active', false);
}
Notice that what disappeared gets marked active: false instead of deleted. A deleted item takes with it every reference other Mets or tasks made to it; an inactive one can be filtered out and still explains why an old conversation talks about it.
3. Check the Met is seeing it
const found = await met.items.search('blue bike');
search looks across the content of the workspace's items. If your Met says "I don't have that information" and this does find it, the data isn't the problem: the Met doesn't have the collection among its own. You set that per Met — see Mets and their tools.
Running it nightly
met items list --collection 12 --limit 5 # quick check from the terminal
Any cron works. If you already use GitHub Actions, the run Meteor from CI recipe has the workflow ready.
Next
- Views, folders and the full model: Data: collections and items.
- If what you want to mirror is people rather than products, it belongs in the CRM and not in a collection: CRM and contacts.