Skip to content

Instantly share code, notes, and snippets.

@shangyilim
Last active June 28, 2025 09:16
Show Gist options
  • Save shangyilim/3521d21324f226e42be7dc9f8b03b31c to your computer and use it in GitHub Desktop.
Save shangyilim/3521d21324f226e42be7dc9f8b03b31c to your computer and use it in GitHub Desktop.
/**
* Retrieves or creates a Firestore document for the user and manages their session ID.
* @param from - The 'From' phone number from the Twilio request (e.g., 'whatsapp:+1234567890').
* @returns An object containing the session ID, whether a session existed, and the customer data.
*/
async function getUserSessionInfo(from: string) {
// Get the Firestore database instance using the Firebase Admin SDK app.
const db = getFirestore(getFirebaseAdminApp());
// Fetch the customer document.
const customerRef = db.collection('customers').doc(from);
const customerDoc = await customerRef.get();
const existingCustomer = customerDoc.data();
// Check if a session ID already exists in the customer data.
const existingSessionIdExists = !!existingCustomer?.sessionId;
// Generate a new UUID for a potential new session.
const newSessionId = crypto.randomUUID();
// Prepare the updated customer data.
const updatedCustomer = {
sessionId: existingCustomer?.sessionId ?? newSessionId,
phoneNumber: existingCustomer?.phoneNumber ?? from.replace('whatsapp:', ""),
name: existingCustomer?.name ??'',
}
// Update the updated customer data back into the Firestore document.
await customerRef.set(updatedCustomer, {merge: true});
return {
sessionId: updatedCustomer.sessionId,
exist: existingSessionIdExists,
customer: updatedCustomer,
}
}
/**
* Gets or creates a Genkit session for the given user.
* @param from - The user's identifier (Twilio 'From' number).
* @returns An object containing the Genkit session and a function to clear the session.
*/
async function getSession(from: string) {
// Get business information, which might be needed by some of the tools.
const businessInfo = await getBusinessInfo();
// Get user session information, including their existing session ID if any,
// and customer details.
const { sessionId, exist, customer } = await getUserSessionInfo(from);
// Initialize a session store (e.g., using Firebase Realtime Database).
const sessionStore = new RtdbSessionStore();
let session;
// Check if a session with the retrieved sessionId already exists.
if (exist) {
// If it exists, load the existing session from the store.
session = await ai.loadSession(sessionId, {
store: sessionStore,
});
}
else {
console.log('session not found, creating new');
// Create a new session with the generated sessionId and store.
// Provide initial state
session = ai.createSession<AgentSessionState>({
sessionId: sessionId,
store: sessionStore,
initialState: {
userId: from,
phoneNumber: customer.phoneNumber,
name: customer.name,
businessInfo,
}
})
}
return {
session,
// Provide a utility function to clear the session from the store.
clearSession: () =>
sessionStore.delete(sessionId)
};
}
/**
* Begin chatting with session
*/
async function onMessaageReceived(from, message){
const { session, clearSession } = await getSession(from);
// Load or create a session for the user.
const chat = session.chat(routingAgent);
const response = await chat.send(userMessage);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment