Sincronizare inițială
La prima conectare a CRM trebuie să încarci toate anunțurile existente în Rentix. Datorită importului integrat de fotografii după URL, asta se face într-un singur pas.
Prezentare proces
1. Pregătire → Verificare cheie API
2. Agenți (opțional) → Invitare și legare agenți
3. Sincronizare → Încărcare bulk anunțuri cu fotografii și status
Sistemul procesează automat fotografiile, traduce descrierile și publică anunțurile. Nu trebuie să urmărești statusul fiecărei operații.
Pasul 1. Pregătire
Verifică conexiunea
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://crm.rentix.md/api/v1';
async function checkConnection() {
const response = await fetch(`${BASE_URL}/agency`, {
headers: { 'Authorization': `ApiKey ${API_KEY}` }
});
if (!response.ok) {
throw new Error('Eroare conexiune. Verifică cheia API.');
}
const agency = await response.json();
console.log(`Conectat: ${agency.name}`);
console.log(`Limită anunțuri: ${agency.limits.monthlyListings.limit}`);
return agency;
}
Pasul 2. Agenți (opțional)
Anunțurile pot fi publicate fără a fi legate de un agent anume — în acest caz se va afișa informația agenției. E convenabil în perioada de tranziție, până când nu toți agenții sunt înregistrați pe platformă.
Invitarea agenților
Agenții trebuie invitați prin interfața web — vor avea nevoie de confirmare prin telefon:
- Autentifică-te pe rentix.md
- Deschide Meniu → Numele agenției → Invitații
- Introdu email-ul agentului și trimite invitația
Legarea după înregistrare
După ce agenții au acceptat invitațiile, leagă-i la înregistrările din CRM-ul tău:
async function linkAgents(crmAgents) {
// Obține agenții din Rentix
const response = await fetch(`${BASE_URL}/users`, {
headers: { 'Authorization': `ApiKey ${API_KEY}` }
});
const { items: rentixAgents } = await response.json();
// Pregătește operațiile de legare
const operations = [];
for (const crmAgent of crmAgents) {
const match = rentixAgents.find(r => r.phone === crmAgent.phone);
if (match && !match.externalId) {
operations.push({
op: 'link',
id: match.id,
externalId: crmAgent.id
});
}
}
if (operations.length === 0) return;
// Legare bulk
await fetch(`${BASE_URL}/users/bulk`, {
method: 'POST',
headers: {
'Authorization': `ApiKey ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ operations })
});
console.log(`Agenți legați: ${operations.length}`);
}
După legare vei putea indica agenții în anunțuri după external ID din CRM-ul tău.
Pasul 3. Sincronizare anunțuri
Trimite anunțurile în pachete de câte 100. Fotografiile transmite-le după URL — sistemul le va încărca automat.
Transformarea datelor
function transformListing(crmListing) {
return {
op: 'upsert',
externalId: crmListing.id,
// Tip
announcementType: crmListing.type === 'sale' ? 'sale' : 'rent',
propertyType: 'residential',
propertySecondaryType: mapPropertyType(crmListing.category),
// Preț
announcementValue: crmListing.price,
announcementCurrency: crmListing.currency || 'EUR',
announcementPayPeriod: crmListing.type === 'rent' ? 'monthly' : undefined,
// Caracteristici
propertyArea: crmListing.area,
propertyFloorNumber: crmListing.floor,
propertyFloorsTotal: crmListing.totalFloors,
// Descriere
announcementDescription: crmListing.description,
// Fotografii — transmite URL și externalFileId pentru urmărire
files: crmListing.photos.map((photo, index) => ({
url: photo.url,
externalFileId: photo.id,
})),
// Agent (dacă e legat)
user: { externalUserId: crmListing.agentId },
// Publicăm imediat
announcementStatus: 'active'
};
}
function mapPropertyType(category) {
const map = {
'apartament': 'apartment',
'casă': 'house',
'cameră': 'room',
};
return map[category];
}
Trimitere în pachete
function chunkArray(array, size) {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
}
async function syncListings(crmListings) {
const operations = crmListings.map(transformListing);
const chunks = chunkArray(operations, 100);
let total = 0;
// Trimite pachetele secvențial
for (const chunk of chunks) {
const response = await fetch(`${BASE_URL}/listings/bulk`, {
method: 'POST',
headers: {
'Authorization': `ApiKey ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ operations: chunk })
});
const result = await response.json();
total += result.summary.succeeded;
console.log(`Procesate: ${total}/${crmListings.length}`);
// Logează erorile
const failed = result.results.filter(r => !r.success);
for (const f of failed) {
console.error(`Eroare ${f.externalId}: ${f.error?.message}`);
}
}
return total;
}
Script complet
async function fullSync() {
console.log('=== Sincronizare inițială ===');
// 1. Verifică conexiunea
console.log('\n1. Verificare conexiune...');
await checkConnection();
// 2. Obține date din CRM
console.log('\n2. Obținere date din CRM...');
const crmListings = await getListingsFromCRM(); // funcția ta
console.log(`Găsite: ${crmListings.length} anunțuri`);
// 3. Sincronizare anunțuri
console.log('\n3. Sincronizare anunțuri...');
const synced = await syncListings(crmListings);
console.log('\n=== Sincronizare finalizată ===');
console.log(`Trimise: ${synced} anunțuri`);
console.log('Anunțurile vor apărea pe site după procesare.');
}
fullSync().catch(console.error);
Ce se întâmplă după trimitere
După trimiterea datelor, sistemul automat:
- Încarcă fotografiile după URL-urile indicate
- Optimizează imaginile — comprimare, conversie, creare previzualizări
- Analizează fotografiile — determină caracteristicile obiectului (facilități, mobilier etc.)
- Traduce descrierea în toate limbile platformei
- Publică anunțul — statusul devine
active
Nu trebuie să urmărești statusul fiecărei operații. Dacă apare o eroare, o vei vedea în rezultatul cererii bulk.
Ce urmează
După sincronizarea inițială, configurează sincronizarea continuă pentru actualizarea regulată a datelor.