Login With Evernote - node.js

I'm trying to connect Evernote with Meteor.
But I'm having a really bad time, trying to get the Oauth token, I was trying to follow this example Evernote Sample Meteor, but is pretty old (2 years), but I tried to follow it and I got the idea.
I can get the connect to evernote, the login page and the email verification, my problem raised on the Meteor Method.
handleCallback, which need the "verify" param, which in this case is the
ouath_token
Second try.
On the evernote npm README they suggest to use oAuthjs, and I try with this code.
var hostName = "http://sandbox.evernote.com";
var options,oauth;
options = {
consumerKey: 'xxxxxxxxx',
consumerSecret: 'xxxxxxxxx',
callbackUrl : 'http://localhost:3000/oauth/auth',
signatureMethod : "HMAC-SHA1",
};
oauth.request({'method': 'GET', 'url': hostName + '/oauth',
'success': function(data){
console.log(data);
}, 'failure': function(data){
console.log(data);
}});
But it returns
(STDERR) No valid request transport found.
So I'm pretty stuck here.

The npm module provided by Evernote includes helper functions to get OAuth working.
Install the Evernote npm module via:
$npm install evernote
Below is the simplest single file example of implementing OAuth in a Evernote application I could put together. Just change the values of CONSUMER_KEY and CONSUMER_SECRET below and it should run just fine if you've installed Evernote:
var Evernote = require('evernote').Evernote;
var http = require("http");
var url = require("url");
CONSUMER_KEY="Put your consumer key here";
CONSUMER_SECRET="put your consumer secret here";
if (CONSUMER_KEY === "Put your consumer key here"){
console.error("\nPlease enter your Evernote consumer key and secret\n\nIf you don't have a key you can get one at:\nhttps://dev.evernote.com/#apikey\n")
process.exit(1)
}
var global = {};
global.oauthToken = '';
global.oauthSecret = '';
function getOauthVerifier(url) {
var regex = new RegExp("[\\?&]oauth_verifier=([^&#]*)"),
results = regex.exec(url);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
var handler = function(request, response) {
var params = url.parse(request.url)
var pathname = params.pathname;
console.log("Request for " + pathname + " received.");
var client = new Evernote.Client ({
consumerKey: "Put your consumer key here",
consumerSecret: "put your consumer secret here",
sandbox: true
});
if (pathname == "/"){
var callbackUrl = 'http://localhost:8888/oauth';
client.getRequestToken(callbackUrl, function(err, oauthToken, oauthSecret, results){
if(err) {
console.log(err);
}
else {
global.oauthToken = oauthToken;
global.oauthSecret = oauthSecret;
console.log("set oauth token and secret");
var authorizeUrl = client.getAuthorizeUrl(oauthToken);
console.log(authorizeUrl);
response.writeHead(200, {"Content-Type":"text/html"});
response.write("Please click here to authorize the application");
response.end();
}
});
}
else if (pathname == "/oauth"){
client.getAccessToken(
global.oauthToken,
global.oauthSecret,
getOauthVerifier(params.search),
function(error, oauthAccessToken, oauthAccessTokenSecret, results) {
if(error) {
console.log("error\n\n\n");
console.log(error);
}
else {
response.writeHead(200, {"Content-Type":"text/html"});
response.write(oauthAccessToken);
response.end();
}
}
);
}
else {
response.writeHead(200, {"Content-Type":"text/html"});
response.write("not a valid URL GO HOME ");
response.end();
}
};
http.createServer(handler).listen(8888);

Related

Callback doesn't seem to work in Lambda Node.js function - maybe due to firewall?

So I'm trying to password-protect a static S3 website using Node.js in a Lambda#Edge function and a CloudFront trigger. I use the www-authenticate header to get the user's credentials, decode the resulting authorization header to get the username/password, then call adminInitiateAuth (from the aws-sdk) to authenticate with a Cognito user pool.
Here's the actual code:
'use strict';
const AWS = require('aws-sdk');
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
const body = 'Unauthorized';
const response = {
status: '401',
statusDescription: 'Unauthorized',
body: body,
headers: {
'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
},
};
if(typeof headers.authorization != 'undefined'){
var decoded = new Buffer(headers.authorization[0].value.split(" ")[1], "base64").toString();
console.log("decoded from auth header without basic: " + decoded);
var arr = decoded.split(":");
var user = arr[0];
var pass = arr[1];
console.log("user: " + user);
console.log("pass: " + pass);
const cognito = new AWS.CognitoIdentityServiceProvider( 'us-east-1');
var params = {
AuthFlow: 'ADMIN_NO_SRP_AUTH',
ClientId: [myclientid],
UserPoolId: [myuserpoolid],
AuthParameters: {
USERNAME: user,
PASSWORD: pass,
},
};
cognito.adminInitiateAuth(params, function(err, data) {
if(err){
console.log("failed to authenticate");
console.log(err, err.stack);
callback(null, response);
} else{
console.log("successfully authenticated");
console.log(data);
callback(null, request);
}
});
}
else{
callback(null, response);
}
};
It doesn't seem like there's a problem with the code itself, because it works fine most of the time. But when I'm on my company's network, I keep getting prompted to enter my username and password, even if I input it correctly. I know my company's network has firewall, but I'm not sure of its settings, and how that would interfere with the authentication in the code.
After testing the code a bit more, I've discovered a few things:
Even with the correct credentials entered, adminInitiateAuth seems to give an error (so the callback to continue the request is never called). The authorization header is in the request as far as I can tell, so I'm not sure why this is happening (and only on my company's network).
CloudWatch logs only seem to appear when I make requests outside of my company's network.

Authentication Error when Retrieving and Editing Device Configuration on IoT-Core

I'm trying to use a backend nodeJS server to access (and edit) the device configuration on IoT-Core referring to this API docs
However, I keep getting error:
code 401 with error message "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED".
I created a service account and a key from Google IAM, and gave it Cloud IoT Device Controller permissions, which could update device configurations but not create or delete. Subsequently, I changed it to Cloud IoT Admin and even Project Editor permissions, but still saw the same error message. Am I getting the keys all wrong, or not doing something else I should be doing?
Code below was how I invoked the request
function createJwt (projectId, privateKeyFile, algorithm) {
// Create a JWT to authenticate this device. The device will be disconnected
// after the token expires, and will have to reconnect with a new token. The
// audience field should always be set to the GCP project ID.
const token = {
'iat': parseInt(Date.now() / 1000),
'exp': parseInt(Date.now() / 1000) + 20 * 60, // 20 minutes
'aud': projectId
};
const privateKey = fs.readFileSync(privateKeyFile);
return jwt.sign(token, privateKey, { algorithm: algorithm });
}
app.get('/', function(req, res){
let authToken = createJwt('test-project', './keys/device-config.pem', 'RS256');
const options = {
url: 'https://cloudiot.googleapis.com/v1/projects/test-project/locations/us-central1/registries/dev-registry/devices/test-device',
headers: {
'authorization': 'Bearer ' + authToken,
'content-type': 'application/json',
'cache-control': 'no-cache'
},
json: true
}
request.get(options, function(error, response){
if(error) res.json(error);
else res.json(response);
})
});
For backend servers to interact with IoT-Core, the authentication method is not the same as for device MQTT or HTTP connections. Reference: https://cloud.google.com/iot/docs/samples/device-manager-samples#get_a_device
I was able to retrieve and update device configurations using the code below
function getClient (serviceAccountJson, cb) {
const serviceAccount = JSON.parse(fs.readFileSync(serviceAccountJson));
const jwtAccess = new google.auth.JWT();
jwtAccess.fromJSON(serviceAccount);
// Note that if you require additional scopes, they should be specified as a
// string, separated by spaces.
jwtAccess.scopes = 'https://www.googleapis.com/auth/cloud-platform';
// Set the default authentication to the above JWT access.
google.options({ auth: jwtAccess });
const DISCOVERY_API = 'https://cloudiot.googleapis.com/$discovery/rest';
const API_VERSION = 'v1';
const discoveryUrl = `${DISCOVERY_API}?version=${API_VERSION}`;
google.discoverAPI(discoveryUrl, {}, (err, client) => {
if (err) {
console.log('Error during API discovery', err);
return undefined;
}
cb(client);
});
}
function getDevice (client, deviceId, registryId, projectId, cloudRegion) {
const parentName = `projects/${process.env.GCP_PROJECT_ID}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const request = {
name: `${registryName}/devices/${deviceId}`
};
const promise = new Promise(function(resolve, reject){
client.projects.locations.registries.devices.get(request, (err, data) => {
if (err) {
console.log('Could not find device:', deviceId);
console.log(err);
reject(err);
} else {
console.log(data.config.binaryData);
resolve(data);
}
});
});
return promise;
}
app.get('/', function(req, res){
const cb = function(client){
getDevice(client, 'test-device', 'dev-registry', process.env.GCP_PROJECT_ID, 'us-central1')
.then(function(response){
let decoded = new Buffer(response.config.binaryData, 'base64').toString();
res.json(decoded);
})
.catch(function(error){
res.json(error);
})
}
getClient(serviceAccountJson, cb);
});
I think what you're looking to do is best accomplished using the client library for NodeJS.
First, retrieve an API client object as done in the sample. This will take in the service account credentials you used and will authenticate against Google API Core servers.
At the point in the referenced code where cb(client); is invoked, you'll have your client object and are ready to update your device. Add the imports and API constants from the sample and replace the code where you have a client object with the following code and you should be set.
Use some strings for your device identifiers:
const projectId = 'my-project';
const cloudRegion = 'us-central1';
const registryId = 'my-registry';
const deviceId = 'my-device;
const config = '{fan: 800}';
Next, form your device String:
const deviceId = `projects/${projectId}/locations/${cloudRegion}/registries/${registryId}/devices/${deviceId}`;
const binaryData = Buffer.from(config).toString('base64');
Now you form your request object and execute:
const request = {
name: `${registryName}`,
versionToUpdate: 0,
binaryData: binaryData
};
console.log(request);
client.projects.locations.registries.devices
.modifyCloudToDeviceConfig(
request,
(err, data) => {
if (err) {
console.log('Could not update config:', deviceId);
console.log('Message: ', err);
} else {
console.log('Success :', data);
}
});
Your configuration is updated. If your device is subscribed to the config topic on MQTT it will receive the latest configuration, otherwise, you can poll for the configuration with HTTP from your device.
Just to confirm, when you created the SSL key pair, and when you registered the device with the Cloud IoT Core registry, did you match the type of key created with the radio button you registered it with?
Also to confirm, you put the Google root certificate on the device in the same directory as the private key: ./keys/device-config.pem ? If not you can fetch it with: wget https://pki.google.com/roots.pem.

How to retrieve user's additional information from Azure Mobile/App Services?

I need to get the user's extra information from social accounts like Facebook and Google+. When I first read about Azure Mobile Services I thought it to be the holy grail of social authentication. Well, after a full week of hair pulling I'm starting to reconsider my first impression. It does authenticate as easily as it could possibly do. I configured Google+ and FB to work with Azure, configured Azure to use the key/secret from each provider and it all just worked. I was able to login perfectly. The problem started when I tried to get information from the logged user, which I honestly think is basic!
Azure Mobile Services returns the UserId and a Token that you can not use to request the extra info on the selected provider. So even if I were to create a second request using FB's graph API for instance, that wouldn't work (I've tried!). That token is Azure's own token. So I found out from several Carlos Figueira (SE at Azure) posts that I should customize my Azure script, make a request to Azure and then I'd be able to get it working.
I've also read several posts from Carlos Figueira on how to implement that extra functionality and even though that was not what I was looking for (customizing the server) I decided to work with that. But my return type is a MobileServiceUser and that type only has 2 properties: UserId and MobileServiceAuthenticationToken. So even after adding the server script from Carlos I couldn't retrieve the extra information from my Xamarin App.
I've read a lot of things, researched a lot and couldn't find an answer =/ By the way this is not the answer:
How to get user name, email, etc. from MobileServiceUser?
Did anyone manage to make it work?
PS: I'm not posting any code here because it's working. If you think checking some part of my code would help decipher the problem just let me know.
Thanks in advance!
EDIT:
Script
function insert(item, user, request) {
item.UserName = "<unknown>"; // default
user.getIdentities({
success: function (identities) {
var url = null;
var oauth = null;
if (identities.google) {
var googleAccessToken = identities.google.accessToken;
url = 'https://www.googleapis.com/oauth2/v3/userinfo?access_token=' + googleAccessToken;
} else if (identities.facebook) {
var fbAccessToken = identities.facebook.accessToken;
url = 'https://graph.facebook.com/me?access_token=' + fbAccessToken;
} else if (identities.microsoft) {
var liveAccessToken = identities.microsoft.accessToken;
url = 'https://apis.live.net/v5.0/me/?method=GET&access_token=' + liveAccessToken;
} else if (identities.twitter) {
var userId = user.userId;
var twitterId = userId.substring(userId.indexOf(':') + 1);
url = 'https://api.twitter.com/1.1/users/show.json?user_id=' + twitterId;
var consumerKey = process.env.MS_TwitterConsumerKey;
var consumerSecret = process.env.MS_TwitterConsumerSecret;
oauth = {
consumer_key: consumerKey,
consumer_secret: consumerSecret,
token: identities.twitter.accessToken,
token_secret: identities.twitter.accessTokenSecret
};
}
if (url) {
var requestCallback = function (err, resp, body) {
if (err || resp.statusCode !== 200) {
console.error('Error sending data to the provider: ', err);
request.respond(statusCodes.INTERNAL_SERVER_ERROR, body);
} else {
try {
var userData = JSON.parse(body);
item.UserName = userData.name;
request.execute();
} catch (ex) {
console.error('Error parsing response from the provider API: ', ex);
request.respond(statusCodes.INTERNAL_SERVER_ERROR, ex);
}
}
}
var req = require('request');
var reqOptions = {
uri: url,
headers: { Accept: "application/json" }
};
if (oauth) {
reqOptions.oauth = oauth;
}
req(reqOptions, requestCallback);
} else {
// Insert with default user name
request.execute();
}
}
});
}
You're talking about the token on the client side correct? That token is specific only to the client. If you're using Server Side flow, the server is the only one with that token. If you want to send that to the client, you need to do that via a custom API you create.
This class you're talking about does only contain those two properties. But on your server side, your ServiceUser can access the different identity provider tokens in order to speak to those servers APIs. Your linked post is correct in how you access the token, you're mistaken on where you can access that token, it's only on the server side (if you use the server directed login flow).
Here is the custom API Script I had working in Mobile Services to return the profile of the logged in user. I am working on updating to Mobile Apps as some environment variables appear to have changed. Would love to know if anyone has gotten it to work with Mobile Apps.
exports.get = function (request, response) {
var user = request.user;
user.getIdentities({
success: function (identities) {
var req = require('request');
var url = null;
var oauth = null;
var userId = user.userId.split(':')[1];
console.log('Identities: ', identities);
if (identities.facebook) {
url = 'https://graph.facebook.com/me?access_token=' +
identities.facebook.accessToken;
} else if (identities.google) {
url = 'https://www.googleapis.com/oauth2/v3/userinfo' +
'?access_token=' + identities.google.accessToken;
} else if (identities.microsoft) {
url = 'https://apis.live.net/v5.0/me?access_token=' +
identities.microsoft.accessToken;
} else if (identities.twitter) {
var consumerKey = process.env.MS_TwitterConsumerKey;
var consumerSecret = process.env.MS_TwitterConsumerSecret;
oauth = {
consumer_key: consumerKey,
consumer_secret: consumerSecret,
token: identities.twitter.accessToken,
token_secret: identities.twitter.accessTokenSecret
};
url = 'https://api.twitter.com/1.1/users/show.json?' +
'user_id=' + userId + '&include_entities=false';
} else {
response.send(500, { error: 'No known identities' });
return;
}
if (url) {
var reqParams = { uri: url, headers: { Accept: 'application/json' } };
if (oauth) {
reqParams.oauth = oauth;
}
req.get(reqParams, function (err, resp, body) {
if (err) {
console.error('Error calling provider: ', err);
response.send(500, { error: 'Error calling provider' });
return;
}
if (resp.statusCode !== 200) {
console.error('Provider call did not return success: ', resp.statusCode);
response.send(500, { error: 'Provider call did not return success: ' + resp.statusCode });
return;
}
try {
var userData = JSON.parse(body);
response.send(200, userData);
} catch (ex) {
console.error('Error parsing response: ', ex);
response.send(500, { error: ex });
}
});
} else {
response.send(500, { error: 'Not implemented yet', env: process.env });
}
}
});
};

Setting Authorization in Node.js SOAP Client

I want to access a WSDL service through SOAP Client in Node.js. I used soap node module. But I can't able to find any documentation to set username and password. I'm not going to create SOAP server, I just want SOAPClient which is similar to PHP's SoapClient, using which I should able to access the WSDL service.
Update:
I had forked and customised the source to support this feature https://github.com/sincerekamal/node-soap
You can provide username and password like this:
var soap = require('soap');
var url = 'your WSDL url';
var auth = "Basic " + new Buffer("your username" + ":" + "your password").toString("base64");
soap.createClient(url, { wsdl_headers: {Authorization: auth} }, function(err, client) {
});
(derived from https://github.com/vpulim/node-soap/issues/56, thank you Gabriel Lucena https://github.com/glucena)
Another option to add basic authentication is using client.addHttpHeader. I tried both setSecurity and setting wsdl_headers but neither worked for me when authenticating to Cisco CUCM AXL.
Here is what worked for me:
var soap = require('soap');
var url = 'AXLAPI.wsdl'; // Download this file and xsd files from cucm admin page
var auth = "Basic " + new Buffer("your username" + ":" + "your password").toString("base64");
soap.createClient(url,function(err,client){
client.addHttpHeader('Authorization',auth);
});
Just to share what I've read from https://github.com/vpulim/node-soap:
var soap = require('soap');
var url = 'your WSDL url';
soap.createClient(url, function(err, client) {
client.setSecurity(new soap.BasicAuthSecurity('your username','your password'));
});
You need to set the username and password by passing the authorisation to the wsdl_headers object e.g
var auth = "Basic " + new Buffer('username' + ':' + 'password').toString("base64");
var client = Soap.createClient('wsdlUrl', { wsdl_headers: { Authorization: auth } }, (err, client) => {
if (err) {
throw err;
} else {
client.yourMethod();
}
});
A small tweak to the existing answers: you can use your security object to create the header for the WSDL request too, e.g.
const security = new soap.BasicAuthSecurity(username, password);
const wsdl_headers = {};
security.addHeaders(wsdl_headers);
soap.createClientAsync(url, { wsdl_headers }).then((err, client) => {
client.setSecurity(security);
// etc.
});
Or if you're using something more complicated than BasicAuthSecurity you may also need to set wsdl_options from the security object, e.g.
const security = new soap.NTLMSecurity(username, password, domain, workstation);
const wsdl_headers = {}, wsdl_options = {};
security.addHeaders(wsdl_headers);
security.addOptions(wsdl_options);
soap.createClientAsync(url, { wsdl_headers, wsdl_options }).then((err, client) => {
client.setSecurity(security);
// etc.
});

Use the Mailchimp API

I'd like to use the Mailchimp Node.js API in my Parse Cloud Hosting app to subscribe a user to a mailing list. Parse doesn't support NPM but, given that the Mailchimp API has no dependencies, I thought I'd be able to copy the code into my project. However, the Mailchimp API uses the "https" module which Parse doesn't support.
Does anyone know of a way around this?
I've been unable to use the Mailchimp API directly but the REST API is pretty easy to use.
In main.js, create a Cloud Function. Enter your API key and update the REST URL to point at the correct Mailchimp data center (http://apidocs.mailchimp.com/api/2.0/)
var mailchimpApiKey = "<<REPLACE_WITH_YOUR_KEY>>";
Parse.Cloud.define("SubscribeUserToMailingList", function(request, response) {
if (!request.params ||
!request.params.email){
response.error("Must supply email address, firstname and lastname to Mailchimp signup");
return;
}
var mailchimpData = {
apikey : mailchimpApiKey,
id : request.params.listid,
email : {
email : request.params.email
},
merge_vars : request.params.mergevars
}
var url = "https://<<REPLACE_WITH_DATA_CENTRE>>.api.mailchimp.com/2.0/lists/subscribe.json";
Parse.Cloud.httpRequest({
method: 'POST',
url: url,
body: JSON.stringify(mailchimpData),
success: function(httpResponse) {
console.log(httpResponse.text);
response.success("Successfully subscribed");
},
error: function(httpResponse) {
console.error('Request failed with response code ' + httpResponse.status);
console.error(httpResponse.text);
response.error('Mailchimp subscribe failed with response code ' + httpResponse.status);
}
});
});
Then, in the code which calls this function... (replace your list ID)
Parse.Cloud.run("SubscribeUserToMailingList", {
listid : "<<REPLACE_WITH_LIST_ID>>",
email : email,
mergevars : {
FNAME : firstName,
LNAME : lastName
}
})
.then(function(success){
console.log("Successfully subscribed");
// ...
},
function(error){
console.log("Unable to subscribe");
// ...
});
Install mailchimp in your project
npm install mailchimp-api
From client controller call the server-controller with required data
Don't forget to add $http to the top of controller
$http({
method : 'POST',
url : '/mailchimp-users/subscribe',
data : {user:this.name}}).
success(function(response) {
console.log("hai this is basic test" + response);
$scope.send = response.message;
}).error(function(response) {
$scope.error = response.message;
});
In server controller
Add this to the beginning of page
var MailchimpUser = mongoose.model('MailchimpUser'),
_ = require('lodash'),
mcapi = require('mailchimp-api');
var apiKey = '4bf6fb8820c333da4179216c3c2ef8fb-us10';
// Change this to your Key
var listID = 'ebbf193760';
var mc = new mcapi.Mailchimp(apiKey, {version: '2.0'});
Add this function
exports.subscribe = function(req, res) {
var entry = req.body.user;
var mcReq = {
apikey: '4bf6fb8820c333da4179216c3c2ef8fb-us10',
id: 'ebbf193760',
email: {email: entry + '#gmail.com'},
merge_vars: {
FNAME: 'subscriber-first-name',
LNAME: 'subscriber-last-name'
},
'double_optin': false,
'send_welcome': true
}
// submit subscription request to mail chimp
mc.lists.subscribe(mcReq, function(data) {
console.log(data);
}, function(error) {
console.log(error);
});
};
Add this route your route file
app.route('/mailchimp-users/subscribe')
.post(mailchimpUsers.subscribe);
Here's how I got it to work using the MailChimp API v3.0, the method below supports adding/updating a subscriber, as well as adding/removing him to/from a Group!
Prerequisite:
You need to get an MD5 hash method to convert the user's email into a hash.
Here's the one I used: http://www.webtoolkit.info/javascript-md5.html#.Vuz-yjZOwXV
Copy the code in the link, and paste it into a newly created file, name it "md5js.js" for example.
Update the code you copied to start with exports.MD5 = function (string) {
You can test the conversion you got from the copy/pasted module by comparing the result with this online tool: http://www.miraclesalad.com/webtools/md5.php
var jsmd5 = require('cloud/md5js.js');
// here replace that with your own data center (by looking at your API key).
var datacenter = "us13";
var MAILCHIMP_URL = "https://<any_string>:<apikey>#" + datacenter + ".api.mailchimp.com/3.0/";
var MAILCHIMP_LIST_NEWSLETTER_ID = <yourlistId>;
Parse.Cloud.define("SubscribeUserToMailingList", function(request, response) {
if (!request.params ||
!request.params.email){
response.error("Must supply email address, firstname and lastname to Mailchimp signup");
return;
}
var email = request.params.email;
var firstName = request.params.firstname;
var lastName = request.params.lastname;
// this converts the email string into an MD5 hash.
// this is Required if you want to use a "PUT" which allows add/update of an entry, compared to the POST that allows only adding a new subscriber.
var emailHash = jsmd5.MD5(email);
var mailchimpData = {
'email_address': email,
'status': "subscribed",
'merge_fields': {
'FNAME': firstName,
'LNAME': lastName
},
'interests': {
"<groupID>": true // optional, if you want to add the user to a "Group".
}
};
var url = MAILCHIMP_URL + "lists/" + MAILCHIMP_LIST_NEWSLETTER_ID + "/members/" + emailHash;
// using a "PUT" allows you to add/update an entry.
Parse.Cloud.httpRequest({
method: 'PUT',
url: url,
body: JSON.stringify(mailchimpData),
success: function(httpResponse) {
console.log(httpResponse.text);
response.success("Successfully subscribed");
},
error: function(httpResponse) {
console.error('Request failed with response code ' + httpResponse.status);
console.error(httpResponse.text);
response.error('Mailchimp subscribe failed with response code ' + httpResponse.status);
}
});
});

Resources