Copy const axios = require('axios');
const config = {
orgId: process.env.LEXAMICA_ORG_ID,
publicKey: process.env.LEXAMICA_PUBLIC_KEY,
privateKey: process.env.LEXAMICA_PRIVATE_KEY,
invitationMappingId: process.env.LEXAMICA_INVITATION_MAPPING_ID,
updateMappingId: process.env.LEXAMICA_UPDATE_MAPPING_ID,
baseUrl: 'https://integration.lexamica.com'
};
// ============================================
// POLLING SERVICE
// ============================================
class HandlerPoller {
constructor() {
this.lastPollTime = null;
}
async poll() {
const now = new Date();
const from = this.lastPollTime || new Date(now.getTime() - 24 * 60 * 60 * 1000);
console.log(`Polling from ${from.toISOString()}`);
try {
// Poll for new invitations
const invitations = await this.fetchEvents('Case Invitation Sent', from, now);
if (invitations.length > 0) {
console.log(`Found ${invitations.length} new invitation(s)`);
await this.processInvitations(invitations);
}
// Poll for incoming updates
const updates = await this.fetchEvents('Case Update Made', from, now);
if (updates.length > 0) {
console.log(`Found ${updates.length} new update(s)`);
await this.processUpdates(updates);
}
this.lastPollTime = now;
} catch (error) {
console.error('Poll failed:', error.message);
}
}
async fetchEvents(eventType, from, to) {
const params = new URLSearchParams({
event: eventType,
from: from.toISOString(),
to: to.toISOString(),
limit: '100'
});
const response = await axios.get(
`${config.baseUrl}/organization/${config.orgId}/stored-events?${params}`,
{ headers: { Authorization: `Bearer ${config.privateKey}` } }
);
return response.data.events || [];
}
async processInvitations(events) {
for (const event of events) {
const payload = event.payload;
// Check if we've already processed this invitation
const exists = await db.pendingCases.exists(payload.invitation_id);
if (exists) continue;
// Store the new invitation
await db.pendingCases.create({
invitationId: payload.invitation_id,
caseId: payload.case_id,
originatorFirmId: payload.originator_firm_id,
clientName: `${payload.client_first_name} ${payload.client_last_name}`,
practiceArea: payload.practice_area,
description: payload.description,
expiresAt: payload.expires_at,
status: 'pending',
receivedAt: new Date()
});
// Alert intake team
await this.notifyIntake(payload);
}
}
async processUpdates(events) {
for (const event of events) {
const payload = event.payload;
await db.caseUpdates.create({
caseId: payload.case_id,
title: payload.title,
content: payload.content,
source: 'originator',
receivedAt: new Date()
});
}
}
async notifyIntake(invitation) {
console.log(`New invitation: ${invitation.invitation_id}`);
// Send email/Slack notification
}
}
// ============================================
// API CLIENT
// ============================================
class LexamicaClient {
async acceptInvitation(invitationId) {
const response = await axios.post(
`${config.baseUrl}/organization/${config.orgId}/inbound-webhooks/case-invitation/${config.invitationMappingId}/accept`,
{ invitation_id: invitationId },
{ params: { Key: config.publicKey } }
);
return response.data;
}
async declineInvitation(invitationId, reason) {
const response = await axios.post(
`${config.baseUrl}/organization/${config.orgId}/inbound-webhooks/case-invitation/${config.invitationMappingId}/decline`,
{ invitation_id: invitationId, decline_reason: reason },
{ params: { Key: config.publicKey } }
);
return response.data;
}
async evaluateInvitation(invitationId) {
const response = await axios.post(
`${config.baseUrl}/organization/${config.orgId}/inbound-webhooks/case-invitation/${config.invitationMappingId}/evaluate`,
{ invitation_id: invitationId },
{ params: { Key: config.publicKey } }
);
return response.data;
}
async sendStatusUpdate(caseId, title, content) {
const response = await axios.post(
`${config.baseUrl}/organization/${config.orgId}/inbound-webhooks/case/${config.updateMappingId}/update`,
{ case_id: caseId, title, content, update_type: 'status' },
{ params: { Key: config.publicKey } }
);
return response.data;
}
}
// ============================================
// RUN
// ============================================
const poller = new HandlerPoller();
const client = new LexamicaClient();
// Poll every 5 minutes for new invitations
const POLL_INTERVAL = 5 * 60 * 1000;
async function run() {
console.log('Polling...');
await poller.poll();
console.log('Done');
}
run();
setInterval(run, POLL_INTERVAL);
// Export client for use in your application
module.exports = { client, poller };
// Example usage in your app:
// await client.acceptInvitation('invitation_id_here');
// await client.sendStatusUpdate('case_id', 'Discovery Complete', 'All depositions done.');