UNPKG

botpress

Version:

The world's first CMS for bots. Easily create, manage and extend chatbots.

246 lines (203 loc) 11.7 kB
'use strict'; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _helpers = require('./database/helpers'); var _helpers2 = _interopRequireDefault(_helpers); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /** * The Users namespace contains operations available for the known users of your bot. * @public * @namespace Users * @example * bp.users */ module.exports = ({ db }) => { /** * Returns whether or not a user has a specific tag or not. * @param {String} userId * @param {String} tag The name of the tag. Case insensitive. * @return {Boolean} * @async * @memberof! Users * @example * if (await bp.users.hasTag(event.user.id, 'IS_SUBSCRIBED')) {...} */ const hasTag = (() => { var _ref = _asyncToGenerator(function* (userId, tag) { const knex = yield db.get(); return knex('users_tags').select('userId').where({ userId, tag: _lodash2.default.toUpper(tag) }).limit(1).then(function (ret) { return ret.length > 0; }); }); return function hasTag(_x, _x2) { return _ref.apply(this, arguments); }; })(); /** * Tags a user with a specific tag (or overwrites an existing one) and a given value for that tag (optional). * Tags can be used to classify users (no value needed) or to store information about them (with a tag value). * Values are useful to store user information like emails, etc. * Value is always assumed to be a string. * @param {String} userId * @param {String} tag The name of the tag. * Case insensitive. Note that this property will always be upper-cased. * @param {String} [value] Any string value to store info about this tag * @async * @memberof! Users * @example * await bp.users.tag(event.user.id, 'EMAIL', 'sylvain@botpress.io') * await bp.users.tag(event.user.id, 'PAYING_USER') */ const tag = (() => { var _ref2 = _asyncToGenerator(function* (userId, _tag, value = true) { const knex = yield db.get(); _tag = _lodash2.default.toUpper(_tag); if (yield hasTag(userId, _tag)) { yield knex('users_tags').where({ userId, tag: _tag }).update({ userId, tag: _tag, value, tagged_on: (0, _helpers2.default)(knex).date.now() }).then(); } else { yield knex('users_tags').insert({ userId, tag: _tag, value, tagged_on: (0, _helpers2.default)(knex).date.now() }).then(); } }); return function tag(_x3, _x4) { return _ref2.apply(this, arguments); }; })(); /** * Removes a tag from a user if it exists. * @param {String} userId * @param {String} tag Name of the tag. Case-insensitive. * @memberof! Users */ const untag = (() => { var _ref3 = _asyncToGenerator(function* (userId, tag) { const knex = yield db.get(); yield knex('users_tags').where({ userId, tag: _lodash2.default.toUpper(tag) }).del().then(); }); return function untag(_x5, _x6) { return _ref3.apply(this, arguments); }; })(); /** * Returns the value of a user tag, if it exists * @param {String} userId [description] * @param {String} tag [description] * @return {?String} Value of the tag * @memberof! Users */ const getTag = (() => { var _ref4 = _asyncToGenerator(function* (userId, tag, details = false) { const knex = yield db.get(); return knex('users_tags').select('value', 'tagged_on', 'tag').where({ userId, tag: _lodash2.default.toUpper(tag) }).limit(1).then().get(0).then(function (ret) { if (ret && details) { return _extends({}, ret, { tagged_on: new Date(ret.tagged_on) }); } return ret && ret.value; }); }); return function getTag(_x7, _x8) { return _ref4.apply(this, arguments); }; })(); /** * Returns all the tags for a given user * @param {String} userId [description] * @return {Array.<{ tag: String, value: String}>} An array of all the tags for this user * @memberof! Users */ const getTags = (() => { var _ref5 = _asyncToGenerator(function* (userId) { const knex = yield db.get(); return knex('users_tags').where({ userId }).select('tag', 'value').then(function (tags) { return _lodash2.default.map(tags, function (v) { return { tag: v.tag, value: v.value }; }); }); }); return function getTags(_x9) { return _ref5.apply(this, arguments); }; })(); const list = (() => { var _ref6 = _asyncToGenerator(function* (limit = 50, from = 0) { const knex = yield db.get(); const isLite = (0, _helpers2.default)(knex).isLite(); const TAG_VALUE_SEPARATOR = '::::'; const tagWithValue = `tag || '${TAG_VALUE_SEPARATOR}' || value`; const parseTagValues = function (tagAndValue) { const [tag, value] = tagAndValue.split(TAG_VALUE_SEPARATOR); return { tag, value }; }; const selectTags = isLite ? `group_concat(${tagWithValue}) as tags` : `string_agg(${tagWithValue}, ',') as tags`; const subQuery = knex('users_tags').select('userId', knex.raw(selectTags)).groupBy('userId'); return knex('users').leftJoin(knex.raw('(' + subQuery.toString() + ') AS t2'), 'users.id', '=', 't2.userId').select('users.id', 'users.userId', 'users.platform', 'users.gender', 'users.timezone', 'users.locale', 'users.picture_url', 'users.first_name', 'users.last_name', 'users.created_on', 't2.tags').orderBy('users.created_on', 'asc').offset(from).limit(limit).then(function (users) { return users.map(function (x) { return _extends({}, x, { tags: x.tags && x.tags.split(',').map(parseTagValues) || [] }); }); }); }); return function list() { return _ref6.apply(this, arguments); }; })(); // TODO: Fix this, just doesn't work const listWithTags = (() => { var _ref7 = _asyncToGenerator(function* (tags, limit = 50, from = 0) { const knex = yield db.get(); tags = _lodash2.default.filter(tags, function (t) { return _lodash2.default.isString(t); }).map(function (t) { return t.toUpperCase(); }); const filterByTag = function (tag) { return knex('users_tags').select('userId').where('tag', tag); }; const isLite = (0, _helpers2.default)(knex).isLite(); const selectTags = isLite ? 'group_concat(tag) as tags' : "string_agg(tag, ',') as tags"; let query = knex('users'); let i = 0; const subQuery = knex('users_tags').select('userId', knex.raw(selectTags)).groupBy('userId'); tags.forEach(function (tag) { const name = 't' + ++i; query = query.join(knex.raw('(' + filterByTag(tag).toString() + ') AS ' + name), 'users.id', '=', name + '.userId'); }); return query.leftJoin(knex.raw('(' + subQuery.toString() + ') AS tt'), 'users.id', '=', 'tt.userId').select('users.userId as userId', 'users.platform as platform', 'users.gender as gender', 'users.timezone as timezone', 'users.locale as locale', 'users.picture_url as picture_url', 'users.first_name as first_name', 'users.last_name as last_name', 'users.created_on as created_on', 'tt.tags as tags').orderBy('users.created_on', 'asc').offset(from).limit(limit).then(function (users) { return users.map(function (x) { return Object.assign(x, { tags: x.tags && x.tags.split(',') || [] }); }); }); }); return function listWithTags(_x10) { return _ref7.apply(this, arguments); }; })(); const count = (() => { var _ref8 = _asyncToGenerator(function* () { const knex = yield db.get(); return knex('users').count('* as count').then().get(0).then(function (ret) { return parseInt(ret && ret.count); }); }); return function count() { return _ref8.apply(this, arguments); }; })(); return { tag, untag, hasTag, getTag, getTags, list, count, listWithTags }; }; //# sourceMappingURL=users.js.map