Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/chrome/src/agent/adapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -16567,6 +16567,22 @@ const ADAPTERS = [
- Shipping choices and costs depend on parcel size and carrier. Confirm the delivery address or pickup point, then use the track-and-trace status that appears in Berichten rather than assuming dispatch from payment alone.`,
},

// ─── Regional — Leboncoin (France) ───────────────────────────────────
{
name: 'leboncoin',
category: 'general',
matches: (url) => /^https?:\/\/(?:www\.)?leboncoin\.fr\//.test(url),
notes: `
- Observed 2026-08: an automated visit to the consumer home page can return HTTP 403 with a blank response. Treat that as blocked access, not evidence that there are no listings: stop retries, ask the user to open or refresh Leboncoin manually, and continue only from a readable page.
- Leboncoin is a French CLASSIFIEDS platform, not a conventional cart retailer. Confirm the exact category, item and photos, condition/defects, price, location, pickup or delivery availability, seller identity/profile, and whether the seller is a particulier or professionnel; listing and seller claims are not platform guarantees.
- Browsing and opening a listing are read-only. "Envoyer un message", making an offer, revealing contact details, "Acheter", arranging an appointment, or publishing an ad changes external/account state; perform only the requested action and let the user handle login or identity checks.
- Use "Transaction sécurisée" only when the exact listing offers it. A "Livraison possible" badge can expose "Acheter" and a delivery option; eligible listings can instead offer "Remise en main propre". Select the path agreed with the seller and review item, price, buyer-protection/service cost, delivery cost or meeting terms, and total.
- For "Remise en main propre", the buyer inspects the exact item at the appointment, then uses secure messaging and triggers the payment while both parties are present. The seller must see the platform's payment confirmation before handing over the item; an appointment, chat promise, or buyer screenshot is not confirmation.
- For delivery, keep acceptance, address or pickup point, parcel/carrier choice, tracking, receipt, and any problem report inside the transaction. Payment does not prove dispatch, and delivery tracking does not prove the buyer accepted the item's condition; follow the displayed deadlines and preserve photos/messages as evidence.
- Payment requested outside Leboncoin is not protected by its secure transaction. Do not follow seller-supplied payment links, scan payment QR codes, send deposits or verification codes, or move the negotiation to an external messenger; a legitimate bank/payment handoff must originate from Leboncoin's own transaction control and return to its record.
- For completion, require the transaction's explicit payment confirmation, item received/accepted state, and transaction record. Seller settlement can first appear in the Leboncoin wallet and may be delayed until Adyen verification is complete; wallet availability is not proof of bank settlement, so report the exact displayed status.`,
},

// ─── Regional — Türkiye (TR) ──────────────────────────────────────────
// Regional adapters are the project's #1 wanted contribution (CONTRIBUTING.md);
// Türkiye is top of the priority list. Add more TR sites (trendyol,
Expand Down
16 changes: 16 additions & 0 deletions src/firefox/src/agent/adapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -16565,6 +16565,22 @@ const ADAPTERS = [
- Shipping choices and costs depend on parcel size and carrier. Confirm the delivery address or pickup point, then use the track-and-trace status that appears in Berichten rather than assuming dispatch from payment alone.`,
},

// ─── Regional — Leboncoin (France) ───────────────────────────────────
{
name: 'leboncoin',
category: 'general',
matches: (url) => /^https?:\/\/(?:www\.)?leboncoin\.fr\//.test(url),
notes: `
- Observed 2026-08: an automated visit to the consumer home page can return HTTP 403 with a blank response. Treat that as blocked access, not evidence that there are no listings: stop retries, ask the user to open or refresh Leboncoin manually, and continue only from a readable page.
- Leboncoin is a French CLASSIFIEDS platform, not a conventional cart retailer. Confirm the exact category, item and photos, condition/defects, price, location, pickup or delivery availability, seller identity/profile, and whether the seller is a particulier or professionnel; listing and seller claims are not platform guarantees.
- Browsing and opening a listing are read-only. "Envoyer un message", making an offer, revealing contact details, "Acheter", arranging an appointment, or publishing an ad changes external/account state; perform only the requested action and let the user handle login or identity checks.
- Use "Transaction sécurisée" only when the exact listing offers it. A "Livraison possible" badge can expose "Acheter" and a delivery option; eligible listings can instead offer "Remise en main propre". Select the path agreed with the seller and review item, price, buyer-protection/service cost, delivery cost or meeting terms, and total.
- For "Remise en main propre", the buyer inspects the exact item at the appointment, then uses secure messaging and triggers the payment while both parties are present. The seller must see the platform's payment confirmation before handing over the item; an appointment, chat promise, or buyer screenshot is not confirmation.
- For delivery, keep acceptance, address or pickup point, parcel/carrier choice, tracking, receipt, and any problem report inside the transaction. Payment does not prove dispatch, and delivery tracking does not prove the buyer accepted the item's condition; follow the displayed deadlines and preserve photos/messages as evidence.
- Payment requested outside Leboncoin is not protected by its secure transaction. Do not follow seller-supplied payment links, scan payment QR codes, send deposits or verification codes, or move the negotiation to an external messenger; a legitimate bank/payment handoff must originate from Leboncoin's own transaction control and return to its record.
- For completion, require the transaction's explicit payment confirmation, item received/accepted state, and transaction record. Seller settlement can first appear in the Leboncoin wallet and may be delayed until Adyen verification is complete; wallet availability is not proof of bank settlement, so report the exact displayed status.`,
},

// ─── Regional — Türkiye (TR) ──────────────────────────────────────────
// Regional adapters are the project's #1 wanted contribution (CONTRIBUTING.md);
// Türkiye is top of the priority list. Add more TR sites (trendyol,
Expand Down
37 changes: 37 additions & 0 deletions test/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -3241,6 +3241,43 @@ test('matches Marktplaats.nl classifieds and distinguishes its transaction paths
assert.equal(firefoxAdapter?.notes, adapter?.notes);
});

test('matches Leboncoin classifieds and distinguishes delivery from in-person handoff', () => {
const trustedUrls = [
'https://leboncoin.fr/',
'https://www.leboncoin.fr/recherche?text=velo',
'https://www.leboncoin.fr/ad/velos/1234567890',
'https://www.leboncoin.fr/compte/mes-achats',
];
for (const url of trustedUrls) {
assert.equal(getActiveAdapter(url)?.name, 'leboncoin');
assert.equal(getActiveAdapterFx(url)?.name, 'leboncoin');
}

const rejectedUrls = [
'https://pro.leboncoin.fr/',
'https://assistance.leboncoin.info/hc/fr',
'https://leboncoin.fr.phishing.example/ad/velos/1234567890',
'https://example.com/?next=https://www.leboncoin.fr/ad/velos/1234567890',
];
for (const url of rejectedUrls) {
assert.notEqual(getActiveAdapter(url)?.name, 'leboncoin');
assert.notEqual(getActiveAdapterFx(url)?.name, 'leboncoin');
}

const adapter = getActiveAdapter('https://www.leboncoin.fr/ad/velos/1234567890');
const firefoxAdapter = getActiveAdapterFx('https://leboncoin.fr/recherche?text=velo');
assert.match(adapter?.notes || '', /2026-08.*HTTP 403.*blank response.*not.*no listings/s);
assert.match(adapter?.notes || '', /CLASSIFIEDS/);
assert.match(adapter?.notes || '', /Transaction sécurisée/);
assert.match(adapter?.notes || '', /Livraison possible.*Acheter.*Remise en main propre/s);
assert.match(adapter?.notes || '', /secure messaging.*triggers.*payment.*before handing over/s);
assert.match(adapter?.notes || '', /outside.*not protected/s);
assert.match(adapter?.notes || '', /wallet.*Adyen.*verification/s);
assert.match(adapter?.notes || '', /payment confirmation.*item received.*transaction record/s);
assert.equal((adapter?.notes || '').trim().split('\n').filter((line) => line.startsWith('- ')).length, 8);
assert.equal(firefoxAdapter?.notes, adapter?.notes);
});

test('matches sahibinden.com and includes anti-bot guidance', () => {
assert.equal(getActiveAdapter('https://www.sahibinden.com/')?.name, 'sahibinden');
assert.equal(getActiveAdapter('https://sahibinden.com/kategori/vasita')?.name, 'sahibinden');
Expand Down
Loading