Created
November 20, 2020 19:40
-
-
Save marcospassos/026514534b43fa16e249a32ac464ceea to your computer and use it in GitHub Desktop.
Croct server-side evaluation for Node JS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as https from 'https'; | |
import * as querystring from 'querystring'; | |
import {createGunzip} from 'zlib'; | |
const APP_ID = process.env.CROCT_APP_ID as string; | |
const API_KEY = process.env.CROCT_API_KEY as string; | |
if (APP_ID === undefined) { | |
throw new Error('Croct app ID required.'); | |
} | |
if (API_KEY === undefined) { | |
throw new Error('Croct API key required.'); | |
} | |
const agent = new https.Agent({ | |
keepAlive: true, | |
}); | |
export function getSessionToken(userId = ''): Promise<string> { | |
return new Promise((resolve, reject) => { | |
const req = https.request( | |
{ | |
agent: agent, | |
hostname: 'api.croct.io', | |
protocol: 'https:', | |
path: `/token/${userId}`, | |
headers: { | |
'Accept-Encoding': 'gzip', | |
'x-api-key': API_KEY, | |
}, | |
}, res => { | |
const data: string[] = []; | |
let stream: NodeJS.ReadableStream = res; | |
if (res.headers['content-encoding'] === 'gzip') { | |
stream = stream.pipe(createGunzip()); | |
} | |
stream.setEncoding('utf-8'); | |
stream.on('data', chunk => data.push(chunk)); | |
stream.on('end', () => { | |
const body = JSON.parse(data.join('')); | |
if (res.statusCode === 200) { | |
resolve(body.token); | |
} else { | |
console.error('Error retrieving Croct token:', body); | |
reject(new Error('Error retrieving Croct token.')); | |
} | |
}); | |
}, | |
); | |
req.on('error', reject); | |
req.end(); | |
}); | |
} | |
export function evaluate<T>(expression: string, token: string, attributes: object = {}): Promise<T> { | |
return new Promise((resolve, reject) => { | |
const request = https.request( | |
{ | |
agent: agent, | |
hostname: 'api.croct.io', | |
protocol: 'https:', | |
path: `/session/web/evaluate?${querystring.stringify({ | |
expression: expression, | |
context: JSON.stringify({ | |
attributes: attributes, | |
}), | |
})}`, | |
headers: { | |
'Accept-Encoding': 'gzip', | |
'content-type': 'applciation/json', | |
'x-app-id': APP_ID, | |
'x-token': token, | |
}, | |
}, response => { | |
const data: string[] = []; | |
let stream: NodeJS.ReadableStream = response; | |
if (response.headers['content-encoding'] === 'gzip') { | |
stream = stream.pipe(createGunzip()); | |
} | |
stream.setEncoding('utf-8'); | |
stream.on('data', chunk => data.push(chunk)); | |
stream.on('error', chunk => data.push(chunk)); | |
stream.on('end', () => { | |
const body = JSON.parse(data.join('')); | |
if (response.statusCode === 200) { | |
resolve(body); | |
} else { | |
console.error('Error during evaluation:', body); | |
reject(new Error('Error during evaluation.')); | |
} | |
}); | |
}, | |
); | |
request.on('error', reject); | |
request.end(); | |
}); | |
} | |
// Example | |
(async () => { | |
// Resolve the internal userId of the user | |
const userId = 'erick.doe'; | |
const token = await getSessionToken(userId); | |
// Send the token back to the client and save it to the session | |
const result = await evaluate<string>("location's city is in context's cities", token, {cities: ['São Paulo', 'Porto Alegre']}); | |
console.log(result); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment