brainerce 1.44.1 → 1.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +221 -34
- package/dist/index.d.mts +286 -2
- package/dist/index.d.ts +286 -2
- package/dist/index.js +147 -5
- package/dist/index.mjs +147 -5
- package/package.json +81 -81
package/README.md
CHANGED
|
@@ -32,28 +32,28 @@ yarn add brainerce
|
|
|
32
32
|
|
|
33
33
|
Every Brainerce storefront must include **all mandatory features** below. Features auto-hide when the underlying capability is disabled, so build them all anyway — they'll appear the moment the store owner enables them.
|
|
34
34
|
|
|
35
|
-
| Feature | SDK entry point
|
|
36
|
-
| ------------------------------------------------------- |
|
|
37
|
-
| Product list with search, filter, pagination | `client.getProducts()`, `client.getSearchSuggestions(query)`
|
|
38
|
-
| Product detail with variant picker, stock, price | `client.getProductBySlug()` + helpers
|
|
39
|
-
| Buyer customization fields (engraving, uploads, select) | `product.customizationFields`, `client.uploadCustomizationFile()`
|
|
40
|
-
| Cart (add, update, remove, coupon, totals) | `client.addToCart()`, `getCartTotals(cart)`
|
|
41
|
-
| Inventory reservation countdown | Cart expiry timestamp from `client.getCart()`
|
|
42
|
-
| Full checkout end-to-end with payment | `setShippingAddress → selectShippingMethod → getPaymentProviders → pay → handlePaymentSuccess → waitForOrder`
|
|
43
|
-
| Order confirmation (clear cart + wait for real order) | `client.handlePaymentSuccess()`, `client.waitForOrder()`
|
|
44
|
-
| Register + email verification flow | `client.registerCustomer()`, `client.verifyEmail()`
|
|
45
|
-
| Login + verification branch | `client.loginCustomer()`
|
|
46
|
-
| Forgot / reset password | `client.forgotPassword()`, `client.resetPassword()`
|
|
47
|
-
| OAuth sign-in buttons + callback handler | `client.getAvailableOAuthProviders()`
|
|
48
|
-
| Account area (profile + order history) | `client.getMyProfile()`, `client.getMyOrders()`
|
|
35
|
+
| Feature | SDK entry point | Mandatory |
|
|
36
|
+
| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ----------- |
|
|
37
|
+
| Product list with search, filter, pagination | `client.getProducts()`, `client.getSearchSuggestions(query)` | ✅ |
|
|
38
|
+
| Product detail with variant picker, stock, price | `client.getProductBySlug()` + helpers | ✅ |
|
|
39
|
+
| Buyer customization fields (engraving, uploads, select) | `product.customizationFields`, `client.uploadCustomizationFile()` | ✅ |
|
|
40
|
+
| Cart (add, update, remove, coupon, totals) | `client.addToCart()`, `getCartTotals(cart)` | ✅ |
|
|
41
|
+
| Inventory reservation countdown | Cart expiry timestamp from `client.getCart()` | ✅ |
|
|
42
|
+
| Full checkout end-to-end with payment | `setShippingAddress → selectShippingMethod → getPaymentProviders → pay → handlePaymentSuccess → waitForOrder` | ✅ |
|
|
43
|
+
| Order confirmation (clear cart + wait for real order) | `client.handlePaymentSuccess()`, `client.waitForOrder()` | ✅ |
|
|
44
|
+
| Register + email verification flow | `client.registerCustomer()`, `client.verifyEmail()` | ✅ |
|
|
45
|
+
| Login + verification branch | `client.loginCustomer()` | ✅ |
|
|
46
|
+
| Forgot / reset password | `client.forgotPassword()`, `client.resetPassword()` | ✅ |
|
|
47
|
+
| OAuth sign-in buttons + callback handler | `client.getAvailableOAuthProviders()` | ✅ |
|
|
48
|
+
| Account area (profile + order history) | `client.getMyProfile()`, `client.getMyOrders()` | ✅ |
|
|
49
49
|
| Loyalty & rewards (points balance + tiers + redeem) | `client.getLoyaltyStatus()`, `client.getAvailableRewards()`, `client.redeemLoyaltyReward(id)`, `client.reportSocialShare()` | conditional |
|
|
50
|
-
| Global header: cart count + search autocomplete | `client.getCart()`, `client.getSearchSuggestions(query)`
|
|
51
|
-
| Discount banners + product badges | `client.getDiscountBanners()`, `client.getProductDiscountBadge(productId)`
|
|
52
|
-
| Product reviews on PDP + JSON-LD aggregateRating | `client.listProductReviews(id)`, `client.submitProductReview(id, …)`
|
|
53
|
-
| Site chrome (header + footer + announcement bar) | `client.content.header.get()`, `client.content.footer.get()`, `client.content.announcement.list()`
|
|
54
|
-
| FAQ page | `client.content.faq.get('main', locale)`
|
|
55
|
-
| Static pages catch-all (`/pages/[slug]`) | `client.content.page.getBySlug(slug, locale)`
|
|
56
|
-
| Multi-language + RTL (when i18n enabled) | `client.setLocale()`, `client.getStoreDirection(locale)`
|
|
50
|
+
| Global header: cart count + search autocomplete | `client.getCart()`, `client.getSearchSuggestions(query)` | ✅ |
|
|
51
|
+
| Discount banners + product badges | `client.getDiscountBanners()`, `client.getProductDiscountBadge(productId)` | ✅ |
|
|
52
|
+
| Product reviews on PDP + JSON-LD aggregateRating | `client.listProductReviews(id)`, `client.submitProductReview(id, …)` | ✅ |
|
|
53
|
+
| Site chrome (header + footer + announcement bar) | `client.content.header.get()`, `client.content.footer.get()`, `client.content.announcement.list()` | ✅ |
|
|
54
|
+
| FAQ page | `client.content.faq.get('main', locale)` | conditional |
|
|
55
|
+
| Static pages catch-all (`/pages/[slug]`) | `client.content.page.getBySlug(slug, locale)` | conditional |
|
|
56
|
+
| Multi-language + RTL (when i18n enabled) | `client.setLocale()`, `client.getStoreDirection(locale)` | conditional |
|
|
57
57
|
|
|
58
58
|
---
|
|
59
59
|
|
|
@@ -874,6 +874,36 @@ console.log('Order created:', orderId);
|
|
|
874
874
|
|
|
875
875
|
> **WARNING:** Do NOT use `submitGuestOrder()` for logged-in customers! Their orders won't be linked to their account and won't appear in their order history.
|
|
876
876
|
|
|
877
|
+
### Address Autocomplete (optional, for the `line1` field)
|
|
878
|
+
|
|
879
|
+
Turn the shipping address's `line1` input into a typeahead instead of free
|
|
880
|
+
text. Suggestions come from Google Places; each resolved address is flagged
|
|
881
|
+
`inZone` against the store's configured shipping zones — a soft signal for a
|
|
882
|
+
warning banner, never a hard block.
|
|
883
|
+
|
|
884
|
+
```typescript
|
|
885
|
+
const sessionToken = crypto.randomUUID(); // one per address-entry attempt
|
|
886
|
+
|
|
887
|
+
// Debounce (~300ms) as the shopper types
|
|
888
|
+
const suggestions = await client.getAddressSuggestions('Rothschild 1', sessionToken);
|
|
889
|
+
// [{ placeId: 'ChIJ...', description: 'Rothschild Blvd 1, Tel Aviv-Yafo' }, ...]
|
|
890
|
+
|
|
891
|
+
// On picking a suggestion — reuse the SAME sessionToken to end the session
|
|
892
|
+
const { address, inZone } = await client.getAddressDetails(suggestions[0].placeId, sessionToken);
|
|
893
|
+
// address: { line1, city, region, postalCode, country, lat, lng, formattedAddress }
|
|
894
|
+
|
|
895
|
+
await client.setShippingAddress(checkout.id, {
|
|
896
|
+
firstName: 'John',
|
|
897
|
+
lastName: 'Doe',
|
|
898
|
+
...address,
|
|
899
|
+
});
|
|
900
|
+
|
|
901
|
+
if (!inZone) {
|
|
902
|
+
// Non-blocking: "This address is outside our regular delivery zones.
|
|
903
|
+
// You can still continue — we'll confirm delivery by phone."
|
|
904
|
+
}
|
|
905
|
+
```
|
|
906
|
+
|
|
877
907
|
---
|
|
878
908
|
|
|
879
909
|
## Cart (Unified for All Users)
|
|
@@ -1573,7 +1603,7 @@ await client.addToCart(cartId, {
|
|
|
1573
1603
|
```typescript
|
|
1574
1604
|
// Works for CartItem, CheckoutLineItem, and OrderItem — same shape
|
|
1575
1605
|
const summary = Object.values(item.customizations ?? {})
|
|
1576
|
-
.map(c => `${c.label}: ${Array.isArray(c.value) ? c.value.join(', ') : c.value}`)
|
|
1606
|
+
.map((c) => `${c.label}: ${Array.isArray(c.value) ? c.value.join(', ') : c.value}`)
|
|
1577
1607
|
.join(' | ');
|
|
1578
1608
|
// e.g. "Frame color: Gold | Add-ons: Gift wrap, Engraving"
|
|
1579
1609
|
```
|
|
@@ -2262,11 +2292,11 @@ interface Checkout {
|
|
|
2262
2292
|
subtotal: string;
|
|
2263
2293
|
discountAmount: string;
|
|
2264
2294
|
shippingAmount: string;
|
|
2265
|
-
taxAmount: string;
|
|
2295
|
+
taxAmount: string; // "0" in inclusive (VAT) mode — see taxBreakdown.totalTax
|
|
2266
2296
|
taxBreakdown?: TaxBreakdown | null; // { totalTax, pricesIncludeTax, breakdown[] }
|
|
2267
2297
|
total: string;
|
|
2268
2298
|
couponCode?: string | null;
|
|
2269
|
-
notes?: string | null;
|
|
2299
|
+
notes?: string | null; // Order note from setCheckoutCustomer/setShippingAddress
|
|
2270
2300
|
items: CheckoutLineItem[];
|
|
2271
2301
|
itemCount: number;
|
|
2272
2302
|
availableShippingRates?: ShippingRate[];
|
|
@@ -2404,12 +2434,12 @@ const checkoutId = checkout.id;
|
|
|
2404
2434
|
Use this method to get ALL enabled payment providers and build dynamic UI.
|
|
2405
2435
|
|
|
2406
2436
|
**Primary vs. additive methods (Shopify-parity).** Each provider carries a
|
|
2407
|
-
`methodType`. A `CREDIT_CARD` provider is the
|
|
2437
|
+
`methodType`. A `CREDIT_CARD` provider is the _primary_ card processor — the
|
|
2408
2438
|
single method that settles the order (`defaultProvider`, `isAdditive: false`,
|
|
2409
|
-
`presentation: 'card_form'`). Everything else is
|
|
2439
|
+
`presentation: 'card_form'`). Everything else is _additive_ (`isAdditive: true`),
|
|
2410
2440
|
e.g. PayPal is a `'WALLET'` with `presentation: 'express_button'`. Render additive
|
|
2411
2441
|
methods as accelerated-checkout **express buttons above the card form** — they sit
|
|
2412
|
-
|
|
2442
|
+
_alongside_ the primary, never replace it. (Exception: a wallet-only store has no
|
|
2413
2443
|
card processor, so its wallet becomes the `defaultProvider` and stands alone.)
|
|
2414
2444
|
|
|
2415
2445
|
```typescript
|
|
@@ -2967,8 +2997,9 @@ const rewards = await client.getAvailableRewards();
|
|
|
2967
2997
|
// Redeem → spends points, returns a one-time coupon code to apply to the cart.
|
|
2968
2998
|
// `discountType` tells you how to interpret `discountValue` (currency amount
|
|
2969
2999
|
// for FIXED_DISCOUNT, 0-100 percent for PERCENT_DISCOUNT).
|
|
2970
|
-
const { couponCode, discountType, discountValue, pointsBalance } =
|
|
2971
|
-
|
|
3000
|
+
const { couponCode, discountType, discountValue, pointsBalance } = await client.redeemLoyaltyReward(
|
|
3001
|
+
rewards[0].id
|
|
3002
|
+
);
|
|
2972
3003
|
await client.applyCoupon(cartId, couponCode);
|
|
2973
3004
|
|
|
2974
3005
|
// Self-reported social share — grants the SOCIAL_SHARE bonus if configured
|
|
@@ -3545,8 +3576,8 @@ client.trackEvent({ eventType: 'pageview', path: '/products/shoes' });
|
|
|
3545
3576
|
const params = new URLSearchParams(window.location.search);
|
|
3546
3577
|
client.trackEvent({
|
|
3547
3578
|
path: window.location.pathname,
|
|
3548
|
-
utmSource:
|
|
3549
|
-
utmMedium:
|
|
3579
|
+
utmSource: params.get('utm_source') ?? undefined,
|
|
3580
|
+
utmMedium: params.get('utm_medium') ?? undefined,
|
|
3550
3581
|
utmCampaign: params.get('utm_campaign') ?? undefined,
|
|
3551
3582
|
screenWidth: window.innerWidth,
|
|
3552
3583
|
lang: navigator.language,
|
|
@@ -3577,6 +3608,94 @@ const admin = new BrainerceClient({
|
|
|
3577
3608
|
});
|
|
3578
3609
|
```
|
|
3579
3610
|
|
|
3611
|
+
### Product Management
|
|
3612
|
+
|
|
3613
|
+
```typescript
|
|
3614
|
+
import type { Product, CreateProductDto, UpdateProductDto } from 'brainerce';
|
|
3615
|
+
|
|
3616
|
+
// Create a simple product
|
|
3617
|
+
const product: Product = await client.createProduct({
|
|
3618
|
+
name: 'Classic T-Shirt',
|
|
3619
|
+
slug: 'classic-t-shirt', // Optional — auto-generated from name if omitted
|
|
3620
|
+
sku: 'TSH-001',
|
|
3621
|
+
description: 'Soft cotton tee.',
|
|
3622
|
+
basePrice: 29.99,
|
|
3623
|
+
salePrice: 24.99, // Optional
|
|
3624
|
+
costPrice: 12.0, // Optional, internal — never synced to platforms
|
|
3625
|
+
status: 'active', // 'active' | 'draft' (default: 'active')
|
|
3626
|
+
type: 'SIMPLE', // 'SIMPLE' | 'VARIABLE' (default: 'SIMPLE')
|
|
3627
|
+
categories: ['cat_id'], // Existing category IDs
|
|
3628
|
+
categoryNames: ['Apparel'], // Or assign/auto-create by name — merged with `categories`
|
|
3629
|
+
brands: ['brand_id'],
|
|
3630
|
+
tags: ['sale', 'summer'],
|
|
3631
|
+
images: [
|
|
3632
|
+
{
|
|
3633
|
+
url: 'https://cdn.example.com/tshirt.jpg',
|
|
3634
|
+
position: 0,
|
|
3635
|
+
isMain: true,
|
|
3636
|
+
alt: 'Classic T-Shirt',
|
|
3637
|
+
},
|
|
3638
|
+
],
|
|
3639
|
+
|
|
3640
|
+
// Cross-platform identifiers (Google Shopping / Facebook Catalog / TikTok).
|
|
3641
|
+
// Provide gtin when the product has one; otherwise mpn + brand.
|
|
3642
|
+
gtin: '012345678905', // EAN/UPC/ISBN — validated (GS1 mod-10 checksum)
|
|
3643
|
+
mpn: 'MFR-TSH-001', // Manufacturer Part Number — used only when gtin is absent
|
|
3644
|
+
|
|
3645
|
+
// Google Merchant Center sale_price_effective_date — bounds when `salePrice`
|
|
3646
|
+
// is actually active. Set both together, or omit both (sale always active).
|
|
3647
|
+
salePriceStartsAt: '2026-06-01T00:00:00Z',
|
|
3648
|
+
salePriceEndsAt: '2026-06-30T23:59:59Z',
|
|
3649
|
+
|
|
3650
|
+
// Shipping weight & dimensions — used for accurate shipping-cost
|
|
3651
|
+
// calculation and Google Shopping's shipping_weight/shipping_length/etc.
|
|
3652
|
+
shippingWeightValue: 0.3,
|
|
3653
|
+
shippingWeightUnit: 'kg', // 'kg' | 'lb' | 'g' | 'oz'
|
|
3654
|
+
shippingLengthValue: 30,
|
|
3655
|
+
shippingWidthValue: 20,
|
|
3656
|
+
shippingHeightValue: 2,
|
|
3657
|
+
shippingDimensionUnit: 'cm', // 'cm' | 'in' — shared by length/width/height
|
|
3658
|
+
});
|
|
3659
|
+
|
|
3660
|
+
// Update a product — every field is optional; only send what changed.
|
|
3661
|
+
// Pass `null` on gtin/mpn/salePriceStartsAt/salePriceEndsAt/shipping* to clear them.
|
|
3662
|
+
const updated: Product = await client.updateProduct('prod_123', {
|
|
3663
|
+
salePrice: null, // End the sale
|
|
3664
|
+
salePriceStartsAt: null,
|
|
3665
|
+
salePriceEndsAt: null,
|
|
3666
|
+
} satisfies UpdateProductDto);
|
|
3667
|
+
|
|
3668
|
+
// Delete a product (optionally also delete from synced platforms)
|
|
3669
|
+
await client.deleteProduct('prod_123', { platforms: ['SHOPIFY'] });
|
|
3670
|
+
|
|
3671
|
+
// VARIABLE products: create the product with type: 'VARIABLE', then add variants
|
|
3672
|
+
const variableProduct = await client.createProduct({
|
|
3673
|
+
name: 'Hoodie',
|
|
3674
|
+
basePrice: 0,
|
|
3675
|
+
type: 'VARIABLE',
|
|
3676
|
+
});
|
|
3677
|
+
await client.bulkSaveVariants(variableProduct.id, {
|
|
3678
|
+
variants: [
|
|
3679
|
+
{
|
|
3680
|
+
sku: 'HOOD-S-BLK',
|
|
3681
|
+
attributes: { Size: 'S', Color: 'Black' },
|
|
3682
|
+
price: 49.99,
|
|
3683
|
+
stock: 20,
|
|
3684
|
+
isEnabled: true,
|
|
3685
|
+
},
|
|
3686
|
+
{
|
|
3687
|
+
sku: 'HOOD-M-BLK',
|
|
3688
|
+
attributes: { Size: 'M', Color: 'Black' },
|
|
3689
|
+
price: 49.99,
|
|
3690
|
+
stock: 15,
|
|
3691
|
+
isEnabled: true,
|
|
3692
|
+
},
|
|
3693
|
+
],
|
|
3694
|
+
});
|
|
3695
|
+
```
|
|
3696
|
+
|
|
3697
|
+
**GTIN vs MPN:** these are two different identifiers, not interchangeable — GTIN (EAN/UPC/ISBN) is a universal barcode; MPN is manufacturer-specific and only meaningful paired with a brand. Provide GTIN when the product has one; otherwise brand + MPN. A product typically needs one or the other, not both.
|
|
3698
|
+
|
|
3580
3699
|
### Taxonomy Management
|
|
3581
3700
|
|
|
3582
3701
|
```typescript
|
|
@@ -3698,6 +3817,37 @@ const euZone = await client.createShippingZone({
|
|
|
3698
3817
|
regionIds: ['reg_eu'],
|
|
3699
3818
|
});
|
|
3700
3819
|
|
|
3820
|
+
// Polygon zone ("draw on map") — a hand-drawn delivery area. GeoJSON
|
|
3821
|
+
// Polygon/MultiPolygon, [lng, lat] ring coordinates. Independent of
|
|
3822
|
+
// `countries`/`regions`/`postalCodes`: a zone matches if the address
|
|
3823
|
+
// satisfies *either* coverage, so both may be set on the same zone (this
|
|
3824
|
+
// example omits `countries` since the polygon is its only coverage).
|
|
3825
|
+
const polygonZone = await client.createShippingZone({
|
|
3826
|
+
name: 'Tel Aviv Metro',
|
|
3827
|
+
countries: [],
|
|
3828
|
+
geometry: {
|
|
3829
|
+
type: 'Polygon',
|
|
3830
|
+
coordinates: [
|
|
3831
|
+
[
|
|
3832
|
+
[34.75, 32.05],
|
|
3833
|
+
[34.75, 32.1],
|
|
3834
|
+
[34.82, 32.1],
|
|
3835
|
+
[34.82, 32.05],
|
|
3836
|
+
[34.75, 32.05],
|
|
3837
|
+
],
|
|
3838
|
+
],
|
|
3839
|
+
},
|
|
3840
|
+
});
|
|
3841
|
+
|
|
3842
|
+
// Restrict a zone to specific sales channels — `SalesChannel.id` or the
|
|
3843
|
+
// public `vc_*` connectionId. Empty/omitted = every channel; a non-empty
|
|
3844
|
+
// list hides the zone unless the checkout came from one of them.
|
|
3845
|
+
const mobileOnlyZone = await client.createShippingZone({
|
|
3846
|
+
name: 'US Domestic (mobile app only)',
|
|
3847
|
+
countries: ['US'],
|
|
3848
|
+
salesChannelIds: ['vc_abc123'],
|
|
3849
|
+
});
|
|
3850
|
+
|
|
3701
3851
|
// Shipping Rates
|
|
3702
3852
|
const rates = await client.getZoneShippingRates('zone_id');
|
|
3703
3853
|
await client.createZoneShippingRate('zone_id', {
|
|
@@ -3720,9 +3870,9 @@ const label = await admin.createShippingLabel(orderId, {
|
|
|
3720
3870
|
shippoRateObjectId: 'rate_8f123456789abcdef', // Shippo rate.object_id from checkout rates
|
|
3721
3871
|
});
|
|
3722
3872
|
|
|
3723
|
-
console.log(label.labelUrl);
|
|
3873
|
+
console.log(label.labelUrl); // PDF label URL for printing
|
|
3724
3874
|
console.log(label.trackingNumber); // Auto-populated on the order
|
|
3725
|
-
console.log(label.carrier);
|
|
3875
|
+
console.log(label.carrier); // e.g. 'USPS', 'UPS', 'FedEx'
|
|
3726
3876
|
```
|
|
3727
3877
|
|
|
3728
3878
|
The `trackingNumber` is stored on the `Order` automatically — customers see it in their
|
|
@@ -4047,6 +4197,43 @@ const preview = await client.previewEmailTemplate('template_id', {
|
|
|
4047
4197
|
});
|
|
4048
4198
|
```
|
|
4049
4199
|
|
|
4200
|
+
### Storefront Bot Settings
|
|
4201
|
+
|
|
4202
|
+
Requires an API key with the `bot-settings:read` / `bot-settings:write` scopes.
|
|
4203
|
+
|
|
4204
|
+
```typescript
|
|
4205
|
+
// Every connection on the store + its current (or default) settings
|
|
4206
|
+
const { connections, settings } = await client.getBotSettings();
|
|
4207
|
+
|
|
4208
|
+
// PATCH semantics — only the fields you pass are changed
|
|
4209
|
+
await client.updateBotSettings({
|
|
4210
|
+
salesChannelId: connections[0].salesChannelId,
|
|
4211
|
+
enabled: true,
|
|
4212
|
+
displayName: 'Maya',
|
|
4213
|
+
personaJson: {
|
|
4214
|
+
greeting: 'Hi! Looking for something specific?',
|
|
4215
|
+
tone: 'friendly', // 'friendly' | 'formal' | 'playful' | 'concise'
|
|
4216
|
+
starterQuestions: ['What sizes do you carry?', "What's your return policy?"],
|
|
4217
|
+
avoidTopics: 'Do not discuss competitor pricing or make medical claims.',
|
|
4218
|
+
customInstructions: 'Always mention free shipping over $75.',
|
|
4219
|
+
capabilities: { productQa: true, recommendations: true, returns: false },
|
|
4220
|
+
},
|
|
4221
|
+
});
|
|
4222
|
+
```
|
|
4223
|
+
|
|
4224
|
+
### Storefront Bot Conversations
|
|
4225
|
+
|
|
4226
|
+
Studio inbox transcripts + on-demand summarization. Requires the `bot-conversations:read` / `bot-conversations:write` scopes.
|
|
4227
|
+
|
|
4228
|
+
```typescript
|
|
4229
|
+
const { data: conversations } = await client.listBotConversations({ limit: 20 });
|
|
4230
|
+
const transcript = await client.getBotConversation(conversations[0].id);
|
|
4231
|
+
|
|
4232
|
+
// Persists a summary on the conversation; short threads (10 or fewer messages)
|
|
4233
|
+
// are a no-op — { summarized: false, summary: null } — no credits charged.
|
|
4234
|
+
const { summarized, summary } = await client.summarizeBotConversation(conversations[0].id);
|
|
4235
|
+
```
|
|
4236
|
+
|
|
4050
4237
|
### Sync Conflict Resolution
|
|
4051
4238
|
|
|
4052
4239
|
```typescript
|
|
@@ -5129,7 +5316,7 @@ const forms = await brainerce.contactForms.list();
|
|
|
5129
5316
|
|
|
5130
5317
|
## Storefront Bot (AI chat widget)
|
|
5131
5318
|
|
|
5132
|
-
Add the store's AI shopping assistant with one line.
|
|
5319
|
+
Add the store's AI shopping assistant with one line. Configuration (name, avatar, colors, greeting, starter questions, guardrails) is normally set in the merchant dashboard — the widget renders nothing until the bot is switched Live there. Those same settings are also readable/writable via `client.getBotSettings()` / `client.updateBotSettings()`, and conversation transcripts + summarization via `client.listBotConversations()` / `client.summarizeBotConversation()` — see [Storefront Bot Settings](#storefront-bot-settings) and [Storefront Bot Conversations](#storefront-bot-conversations) in the Admin API Reference.
|
|
5133
5320
|
|
|
5134
5321
|
```html
|
|
5135
5322
|
<!-- zero-code embed: keep the tag exactly this bare (no integrity/crossorigin) -->
|