Skip to main content
Glama
sync-candid-tasks.ts4.11 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { createReference } from '@medplum/core'; import type { BotEvent, MedplumClient } from '@medplum/core'; import fetch from 'node-fetch'; const CANDID_API_URL = 'https://api-staging.joincandidhealth.com/api/v1/'; export async function handler(medplum: MedplumClient, event: BotEvent): Promise<any> { const status = 'open'; // Craft the queries all status of requested typs const candidTaskQuery = { skip: 0, limit: 100, status: status, updated_since: '2021-01-01T00:00:00.000Z', sort: 'updated_at:desc', }; const result = await getCandidTasks( candidTaskQuery, event.secrets['CANDID_API_KEY'].valueString as string, event.secrets['CANDID_API_SECRET'].valueString as string ); console.log('Received Response from Candid:\n', JSON.stringify(result, null, 2)); const candidTaskResult = (await result.json()) as CandidTask[]; for (const candidTask of candidTaskResult) { const encounter = await medplum.createResourceIfNoneExist( { resourceType: 'Encounter', status: 'finished', class: { code: 'inpatient' }, identifier: [ { system: 'https://joincandidhealth.com/encounter/id', value: candidTask.encounter_id, }, ], }, 'identifier=' + candidTask.encounter_id ); await medplum.createResourceIfNoneExist( { resourceType: 'Task', status: 'in-progress', intent: 'order', identifier: [ { system: 'https://api-staging.joincandidhealth.com/task/id', value: candidTask.task_id, }, ], businessStatus: { coding: [ { system: 'http://joincandidhealth.com/task-status', code: candidTask.status, display: candidTask.status, }, ], }, code: { coding: [ { system: 'http://joincandidhealth.com/task-category', code: candidTask.category, }, { system: 'http://joincandidhealth.com/task-category-detail', code: candidTask.detailed_category, }, ], }, note: candidTask.notes.map((note) => ({ text: note.text, authorString: note.author_name, time: note.created_at, })), encounter: createReference(encounter), }, 'identifier=' + candidTask.task_id ); } return result; } /** * Authenticates into the Candid Health API using API key and API secret, and gets the Task object from * Candid's /v1/tasks endpoint * @param candidCodedEncounter - The CodedEncounter object to send to Candid Health * @param apiKey - Candid Health API Key * @param apiSecret - Candid Health API Secret * @returns The response from the Candid Health API */ async function getCandidTasks(candidCodedEncounter: any, apiKey: string, apiSecret: string): Promise<any> { // Get a Bearer Token const authResponse = await fetch(CANDID_API_URL + 'auth/token', { method: 'post', body: JSON.stringify({ client_id: apiKey, client_secret: apiSecret, }), headers: { 'Content-Type': 'application/json' }, }); const bearerToken = ((await authResponse.json()) as any).access_token; // Send the CodedEncounter const taskResponse = await fetch(CANDID_API_URL + '/tasks', { method: 'get', body: JSON.stringify(candidCodedEncounter), headers: { 'Content-Type': 'application/json', authorization: `Bearer ${bearerToken}` }, }); return taskResponse; } interface TaskNote { text: string; task_note_id: string; created_at: string; author_name: string; author_organization_name: string; } interface CandidTask { encounter_id: string; category: string; task_id: string; external_id: string; status: string; notes: TaskNote[]; detailed_category: string; created_at: string; updated_at: string; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server