From 1469e08063762db44fe8faf8805a6c6d169c874c Mon Sep 17 00:00:00 2001
From: Andris Reinman
Date: Mon, 29 Aug 2016 12:27:14 +0300
Subject: [PATCH] Added API call to create new custom fields
---
lib/models/fields.js | 4 +++-
routes/api.js | 48 ++++++++++++++++++++++++++++++++++++++++++++
routes/users.js | 5 +++++
views/users/api.hbs | 47 +++++++++++++++++++++++++++++++++++++++----
4 files changed, 99 insertions(+), 5 deletions(-)
diff --git a/lib/models/fields.js b/lib/models/fields.js
index 87ad301c..5640f9b7 100644
--- a/lib/models/fields.js
+++ b/lib/models/fields.js
@@ -7,6 +7,7 @@ let lists = require('./lists');
let shortid = require('shortid');
let allowedKeys = ['name', 'key', 'default_value', 'group', 'visible'];
+let allowedTypes;
module.exports.grouped = ['radio', 'checkbox', 'dropdown'];
module.exports.types = {
@@ -25,6 +26,8 @@ module.exports.types = {
option: 'Option'
};
+module.exports.allowedTypes = allowedTypes = Object.keys(module.exports.types);
+
module.exports.genericTypes = {
text: 'string',
website: 'string',
@@ -268,7 +271,6 @@ function addCustomField(listId, name, defaultValue, type, group, visible, callba
let column = null;
let key = slugify('merge ' + name, '_').toUpperCase();
- let allowedTypes = ['text', 'number', 'radio', 'checkbox', 'dropdown', 'date-us', 'date-eur', 'birthday-us', 'birthday-eur', 'website', 'option', 'gpg', 'longtext'];
if (allowedTypes.indexOf(type) < 0) {
return callback(new Error('Unknown column type ' + type));
diff --git a/routes/api.js b/routes/api.js
index 8c312711..f4476830 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -276,4 +276,52 @@ router.post('/delete/:listId', (req, res) => {
});
});
+router.post('/field/:listId', (req, res) => {
+ let input = {};
+ Object.keys(req.body).forEach(key => {
+ input[(key || '').toString().trim().toUpperCase()] = (req.body[key] || '').toString().trim();
+ });
+ lists.getByCid(req.params.listId, (err, list) => {
+ if (err) {
+ log.error('API', err);
+ res.status(500);
+ return res.json({
+ error: err.message || err,
+ data: []
+ });
+ }
+ if (!list) {
+ res.status(404);
+ return res.json({
+ error: 'Selected listId not found',
+ data: []
+ });
+ }
+
+ let field = {
+ name: (input.NAME || '').toString().trim(),
+ defaultValue: (input.DEFAULT || '').toString().trim() || null,
+ type: (input.TYPE || '').toString().toLowerCase().trim(),
+ group: Number(input.GROUP) || null,
+ visible: !['false', 'no', '0', ''].includes((input.VISIBLE || '').toString().toLowerCase().trim())
+ };
+
+ fields.create(list.id, field, (err, id) => {
+ if (err) {
+ res.status(500);
+ return res.json({
+ error: err.message || err,
+ data: []
+ });
+ }
+ res.status(200);
+ res.json({
+ data: {
+ id
+ }
+ });
+ });
+ });
+});
+
module.exports = router;
diff --git a/routes/users.js b/routes/users.js
index bffc073b..9ec2aaa1 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -4,6 +4,7 @@ let passport = require('../lib/passport');
let express = require('express');
let router = new express.Router();
let users = require('../lib/models/users');
+let fields = require('../lib/models/fields');
let settings = require('../lib/models/settings');
router.get('/logout', (req, res) => passport.logout(req, res));
@@ -90,6 +91,10 @@ router.get('/api', passport.csrfProtection, (req, res, next) => {
}
user.serviceUrl = configItems.serviceUrl;
user.csrfToken = req.csrfToken();
+ user.allowedTypes = Object.keys(fields.types).map(key => ({
+ type: key,
+ description: fields.types[key]
+ }));
res.render('users/api', user);
});
});
diff --git a/views/users/api.hbs b/views/users/api.hbs
index d8249d95..5adda389 100644
--- a/views/users/api.hbs
+++ b/views/users/api.hbs
@@ -73,7 +73,8 @@
-
- FORCE_SUBSCRIBE – set to "yes" if you want to make sure the email is marked as subscribed even if it was previously marked as unsubscribed. If the email was already unsubscribed/blocked then subscription status is not changed by default.
+ FORCE_SUBSCRIBE – set to "yes" if you want to make sure the email is marked as subscribed even if it was previously marked as unsubscribed. If the email was already unsubscribed/blocked then subscription status is not changed
+ by default.
-
REQUIRE_CONFIRMATION – set to "yes" if you want to send confirmation email to the subscriber before actually marking as subscribed
@@ -84,7 +85,7 @@
Example
-curl -XPOST {{serviceUrl}}api/subscribe/B16uVTdW?access_token={{accessToken}}\
+curl -XPOST {{serviceUrl}}api/subscribe/B16uVTdW?access_token={{accessToken}} \
--data 'EMAIL=test@example.com&MERGE_CHECKBOX=yes&REQUIRE_CONFIRMATION=yes'
POST /api/unsubscribe/:listId – Remove subscription
@@ -111,7 +112,7 @@
Example
-curl -XPOST {{serviceUrl}}api/unsubscribe/B16uVTdW?access_token={{accessToken}}\
+curl -XPOST {{serviceUrl}}api/unsubscribe/B16uVTdW?access_token={{accessToken}} \
--data 'EMAIL=test@example.com'
POST /api/delete/:listId – Delete subscription
@@ -138,5 +139,43 @@
Example
-curl -XPOST {{serviceUrl}}api/delete/B16uVTdW?access_token={{accessToken}}\
+curl -XPOST {{serviceUrl}}api/delete/B16uVTdW?access_token={{accessToken}} \
--data 'EMAIL=test@example.com'
+
+POST /api/field/:listId – Add new custom field
+
+
+ This API call creates a new custom field for a list.
+
+
+
+ GET arguments
+
+
+ - access_token – your personal access token
+
+
+
+ POST arguments
+
+
+ - NAME – field name (required)
+ - TYPE – one of the following types:
+
+ {{#each allowedTypes}}
+ -
+ {{type}} {{description}}
+
+ {{/each}}
+
+
+ - GROUP – If the type is 'option' then you also need to specify the parent element ID
+ - VISIBLE – yes/no, if not visible then the subscriber can not view or modify this value at the profile page
+
+
+
+ Example
+
+
+curl -XPOST {{serviceUrl}}api/field/B16uVTdW?access_token={{accessToken}} \
+--data 'NAME=Birthday&TYPE=birthday-us&VISIBLE=yes'