Skip to content

Instantly share code, notes, and snippets.

@marcospassos
Created November 20, 2020 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcospassos/026514534b43fa16e249a32ac464ceea to your computer and use it in GitHub Desktop.
Save marcospassos/026514534b43fa16e249a32ac464ceea to your computer and use it in GitHub Desktop.
Croct server-side evaluation for Node JS
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