62 lines
1.6 KiB
TypeScript
Raw Normal View History

feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 11:42:58 -05:00
import { UserSettings } from 'models/settings'
import { QueryParamKeys } from 'models/shell'
export enum PostMessageEventName {
CONFIG = 'config',
CONFIG_REQUESTED = 'configRequested',
}
export enum ChatEmbedAttributes {
COLOR_MODE = 'color-mode',
PLAY_MESSAGE_SOUND = 'play-message-sound',
ROOM_NAME = 'room',
ROOT_URL = 'root-url',
USER_ID = 'user-id',
USER_NAME = 'user-name',
}
export interface PostMessageEvent extends MessageEvent {
data: {
name: PostMessageEventName
payload: Record<string, any>
}
}
export interface ConfigMessageEvent extends PostMessageEvent {
data: {
name: PostMessageEventName.CONFIG
payload: Partial<UserSettings>
}
}
export const isPostMessageEvent = (
event: MessageEvent
): event is PostMessageEvent => {
const { data } = event
if (typeof data !== 'object' || data === null) return false
if (!('name' in data && typeof data.name === 'string')) return false
if (!('payload' in data && typeof data.payload === 'object')) return false
return true
}
export const isConfigMessageEvent = (
event: MessageEvent
): event is ConfigMessageEvent => {
const queryParams = new URLSearchParams(window.location.search)
const parentDomain = queryParams.get(QueryParamKeys.PARENT_DOMAIN)
if (parentDomain === null) return false
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 11:42:58 -05:00
const { origin: parentFrameOrigin } = new URL(
decodeURIComponent(parentDomain)
feat(sdk): Implement Chitchatter SDK (#183) * feat(sdk): render iframe in chat-room component * fix(ci): install optional dependencies * feat(sdk): allow subset of attributes * feat(sdk): accept root-domain attribute * feat(sdk): accept custom room name or use sane default * feat(sdk): set allowed features * feat(sdk): add sdk instructions to embed code dialog * fix(sdk): use dynamic rootUrl * fix(sdk): use static defaultRoot * feat(sdk): send config from SDK to chat * fix(sdk): expire poller * fix(sdk): pass parent domain to iframe via query param * refactor(sdk): type message event data * feat(sdk): send user id to chat frame * feat(sdk): handle some attribute updates * chore(package): add build:sdk:watch script * refactor(sdk): move more code to updateIframeAttributes * feat(sdk): support changing rooms * feat(sdk): support more user settings * docs(sdk): add SDK section to README * feat(sdk): render root-url in embed code if necessary * refactor(sdk): use map for chat room attributes * fix(sdk): unbind event listener when chat-room is disconnected * fix(sdk): properly tear down receipt listener * fix(sdk): send config when frame reloads * feat(sdk): listen for config updates * feat(sdk): request config from sdk instead of sending it repeatedly * refactor(sdk): use type guard for config message * fix(sdk): use settings from SDK when there is no preexisting persisted data * fix(sdk): observe all iframe attributes * refactor(sdk): simplify bootup logic * feat(sdk): improve embed code display
2023-10-28 11:42:58 -05:00
)
if (event.origin !== parentFrameOrigin) return false
if (!isPostMessageEvent(event)) return false
if (event.data.name !== PostMessageEventName.CONFIG) return false
return true
}