getting profile information using passport-linkedin-oauth2 - node.js

I am using passport-linkedin-oauth to connect to linkedin from node.js. I am getting results in the format :
{ provider: 'linkedin',
id: 'd8UCzVLeQ4',
displayName: 'Sunanda Saha',
name: { familyName: 'Saha', givenName: 'Sunanda' },
emails: [ { value: 'sunanda.saha90#gmail.com' } ],
photos:
[ { value: 'https://media.licdn.com/dms/image/C4D03AQFrIK2nFzHrCA/profile-displayphoto-shrink_100_100/0?e=1535587200&v=beta&t=uSLIk3r-gZ8yxdKK_X3g8M1a4usPXmkLbQbyhvhwu0w' } ],
_raw: '{\n "apiStandardProfileRequest": {\n "headers": {\n "_total": 1,\n "values": [{\n "name": "x-li-auth-token",\n "value": "name:Hhbi"\n }]\n },\n "url": "https://api.linkedin.com/v1/people/d8UCzVLeQ4"\n },\n "distance": 0,\n "emailAddress": "sunanda.saha90#gmail.com",\n "firstName": "Sunanda",\n "formattedName": "Sunanda Saha",\n "headline": "Student at National Institute of Technology Durgapur",\n "id": "d8UCzVLeQ4",\n "industry": "Computer Hardware",\n "lastName": "Saha",\n "location": {\n "country": {"code": "in"},\n "name": "Durgapur Area, India"\n },\n "numConnections": 43,\n "numConnectionsCapped": false,\n "pictureUrl": "https://media.licdn.com/dms/image/C4D03AQFrIK2nFzHrCA/profile-displayphoto-shrink_100_100/0?e=1535587200&v=beta&t=uSLIk3r-gZ8yxdKK_X3g8M1a4usPXmkLbQbyhvhwu0w",\n "pictureUrls": {\n "_total": 1,\n "values": ["https://media.licdn.com/dms/image/C4D00AQHRGUNS3tX9nA/profile-originalphoto-shrink_900_1200/0?e=1530086400&v=beta&t=OpBcFgQZf3T6itjXiRUruXYwBmJ0E-Lth3Vk-HwSMT8"]\n },\n "positions": {"_total": 0},\n "publicProfileUrl": "https://www.linkedin.com/in/sunanda-saha-b02098144",\n "relationToViewer": {"distance": 0},\n "siteStandardProfileRequest": {"url": "https://www.linkedin.com/profile/view?id=AAoAACLlVTIBohmGBTmRaxEcHqMt7a-RpvQakIE&authType=name&authToken=Hhbi&trk=api*a5259465*s5577785*"}\n}',
_json:
{ apiStandardProfileRequest:
{ headers: [Object],
url: 'https://api.linkedin.com/v1/people/d8UCzVLeQ4' },
distance: 0,
emailAddress: 'sunanda.saha90#gmail.com',
firstName: 'Sunanda',
formattedName: 'Sunanda Saha',
headline: 'Student at National Institute of Technology Durgapur',
id: 'd8UCzVLeQ4',
industry: 'Computer Hardware',
lastName: 'Saha',
location: { country: [Object], name: 'Durgapur Area, India' },
numConnections: 43,
numConnectionsCapped: false,
pictureUrl: 'https://media.licdn.com/dms/image/C4D03AQFrIK2nFzHrCA/profile-displayphoto-shrink_100_100/0?e=1535587200&v=beta&t=uSLIk3r-gZ8yxdKK_X3g8M1a4usPXmkLbQbyhvhwu0w',
pictureUrls: { _total: 1, values: [Array] },
positions: { _total: 0 },
publicProfileUrl: 'https://www.linkedin.com/in/sunanda-saha-b02098144',
relationToViewer: { distance: 0 },
siteStandardProfileRequest:
{ url: 'https://www.linkedin.com/profile/view?id=AAoAACLlVTIBohmGBTmRaxEcHqMt7a-RpvQakIE&authType=name&authToken=Hhbi&trk=api*a5259465*s5577785*' } } }
To get the information I am using
newUser.linkedin.name = profile.displayName;
newUser.linkedin.email = profile.emailAddress;
newUser.linkedin.location = profile.location;
I am getting the name but not email and location. How to get the other two. And also the gender.

According to the json you provided it should give you your required info in the following formate.
newUser.linkedin.name = jsonYouGave.formattedName;
newUser.linkedin.email = jsonYouGave.emailAddress;
newUser.linkedin.location = jsonYouGave.location.name;
jsonYouGave is the json which you updated in your answer.

Related

Mongodb nodejs, find and display array in array

I'm looking for display a array in array after findOne.
Example my document:
"name": "test",
"Electro": [{
"name": "test2",
"level": "0",
"_id": {
"$oid": "62015643157b21f7abfcf0b0"
},
"build": [{
"artifactName": "Aventurier",
"MainStat": "HP",
"MainStatValue": "15%",
"SubStat1": "Crit%",
"SubStat1Value": "30%",
"SubStat2": "PV%",
"SubStat2Value": "9%"
}]
//////////////////////////
type is a variable (let type = Electro)
User.User_Characters.findOne({"name": 'test'}, {[type]:{$elemMatch:{'name': cn}}}).then(result => {
if(result){
console.log(result); console.log(result.Electro)
}
i need console.log(result.Electro.build)
UPDATE:
resolve -> result.Electro[0], thx Joe
I have other problems :
User.User_Characters.findOne({"name": username}, {[type]:{$elemMatch:{'name': cn}}}).then(result => {
if(result){
console.log(result)
And my result =
{
_id: new ObjectId("61fea8cfcfad2dc0c3f0f740"),
Pyro: [
{
name: 'Amber',
level: '0',
_id: new ObjectId("62015643157b21f7abfcf0aa"),
build: [{
"artifactName": "Aventurier",
"MainStat": "HP",
"MainStatValue": "15%",
"SubStat1": "Crit%",
"SubStat1Value": "30%",
"SubStat2": "PV%",
"SubStat2Value": "9%"
}]
}
]
}
I just need result = build array :
{
build: [{
"artifactName": "Aventurier",
"MainStat": "HP",
"MainStatValue": "15%",
"SubStat1": "Crit%",
"SubStat1Value": "30%",
"SubStat2": "PV%",
"SubStat2Value": "9%"
}]
}

Update numeric and float fields in elasticsearch client

I am bit new to elasticsearch client.
I have not done any type of predefined mapping to any field, because I might add some new field to the documents in future.
My data looks like this:-
{
"segmentId": "4700-b70e-881",
"segmentName": "test",
"data": "This is a test data",
"dataId": "70897e86-9d69-4700-b70e-881a7f74e9f9",
"augmented": false,
"createdBy": {
"email": "2010abinas#gmail.com",
"primaryKey": "902d2b57-54e6",
"secondaryKey": "adcc-f20423822c93"
},
"status": "active",
"createdAt": 1617422043554,
"updatedAt": 1617422043554
}
I wanted to update 3 fields by using updateByQuery.
I was trying below approach.
await esClient.updateByQuery({
index: "data",
type: "doc",
refresh: true,
body:{
query:{
match: {
dataId: "70897e86-9d69-4700-b70e-881a7f74e9f9"
}
},
script:{
lang:"painless",
source:`ctx._source.data='This is updated test data';ctx._source.updatedAt=${Date.now()};ctx._source.segmentId=null`
}
}
})
I am getting compilation error because of updatedAt and segmentId, When I pass as string it works, like:-
source:`ctx._source.data='This is updated test data';ctx._source.updatedAt='${Date.now()}';ctx._source.segmentId='null'`
I found a way to solve the above issue,
await esClient.updateByQuery({
index: "data",
type: "doc",
refresh: true,
body:{
query:{
match: {
dataId: "70897e86-9d69-4700-b70e-881a7f74e9f9"
}
},
script:{
lang:"painless",
source:`ctx._source.data='This is updated test data';ctx._source.updatedAt=params.date;ctx._source.segmentId=params.segmentId`,
params:{
date: Date.now(),
segmentId: null
}
}
}
});

No value passed to the slots but Original Value is passed in the bot

I am using Amazon lex with AWS lambda as a validation Codehook. When I was trying to pass a value with a response card dynamically generated, it is showing null value in the AppointmentTime Slot but the original value is showing value in slotDetails.
Here is the request sent through lex:
{
"messageVersion": "1.0",
"invocationSource": "DialogCodeHook",
"userId": "prwna44b91sbr4w7d2pwwva59anaqzqx",
"sessionAttributes": {
"store_id": "26",
"address": "Quark Atrium, A‐45, Phase VIII Extension,Industrial Focal Point,Sahibzada Ajit Singh Nagar, Punjab 160071,India",
"closingTime": "19:00:00",
"city": "Mohali",
"phone": "9718409751",
"bookingDateTime": "2018-05-27T21:25:46+05:30",
"openingTime": "10:00:00",
"state": "PB",
"email": "bhuvnesh.kumar#sourcefuse.com",
"zip_code": "44545"
},
"requestAttributes": null,
"bot": {
"name": "ScheduleRide",
"alias": "$LATEST",
"version": "$LATEST"
},
"outputDialogMode": "Text",
"currentIntent": {
"name": "BookAppointment",
"slots": {
"CustomerAgreement": null,
"DropLocationPrompt": "yes",
"PickupAddress": "Unnamed Road, Industrial Area, Sector 74, Sahibzada Ajit Singh Nagar, Punjab 140308, India",
"RequiredService": null,
"AppointmentTime": null,
"DropAddress": null,
"PhoneNumber": null,
"AppointmentDate": "2018-05-28"
},
"slotDetails": {
"CustomerAgreement": {
"resolutions": [],
"originalValue": null
},
"DropLocationPrompt": {
"resolutions": [
{
"value": "yes"
}
],
"originalValue": "yes"
},
"PickupAddress": {
"resolutions": [],
"originalValue": "Unnamed Road, Industrial Area, Sector 74, Sahibzada Ajit Singh Nagar, Punjab 140308, India"
},
"RequiredService": {
"resolutions": [],
"originalValue": null
},
"AppointmentTime": {
"resolutions": [
{
"value": "00:00"
},
{
"value": "12:00"
}
],
"originalValue": "14:00:00"
},
"DropAddress": {
"resolutions": [],
"originalValue": null
},
"PhoneNumber": {
"resolutions": [],
"originalValue": null
},
"AppointmentDate": {
"resolutions": [],
"originalValue": "28 may"
}
},
"confirmationStatus": "None"
},
"inputTranscript": "14:00:00"
}
Here is the request passed to the lex, see the AppointmentTime in the slots object, it is showing null and in the slotDetails object, it is showing value. Here is the array of buttons which i pass from the response card object:
[ { text: '1:00 PM', value: '13:00:00' },
{ text: '1:30 PM', value: '13:30:00' },
{ text: '2:00 PM', value: '14:00:00' },
{ text: '2:30 PM', value: '14:30:00' },
{ text: '3:00 PM', value: '15:00:00' },
{ text: '3:30 PM', value: '15:30:00' },
{ text: '4:00 PM', value: '16:00:00' },
{ text: '4:30 PM', value: '16:30:00' },
{ text: '5:00 PM', value: '17:00:00' },
{ text: '5:30 PM', value: '17:30:00' },
{ text: '6:00 PM', value: '18:00:00' },
{ text: '6:30 PM', value: '18:30:00' } ]
Here is the function of buildResponseCard:
function buildResponseCard(title, subTitle, options){
let buttons = null;
console.log(options);
let genericAttachments = [];
if (options != null){
buttons = [];
for(let i = 0; i < (options.length); i++){
buttons.push(options[i]);
if(i%3 === 2){
genericAttachments.push({
title,
subTitle,
buttons
});
buttons = [];
}
}
}
return {
version: 1,
contentType: "application/vnd.amazonaws.card.generic",
genericAttachments
};
}
The reason I want AppointmentTime slot value on slot object to be shown on is that whenever the value in the slot is invalid through validation, I will set it to null and will callback it through lambda function and i will not be able to callback the slotDetails object in the response.
Can anyone tell me how can i achieve this?
For the AMAZON.TIME built-in slot:
When a user enters an ambiguous time, Amazon Lex uses the slotDetails attribute of a Lambda event to pass resolutions for the ambiguous times to your Lambda function. ... In this case, the value in the slots map is null, and the slotDetails entity contains the two possible resolutions of the time.
Your input of "14:00:00" is not understood as an unambiguous time, and Lex tries to resolve it to either noon or midnight, which is obviously wrong. This is probably because the Lex Time slot is expecting only hours and minutes (hh:mm) but not seconds (hh:mm:ss).
So if it is possible for you, one solution is to remove the seconds digits from your time values. For example:
[ { text: '1:00 PM', value: '13:00' }, ... ]
However, if you must have the seconds in the time value, then you can simply find the time the user selected from the inputTranscript value and do your validation of it from there.
var userInput = event.inputTranscript;
EDIT:
Another option is to ignore Lex's suggested resolutions and get the slot-details original-value. Like this:
var timeValue = event.currentIntent.slotDetails.AppointmentTime.originalValue;
And then set the AppointmentTime slot yourself. Like this:
event.currentIntent.slots.AppointmentTime = timeValue;

Not able to get authorization on 2checkout

I am trying to authorize orders on the 2checkout sandbox, it was working fine but suddenly it stopped. Now I am always getting:
Payment Authorization Failed: Please verify your information and try
again, or try another payment method.
var tco = new Twocheckout({
sellerId: "1234456688", //on my code I am sending my true seller id
privateKey: "XXXXXXX-XXXXXX-XXXXXX", //on my code I am sending my key
sandbox: true
});
var plan = SubscriptionService.getPlan(req.body.plan);
if(plan) {
var params = {
"merchantOrderId": new Date().valueOf()+"",
"token": req.body.token,
"currency": "USD",
"tangible": "N",
"lineItems": [
{
"name": plan.name,
"price": plan.price,
"type": "product",
"quantity": "1",
"productId": plan.id,
"recurrence": "1 Month",
"duration": "Forever",
"description": ""
}],
"billingAddr": {
"name": req.body.ccName,
"addrLine1": req.body.streetAddress,
"city": req.body.city,
"state": req.body.state,
"zipCode": req.body.zip,
"country": req.body.country,
"email": req.user.email,
"phoneNumber": "5555555555"
}
};
tco.checkout.authorize(params, function (error, data) {
if (error) {
res.send(error);
} else {
res.send(data.response);
}
});
}
}
this is the example of a json I am sending
{ merchantOrderId: '1494967223074',
token: 'ZTFiNmFkMjktZWNmMi00NjlhLWE0MDAtZmJkMGJlYjU5M2Q1',
currency: 'USD',
tangible: 'N',
lineItems:
[ { name: 'pro plan',
price: '149.00',
type: 'product',
quantity: '1',
productId: '002',
recurrence: '1 Month',
duration: 'Forever',
description: '' } ],
billingAddr:
{ name: 'Testing Tester',
addrLine1: '123 Main Street',
city: 'Townsville',
state: 'ohio',
zipCode: '43206',
country: 'USA',
email: 'victor.eloy#landmarkwebteam.com',
phoneNumber: '55555555' } }
If I go to my account >> site management and set demo to true I manage to get authorizations from the sandbox but the orders do not get logged to the sandbox. Previously even when the demo mode was off I managed to get the orders authorized but now I don't know what is happening.
here comes a log from one order:
I have the exact same problem. Just 4 days ago the code was working fine. I'm assuming it's something from 2checkout not from our code..
Only thing I can see is you are attempting to parse
"zipCode": req.body.zip
but you are sending
zipCode: '43206'
I assume this should be parsed as req.body.zipCode

Mongoose Mixed type field not getting populated

I have a json doc that has embedded document which is variable (but in json format). So I use Mixed Schema type.
When I save, everything works fine except the mixed type object doesn't get populated and won't save.
What am I doing wrong here ?
Updating --> What I mean is - everything works as expected except the data node (which is suppose to be of mixed type)
My Document Example:
{
"data": {
"user_name": "username",
"cart_items": [
{
"sku": "ABCD",
"msrp": 1250.25,
"discount": 10,
"final_price": 112.22
},
{
"sku": "PQRSDF",
"msrp": 12.25,
"discount": 10,
"final_price": 1.2
}
]
},
"template_id": "1",
"from": "x#gmail.com",
"send_status": 0,
"priority": 99,
"app_id": "app3",
"_id": "532a54aa1c76fba0874c48ea",
"bcc": [],
"cc": [],
"to": [
{
"name": "acv",
"email": "x#outlook.com"
},
{
"name": "pem",
"email": "y#gmail.com"
}
],
"call_details": {
"data_id": "01234",
"event_id": 25
}
}
code to insert:
Schema definition:
app_id : { type: String, trim: true },
priority: { type: Number},
send_status: { type: Number},
call_details : {
event_id : { type: Number},
data_id : { type: String, trim: true },
id : false
},
from : { type: String, trim: true },
to : [addressSchema],
cc : [addressSchema],
bcc : [addressSchema],
template_id : { type: String, trim: true },
data: { any: {} }
Code:
r.app_id = req.body.app_id;
r.priority= req.body.priority;
r.send_status= req.body.send_status;
r.call_details.event_id= req.body.call_details.event_id;
r.call_details.data_id= req.body.call_details.data_id;
r.from= req.body.from;
r.to = populate_address(req.body.to);
r.cc = populate_address(req.body.cc);
r.bcc = populate_address(req.body.bcc);
r.template_id= req.body.template_id;
r.data =req.body.data);
r.markModified('data');
r.save(function (err){
console.log("add");
res.send ("added");
});
As you currently define your schema, it will only save the any field within data.
Remove the any embedded field from the definition for data in your schema.
So instead of:
data: { any: {} }
Use:
data: {}
As mongoose does not handle the embedded document save automatically. You need to save the embedded document first and assign the object ID to the parent schema as reference.

Resources