Skip to main content

Overview

The Social Feed API provides social networking features including following customers and stores, activity feeds, product interactions, and social discovery. The feed respects privacy settings - private accounts only show content to followers. Location: convex/customers/feed.ts

Privacy Controls

The feed system respects customer privacy settings:
  • Private accounts (default): Content only visible to followers
  • Public accounts: Content visible to all users
  • Users can always see their own content regardless of privacy settings

Follow Customer

followerCustomerId
Id<'customers'>
required
Customer doing the following
targetCustomerId
Id<'customers'>
required
Customer to follow
await convex.mutation(api.customers.feed.followCustomer, {
  followerCustomerId: "c123456789",
  targetCustomerId: "c987654321"
});

Follow Store

followerCustomerId
Id<'customers'>
required
Customer following the store
storeId
Id<'stores'>
required
Store to follow
await convex.mutation(api.customers.feed.followStore, {
  followerCustomerId: "c123456789",
  storeId: "j123456789"
});

Like Product

productId
Id<'products'>
required
Product to like
customerId
Id<'customers'>
required
Customer ID
await convex.mutation(api.customers.feed.likeProduct, {
  productId: "p123456789",
  customerId: "c123456789"
});

Get Feed

Retrieve personalized product-focused activity feed for a customer. The feed respects privacy settings and only shows content the user is authorized to see. Uses custom cursor-based pagination where the cursor is a timestamp string.
customerId
Id<'customers'>
Customer ID (defaults to authenticated user if omitted)
paginationOpts
PaginationOptions
required
Pagination options with numItems (1-100) and cursor (timestamp string or null for first page)
const feed = await convex.query(api.customers.feed.getFeed, {
  paginationOpts: { numItems: 20, cursor: null }
});

// Load next page
const nextPage = await convex.query(api.customers.feed.getFeed, {
  paginationOpts: { numItems: 20, cursor: feed.continueCursor }
});

Feed Content Types

The feed includes these activity types (filtered by privacy):
  1. Price Updates: From followed stores and on liked products
  2. Product Likes: From followed customers (only if you also like the product)
  3. Product Shares: From followed customers
  4. Direct Shares: Shared directly to you (always visible regardless of privacy)
  5. New Products: From followed stores
{
  "page": [
    {
      "activityId": "pa123456789",
      "activityType": "product_liked",
      "activityTime": 1640995800000,
      "product": {
        "_id": "p123456789",
        "name": "Organic Apples",
        "price": 12.99,
        "primaryImageUrl": "https://storage.convex.dev/apples.jpg",
        "isLikedByCustomer": true,
        "store": {
          "_id": "j123456789",
          "name": "Fresh Market",
          "logoUrl": "https://storage.convex.dev/logo.jpg"
        }
      },
      "actorCustomer": {
        "_id": "c987654321",
        "name": "Jane Smith",
        "avatarUrl": "https://storage.convex.dev/jane.jpg"
      },
      "priceData": null,
      "shareData": null
    },
    {
      "activityId": "pa987654321",
      "activityType": "price_update",
      "activityTime": 1640995600000,
      "product": {
        "_id": "p555666777",
        "name": "Wireless Headphones",
        "price": 79.99,
        "primaryImageUrl": "https://storage.convex.dev/headphones.jpg",
        "isLikedByCustomer": false,
        "store": {
          "_id": "j987654321",
          "name": "Tech Store",
          "logoUrl": "https://storage.convex.dev/tech-logo.jpg"
        }
      },
      "actorCustomer": null,
      "priceData": {
        "oldPrice": 99.99,
        "newPrice": 79.99,
        "discountPercent": 20
      },
      "shareData": null
    }
  ],
  "isDone": false,
  "continueCursor": "1640995600000"
}

Get Feed Debug Info

Debug helper to inspect feed data sources for a customer. Returns counts of followed customers, stores, and recent activity.
customerId
Id<'customers'>
Customer ID (defaults to authenticated user if omitted)
const debugInfo = await convex.query(api.customers.feed.getFeedDebugInfo, {
  customerId: "c123456789"
});
{
  "customerId": "c123456789",
  "followedCustomersCount": 15,
  "followedStoresCount": 8,
  "totalShares": 10,
  "totalPromotions": 10,
  "recentSharesCount": 10,
  "recentPromotionsCount": 10
}

Create Test Product Activity

Helper mutation to create test product activity events for development and testing purposes.
productId
Id<'products'>
required
Product ID for the activity event
activityType
'price_update' | 'product_liked' | 'product_shared' | 'new_product'
required
Type of activity to create
customerId
Id<'customers'>
Optional actor customer ID
oldPrice
number
Previous price (for price_update events)
newPrice
number
New price (for price_update events)
const activityId = await convex.mutation(api.customers.feed.createTestProductActivity, {
  productId: "p123456789",
  activityType: "price_update",
  oldPrice: 99.99,
  newPrice: 79.99
});
"pa123456789"

Test Feed

Test function to validate feed functionality. Runs a feed query and returns diagnostic information.
numItems
number
Number of items to request (default: 10)
const testResult = await convex.query(api.customers.feed.testFeed, {
  numItems: 5
});
{
  "success": true,
  "message": "Product feed query successful",
  "feedLength": 5,
  "hasNextPage": true,
  "activityTypes": ["price_update", "product_liked", "product_shared"]
}
Social feed includes activity from followed customers and stores with real-time updates. Privacy-restricted content is automatically filtered out.