npm.io
1.0.18 • Published 19h ago

@paramms/chat-widget

Licence
MIT
Version
1.0.18
Deps
1
Size
496 kB
Vulns
0
Weekly
2.4K

@paramms/chat-widget

Real-time embeddable chat widget for the Relay platform. Drop into any website with a single script tag — no build step required.

Install

npm install @paramms/chat-widget

Quick start — CDN (no npm, no build)

<div id="chat"></div>
<script type="module">
  import { mount } from 'https://relay.paramms.com/index.js'
  mount({
    el:        document.getElementById('chat'),
    url:       'wss://api.paramms.com/ws',
    profileId: 'YOUR_PROFILE_ID',
  })
</script>

React / Next.js

General support chat (ChatWidget)
'use client'
import { ChatWidget } from '@paramms/chat-widget/react'

export default function SupportPage({ session }) {
  return (
    <ChatWidget
      url={process.env.NEXT_PUBLIC_RELAY_WS_URL}
      profileId={process.env.NEXT_PUBLIC_RELAY_PROFILE_ID}
      userId={session?.user.id}        // optional  anonymous if omitted
      userName={session?.user.name}    // optional  shown to agents
      userEmail={session?.user.email}  // optional  shown to agents
    />
  )
}
Marketplace / multi-listing chat (MarketplaceChat)

Two modes — one component:

On a listing page (with listingId) → opens that item's chat directly. No list. Buyer is already looking at the item.

'use client'
import { MarketplaceChat } from '@paramms/chat-widget/react'

// Listing detail page — floating bubble in bottom-right corner
export default function ListingPage({ car, session }) {
  return (
    <>
      <YourPageContent />

      <MarketplaceChat
        url={process.env.NEXT_PUBLIC_RELAY_WS_URL}
        profileId={process.env.NEXT_PUBLIC_RELAY_PROFILE_ID}
        listingId={car.id}
        listingTitle={car.title}          // shown in chat header
        listingPrice={car.price}          // shown as "$12,500" tag
        listingMeta="214,500 km · LPG"   // one line of detail
        listingStatus="Available"
        userId={session?.user.id}         // optional  anonymous if omitted
        userName={session?.user.name}     // optional
        launcher                          // floating bubble button
        position="bottom-right"
      />
    </>
  )
}

On a /messages page (without listingId) → shows the buyer's full thread list (WhatsApp-style). No conversation opens until they tap one.

// Dedicated inbox page — e.g. /messages
export default function MessagesPage({ session }) {
  return (
    <div style={{ height: '600px' }}>
      <MarketplaceChat
        url={process.env.NEXT_PUBLIC_RELAY_WS_URL}
        profileId={process.env.NEXT_PUBLIC_RELAY_PROFILE_ID}
        userId={session?.user.id}
        userName={session?.user.name}
        // no listingId = inbox mode, shows all threads
      />
    </div>
  )
}
Old section below (kept for reference)
'use client'
import { ChatWidget } from '@paramms/chat-widget/react'

export default function SupportChat() {
  return (
    <ChatWidget
      url="wss://api.paramms.com/ws"
      profileId="YOUR_PROFILE_ID"
    />
  )
}

Identified users (no separate login needed)

Pass your own user's ID as the token and their details via user. Anonymous users work without any configuration.

<ChatWidget
  url="wss://api.paramms.com/ws"
  profileId="YOUR_PROFILE_ID"
  token={currentUser.id}          // your own stable user ID  ties history across devices
  user={{
    name:   currentUser.name,     // shown to agents instead of opaque ID
    email:  currentUser.email,    // agents can follow up even after disconnect
    avatar: currentUser.avatarUrl,
    meta: {
      plan:      currentUser.plan,
      accountId: currentUser.id,
    },
  }}
/>

Cryptographically verified identity (Tier 4)

For marketplaces and financial services — the guest's identity is verified against your ECDSA key so it cannot be spoofed.

// 1. Generate a key pair (once, server-side)
//    openssl ecparam -genkey -name prime256v1 -noout | openssl pkcs8 -topk8 -nocrypt -out private.pem
//    openssl ec -in private.pem -pubout | base64 -w0  → paste in Dashboard → Domain → Guest identity linking

// 2. Sign a token per user (your backend)
import { createSign } from 'node:crypto'
const hdr = Buffer.from(JSON.stringify({ alg: 'ES256', typ: 'JWT' })).toString('base64url')
const pay = Buffer.from(JSON.stringify({ sub: userId, iat: Math.floor(Date.now() / 1000), exp: Math.floor(Date.now() / 1000) + 3600 })).toString('base64url')
const sig = createSign('SHA256').update(`${hdr}.${pay}`).sign(privateKey, 'base64url')
const signedToken = `${hdr}.${pay}.${sig}`

// 3. Pass to widget — server verifies the signature automatically
<ChatWidget url="..." profileId="..." token={signedToken} />

Marketplace / multi-item (one thread per listing)

<ChatWidget
  url="wss://api.paramms.com/ws"
  profileId="YOUR_PROFILE_ID"
  subjectId={`car_${listing.id}`}   // one conversation per item
  showChatList={true}                // guest can switch between their threads
/>

Launcher (floating button)

<ChatWidget
  url="wss://api.paramms.com/ws"
  profileId="YOUR_PROFILE_ID"
  launcher={true}
  position="bottom-right"
  accent="#4F63F5"
/>

Internationalisation

<ChatWidget
  url="wss://api.paramms.com/ws"
  profileId="YOUR_PROFILE_ID"
  i18n={{
    placeholder: 'Écrivez un message…',
    send:        'Envoyer',
    offline:     'Nous sommes hors ligne pour l\'instant',
    poweredBy:   '',   // empty string hides the footer
  }}
/>

RTL is detected automatically for Arabic, Hebrew, Persian and Urdu browsers.

All options

Option Type Default Description
el HTMLElement required Mount target
url string required WebSocket URL (wss://...)
profileId string required Domain profile ID
token string auto-generated Guest identity token — pass your user's stable ID to tie history across devices
user UserInfo Name, email, avatar, custom metadata — shown to agents
subjectId string Item ID for marketplace mode
showChatList boolean false Show conversation switcher in header
accent string #f5713c Brand colour (hex)
launcher boolean false Render as floating button
position 'bottom-right' | 'bottom-left' 'bottom-right' Launcher position
translateLang string Auto-translate incoming messages (ISO language code)
quickReplies string[] Pre-set reply chips shown above input
i18n I18nStrings English UI string overrides

Development

npm install
npm run dev          # Vite preview at http://localhost:5174/
npm run build        # tsc → dist/
npm run build:bundle # Vite → standalone CDN bundle
npm test             # 75 tests via vitest
npm run typecheck

Keywords