Skip to content

Commit

Permalink
chore: switch ayesha to ws
Browse files Browse the repository at this point in the history
  • Loading branch information
Olutunde22 committed Jan 17, 2024
1 parent 8932c59 commit e3a57fb
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 48 deletions.
File renamed without changes
2 changes: 1 addition & 1 deletion src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useAtom } from 'jotai';
import { useEffect } from 'react';
import { Radio } from 'react-loader-spinner';
import avatar from '../assets/avatar.png';
import avatar from '/avatar.png';
import cancelIcon from '../assets/cancel.svg';
import wifiIcon from '../assets/wifi.svg';
import { connectionAtom, socketAtom } from '../state/atoms';
Expand Down
10 changes: 10 additions & 0 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,13 @@ export const capitalize = (str: string): string => {
export const classNames = (...classes: string[]): string => {
return classes.filter(Boolean).join(' ');
};

export const objectOrString = (str: string) => {
try {
const parsedObject = JSON.parse(str);
return typeof parsedObject === 'object' && parsedObject !== null && parsedObject;
} catch (error) {
return str;
}
}

23 changes: 13 additions & 10 deletions src/helpers/processEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,24 @@ const processEvent = (event: MessageEvent<unknown>) => {

const eventData: ChatEvent = JSON.parse(event.data);

const { action, orgId, sessionId, agentName, logoUrl, data, form, sessionTtl } = eventData;
const { data, metadata } = eventData;

const { message, role, timestamp } = data;
const { message, timestamp } = data;

const { organization, session, botName, avatarUrl } = metadata

return {
action,
orgId,
sessionId,
agentName,
logoUrl,
orgId: organization?.id,
sessionId: session?.id,
agentName: botName,
logoUrl: avatarUrl,
message,
role,
role: 'assistant',
cues: data?.cues,
timestamp,
form,
sessionTtl,
form: data?.form ?? null,
sessionTtl: session.ttl,
metadata,
};
};

Expand Down
53 changes: 32 additions & 21 deletions src/state/atoms.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Getter, Setter, atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import processEvent from '../helpers/processEvent';
import { Command, MessageType, Messenger } from '../types';
import { ChatEventMetaData, Command, MessageType, Messenger, QueryData } from '../types';
// import { Socket, io } from 'socket.io-client';
import { objectOrString } from '../helpers';

type Connection = {
orgId?: string;
Expand All @@ -11,6 +13,7 @@ type Connection = {
logoUrl?: string;
connected?: boolean;
timedOut?: boolean;
cues?: string[];
reconnect?: () => void;
disconnect?: () => void;
messenger?: Messenger;
Expand All @@ -22,50 +25,51 @@ export const accessKeyAtom = atomWithStorage<string>('acc_key', '');
export const connectionAtom = atomWithStorage<Connection>('connection', {});
export const formAtom = atomWithStorage<string>('form', '');
export const socketAtom = atom<WebSocket | null>(null);
const metaDataAtom = atomWithStorage<ChatEventMetaData | null>('metadata', null)


export const createSocketAtom = atom(null, (get: Getter, set: Setter) => {
let socket = get(socketAtom);
const searchParams = new URLSearchParams(document.location.search);
set(accessKeyAtom, searchParams.get('token') || '');
const accessKey = get(accessKeyAtom);

// TODO Ayesha accessKey
const AYESHA_ACCESS_KEY =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjoiVTJGc2RHVmtYMTlHcTV1SFJhZm9SSVRkbWFhZEI3bkt1Mkt6c0ZTaS9VaUdBbzh5UkhMOVFDeitKUVYzMEw3Z3NWbzRoV2x1SWxCMkJvS2NRcFhaTXE5c3ZKZG5ONkpybUtjZEJNemRTNW5ZejJ6cFNJYktnaktZOTJ3NVhlKzQiLCJpYXQiOjE2OTkxNzcyODUsImF1ZCI6Ik5pZ2NvbXNhdCBjdXN0b21lcnMiLCJpc3MiOiJWYXVsdCBIaWxsIn0.h21RQqHCzIkPUH56vW3ZOkRao8qQlKnpPw2xWcLXWww';
const ACCESS_KEY = import.meta.env.VITE_ACCESS_KEY;

const setup = () => {
// console.log('connecting...');
set(connectionAtom, {});
socket = new WebSocket(
`${import.meta.env.VITE_WS_CONN_URL}?acc_key=${accessKey ? accessKey : AYESHA_ACCESS_KEY}`,
`${import.meta.env.VITE_WS_CONN_URL}?access-key=${accessKey ? accessKey : ACCESS_KEY}`,
);
set(socketAtom, socket);

socket.onopen = () => {
// console.log('connected');
set(messageAtom, []);
set(connectionAtom, { connected: true, reconnect, disconnect, messenger });
};
}

socket.onclose = () => {
// console.log('disconnected');
set(connectionAtom, (prev) => ({ ...prev, connected: false, timedOut: true }));

const response: MessageType = {
timestamp: new Date().toISOString(),
timestamp: new Date().getMilliseconds(),
role: 'assistant',
message:
"As you're no longer asking questions, I'll go ahead and close the session. Feel free to reach out later if you have more inquiries or need assistance. Thank you for using our service.",
cues: [],
};

set(messageAtom, (prev) => [...prev, response]);
};
}

socket.onmessage = (event) => {
const data = processEvent(event);

if (data) {
const { message, orgId, sessionId, agentName, logoUrl, role, timestamp, form, sessionTtl } =
const { message, orgId, sessionId, agentName, logoUrl, role, timestamp, form, sessionTtl, metadata, cues } =
data;

if (!message) {
Expand All @@ -77,26 +81,32 @@ export const createSocketAtom = atom(null, (get: Getter, set: Setter) => {
set(formAtom, JSON.stringify(form));
}

set(connectionAtom, (prev) => ({ ...prev, orgId, agentName, logoUrl, sessionTtl }));
set(connectionAtom, (prev) => ({ ...prev, orgId, agentName, logoUrl, sessionTtl, cues }));

const response: MessageType = {
orgId,
sessionId,
timestamp,
role,
message,
cues
};

set(metaDataAtom, metadata)
set(messageAtom, (prev) => [...prev, response]);
}
};
}

const messenger = {
call: (command: Command) => {
const { orgId, totalDislikes, agentName, adhoc } = get(connectionAtom);
const metaData = get(metaDataAtom);

if (!metaData) {
return socket?.close()
}

const message: MessageType = {
timestamp: new Date().toISOString(),
timestamp: new Date().getMilliseconds(),
role: 'user',
message: command.message,
};
Expand All @@ -106,13 +116,9 @@ export const createSocketAtom = atom(null, (get: Getter, set: Setter) => {
typing: true,
};

const query = {
action: command.action,
orgId,
agentName,
totalDislikes,
adhoc: command?.adhoc || adhoc,
data: { message: command?.message },
const query: QueryData = {
data: { message: command?.message ? objectOrString(command?.message) : undefined },
metadata: metaData
};

if (!command.ghost) {
Expand All @@ -123,7 +129,12 @@ export const createSocketAtom = atom(null, (get: Getter, set: Setter) => {
set(messageAtom, (prev) => [...prev, typing]);
}

socket?.send(JSON.stringify(query));
socket?.send(
JSON.stringify({
event: 'message',
data: query,
}),
);
},
};
};
Expand Down
44 changes: 28 additions & 16 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
type EventData = {
message: string;
role: string;
timestamp: string;
};

export type Field = {
head: string | null;
element: string;
Expand All @@ -28,26 +22,39 @@ export type Field = {
next?: string | null;
}

export type Form = { type: string; fields: Field[] };
export type Form = { title: string; fields: Field[] };

export type ChatEvent = {
action: string;
orgId: string;
sessionId: string;
agentName: string;
logoUrl: string;
form?: Form;
sessionTtl?: number;
data: EventData;
metadata: ChatEventMetaData
data: ChatEventData
};

export type ChatEventMetaData = {
mode: string;
accessKey: string;
botName?: string;
avatarUrl?: string;
session: { id: string; ttl: number };
organization?: { id: string; name: string };
}

export type ChatEventData = {
cues?: string[];
message: string;
form?: Form;
timestamp?: number;
status?: string;
error?: string;
}

export type MessageType = {
orgId?: string;
sessionId?: string;
timestamp?: string;
timestamp?: number;
role: string;
message?: string;
typing?: boolean;
cues?: string[]
};

export type Command = {
Expand All @@ -57,6 +64,11 @@ export type Command = {
ghost?: boolean;
};

export type QueryData = {
data: { message?: string };
metadata: ChatEventMetaData
}

export type Messenger = {
call: (command: Command) => void;
};

0 comments on commit e3a57fb

Please sign in to comment.