botpress
Version:
The world's first CMS for bots. Easily create, manage and extend chatbots.
246 lines (203 loc) • 11.7 kB
JavaScript
;
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