I'm attempting to use the node SOAP npm module(https://github.com/vpulim/node-soap) service.
var soap = require('soap');
var soapWSDL = "https://webservice.s7.exacttarget.com/etframework.wsdl";
soap.createClient(soapWSDL, function (err, client) {
if (err) {
return callback(err, null);
}
client.setSecurity(new soap.WSSecurity(self.username, self.password));
console.log("describe", client.describe());
console.log("retrieve", client.describe().PartnerAPI.Soap.Retrieve);
});
The first log shows the available methods...
But i'm trying to understand the exact format required for params from the second console.log...
More specifically, when i call client.Retrieve(options,function(e,r){}); what is the required format of options supposed to be?
Here is the output from the two console.logs
Describe:
{ PartnerAPI:
{ Soap:
{ Create: [Object],
Retrieve: [Object],
Update: [Object],
Delete: [Object],
Query: [Object],
Describe: [Object],
Execute: [Object],
Perform: [Object],
Configure: [Object],
Schedule: [Object],
VersionInfo: [Object],
Extract: [Object],
GetSystemStatus: [Object] } } }
Retrieve:
{ input:
{ RetrieveRequest:
{ 'ClientIDs[]': [Object],
ObjectType: 'xsd:string',
'Properties[]': 'xsd:string',
Filter: [Object],
'RespondTo[]': [Object],
'PartnerProperties[]': [Object],
ContinueRequest: 'xsd:string',
QueryAllAccounts: 'xsd:boolean',
RetrieveAllSinceLastBatch: 'xsd:boolean',
RepeatLastResult: 'xsd:boolean',
Retrieves: [Object],
Options: [Object],
targetNSAlias: 'tns',
targetNamespace: 'http://exacttarget.com/wsdl/partnerAPI' } },
output:
{ OverallStatus: 'xsd:string',
RequestID: 'xsd:string',
'Results[]':
{ Client: [Object],
PartnerKey: 'xsd:string',
'PartnerProperties[]': [Object],
CreatedDate: 'xsd:dateTime',
ModifiedDate: 'xsd:dateTime',
ID: 'xsd:int',
ObjectID: 'xsd:string',
CustomerKey: 'xsd:string',
Owner: [Object],
CorrelationID: 'xsd:string',
ObjectState: 'xsd:string',
targetNSAlias: 'tns',
targetNamespace: 'http://exacttarget.com/wsdl/partnerAPI' } } }
In this example you should be looking at the key names and formats. For example any key with a [] at the end means this should be a SOAP Sequence. Without seeing the entire format of the input / output I can't be 100% certain on some - you could try using Node.js' util function to get a deep inspect of the object.
For example:
var utils = require('utils');
/* later */
console.log( utils.inspect( testObject, {depth: null} ) );
To answer your question as much as I can:
var args = {
ClientIDs: [{ /* Some object - not sure without inspect */ }],
ObjectType: 'someString',
Properties: ['someString', 'someString'],
Filter: { /* Some object - not sure without inspect */ },
RespondTo: [{ /* Some object - not sure without inspect */ }],
PartnerProperties: [{ /* Some object - not sure without inspect */ }],
ContinueRequest: 'someString',
QueryAllAccounts: true, /* or false */
RetrieveAllSinceLastBatch: true, /* or false */
RepeatLastResult: true, /* or false */
Retrieves: [{ /* Some object - not sure without inspect */ }],
Options: [{ /* Some object - not sure without inspect */ }]
}
client.RetrieveRequest(args, function(err, result, raw, soapHeader) {
/* do something with the result */
});
You can use JSON.stringify options to look at the details of the output you are getting from client.describe(). It will show you all the parameters in .json format.
Related
I'm using the spotify-web-api-node and when I do api calls, the returned data looks like that in the console:
Album information {
album_type: 'album',
artists: [
{
external_urls: [Object],
href: 'https://api.spotify.com/v1/artists/2hazSY4Ef3aB9ATXW7F5w3',
id: '2hazSY4Ef3aB9ATXW7F5w3',
name: 'IZAL',
type: 'artist',
uri: 'spotify:artist:2hazSY4Ef3aB9ATXW7F5w3'
}
],
...
label: 'Hook Ediciones Musicales',
name: 'Agujeros de Gusano',
popularity: 0,
release_date: '2014-01-25',
release_date_precision: 'day',
total_tracks: 13,
tracks: {
offset=0&limit=50',
items: [
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object]
],
limit: 50,
next: null,
offset: 0,
previous: null,
total: 13
},
type: 'album',
uri: 'spotify:album:5U4W9E5WsYb2jUQWePT8Xm'
}
As you can see, some fields like external_urls: and (later) items: have [Object] returned, instead of the actual data.
The (node.js) code for that particular example is the following:
spotifyApi.getAlbum('5U4W9E5WsYb2jUQWePT8Xm')
.then(function(data) {
console.log('Album information',data.body);
}, function(err) {
console.error(err);
});
If I change the data.body part in console.log to JSON.stringify(data.body) it is somewhat better, as it does return the data, but as a string (obviously), which not exactly... useable:
Album information {"album_type":"album","artists":[{"external_urls":{"spotify":"https://open.spotify.com/artist/2hazSY4Ef3aB9ATXW7F5w3"},"href":"https://api.spotify.com/v1/artists/2hazSY4Ef3aB9ATXW7F5w3","id":"2hazSY4Ef3aB9ATXW7F5w3","name":"IZAL","type":"artist","uri":"spotify:artist:2hazSY4Ef3aB9ATXW7F5w3"}],"available_markets":[],"copyrights":[{"text":"2013 Hook Ediciones Musicales","type":"C"},{"text":"2013 Hook Ediciones Musicales","type":"P"}],
etc etc. Also tried JSON.parse(JSON.stringify(data.body)) but I get the same output as with console.log.
How can I get the field's actual data, without losing its format?
You can use console.log(JSON.stringify(data.body, null, 2)).
That prints JSON in tree without losing its content like you see in [Object].
Following #snak 's comment, I changed the console.log line to:
console.log('Album information',util.inspect(data.body, false, null, true));
and it seems to return everything fine, no [Object].
(Make sure to include const util = require('util'); and install it with npm install util --save.)
I am querying a DynamoDB. It has an attribute called 'Multiple Units' with the following structure: List [ Map { Map { S }, S }, ... ]
I test a lambda locally:
module.exports.getByAddress = async (event) => {
const params = {
TableName: process.env.tableName,
Key: {
Address: event.pathParameters.address
}
};
var docClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
docClient.get(params).promise().then(
returnResult => console.log(returnResult)
)
}
This is the output:
Item: {
...
license: '',
Coordinates: { lng: '-71.075985', lat: '42.346096' },
'Multiple Units': [ [Object], [Object], [Object], [Object], [Object], [Object] ],
...
}
When I attempt to console.log Multiple Units list specifically, I get undefined.
In reading about DynamoDB get/getItem, I am guessing it has to do with async but I cannot configure a change that will result in correct output.
Based on your comment, you mention that you're getting undefined when you execute console.log(returnResult['Multiple Units']).
Take a closer look at what console.log(returnResult) is printing:
Item: {
...
license: '',
Coordinates: { lng: '-71.075985', lat: '42.346096' },
'Multiple Units': [ [Object], [Object], [Object], [Object], [Object], [Object] ],
...
}
Notice that it's printing a map with the key of Item. Therefore, to get at your data, try to console.log(returnResult.Item['Multiple Units'])
You can check out the DynamoDB SDK API for more info regarding the result of a get call.
This question already has answers here:
Can we add text field dynamically
(2 answers)
Closed 2 years ago.
I'm having a problem retrieving the activityID of a Choice prompt once the selection has been made within a waterfall dialog. Im currently making use of a Teams channel.
An example my code can be found below. In the step after the selection, if I have a look at the stepContext object(found further below), there is reference of an Activity.id, but this id is infact the Activity id for the current step. I'm sure I'm missing something simple, but cant figure it out.
async step1(step) {
const choice1 = await step.prompt(CHOICE_PROMPT, {
prompt: 'Please select one of the following:',
choices: ChoiceFactory.toChoices(['Option1', 'Option2', 'Option3'])
});
return choice1
}
async step2(step) {
console.log(step)
console.log("...........................................................................")
return await step.prompt(NAME_PROMPT, 'Please insert your name')
}
WaterfallStepContext {
dialogs:
DialogSet {
dialogs:
{ NAME_PROMPT: [Object],
CHOICE_PROMPT: [Object],
CONFIRM_PROMPT: [Object],
ATTACHMENT_PROMPT: [Object],
WATERFALL_DIALOG: [Object] },
dialogState: undefined },
context:
TurnContext {
_respondedRef: { responded: false },
_turnState:
Map {
Symbol(BotIdentity) => [Object],
Symbol(ConnectorClient) => [Object],
Symbol(OAuthScope) => 'https://api.botframework.com',
'botCallbackHandler' => [AsyncFunction],
Symbol(state) => [Object],
Symbol(ActivityReceivedEmitted) => true },
_onSendActivities: [],
_onUpdateActivity: [],
_onDeleteActivity: [],
bufferedReplyActivities: [],
_adapter:
BotFrameworkAdapter {
middleware: [Object],
BotIdentityKey: Symbol(BotIdentity),
OAuthScopeKey: Symbol(OAuthScope),
ConnectorClientKey: Symbol(ConnectorClient),
TokenApiClientCredentialsKey: Symbol(TokenApiClientCredentials),
settings: [Object],
credentials: [Object],
credentialsProvider: [Object],
isEmulatingOAuthCards: false,
authConfiguration: [Object],
turnError: [AsyncFunction] },
_activity:
{ text: 'Option1',
textFormat: 'plain',
type: 'message',
timestamp: 2020-05-05T13:32:42.187Z,
localTimestamp: 2020-05-05T13:32:42.187Z,
id: '1588685562137',
channelId: 'msteams',
serviceUrl: 'https://smba.trafficmanager.net/za/',
from: [Object],
conversation: [Object],
recipient: [Object],
entities: [Array],
channelData: [Object],
locale: 'en-US' } },
stack: [ { id: 'WATERFALL_DIALOG', state: [Object] } ],
state: DialogStateManager { dialogContext: [Circular] },
_info:
{ index: 1,
options: {},
reason: 'endCalled',
result: { value: 'Option1', index: 0, score: 1, synonym: 'Option1' },
values: { instanceId: 'b5bef7ce-1c43-e1db-abc0-651ed2b5bb8f' },
onNext: [Function: onNext] },
parent:
DialogContext {
dialogs: DialogSet { dialogs: [Object], dialogState: [Object] },
context:
TurnContext {
_respondedRef: [Object],
_turnState: [Object],
_onSendActivities: [],
_onUpdateActivity: [],
_onDeleteActivity: [],
bufferedReplyActivities: [],
_adapter: [Object],
_activity: [Object] },
stack: [ [Object] ],
You're not missing anything simple. This is actually sort of difficult to do because Microsoft Teams does not include any information about the button that sent an action to your bot.
In order to get the activity ID that an action came from, you have to save the ID in bot state on the turn that you send the activity. The ID can be found in the resource response returned by whichever method you use to send the activity. Unfortunately, this means you can't let the prompt send the card for you because then you wouldn't be able to access the resource response.
If you want to save more than one activity ID at a time, you'll need a way of knowing which one is associated with each incoming action. This means you'll have to include metadata in the actions you put in your cards and save that metadata along with the activity ID in your bot state.
If you'd like an easier or even an automatic way of doing all this, please voice your support for the cards library that I'm currently working on: https://github.com/BotBuilderCommunity/botbuilder-community-dotnet/issues/137
i have used a middleware called checktoken in every routes except login route in my code . when i hit login url it logged me in where there is to token checked. but now if i wish to go to any route after logging in it restricts me inside checkToken middleware.i have used jsonwebtoken module to generate token and verify it.but my code failed to find users.here is my checktoken middle ware code
if (token) {
try {
var decoded = jsonwebtoken.verify(token, jwt_key);
req.user = decoded.user;///
console.log(req.user._id);// i get id here and from this id i can find user in database
UserSchema.findOne({
_id: req.user._id
})///this query failed finding result
.exec(function(err, result) {
if (err) {
console.log(err);//error gets output in the console.
res.status(500);
return res.json({
result: err
});
}
if (result) {
return next();
} else {
res.status(400);
return res.json({
message: "The user does not exists"
});
}
});
} catch (err) {
res.status(403);
res.json({
message: "Invalid Token"
});
}
} else {
res.status(401);
res.json({
message: "No token provided"
});
}
the error message i get in console is
{ [CastError: Cast to ObjectId failed for value "5875d76e1df97635623061c5" at path "_id" for model "User"]
message: 'Cast to ObjectId failed for value "5875d76e1df97635623061c5" at path "_id" for model "User"',
name: 'CastError',
stringValue: '"5875d76e1df97635623061c5"',
kind: 'ObjectId',
value: '5875d76e1df97635623061c5',
path: '_id',
reason: undefined,
model:
{ [Function: model]
hooks: Kareem { _pres: {}, _posts: {} },
base:
Mongoose {
connections: [Object],
plugins: [],
models: [Object],
modelSchemas: [Object],
options: [Object] },
modelName: 'User',
model: [Function: model],
db:
NativeConnection {
base: [Object],
collections: [Object],
models: [Object],
config: [Object],
replica: false,
hosts: null,
host: 'localhost',
port: 27017,
user: undefined,
pass: undefined,
name: 'myschoolbus_demo',
options: [Object],
otherDbs: [],
_readyState: 1,
_closeCalled: false,
_hasOpened: true,
_listening: false,
db: [Object] },
discriminators: undefined,
schema:
Schema {
obj: [Object],
paths: [Object],
subpaths: {},
virtuals: [Object],
singleNestedPaths: {},
nested: [Object],
inherits: {},
callQueue: [Object],
_indexes: [],
methods: [Object],
statics: {},
tree: [Object],
_requiredpaths: undefined,
discriminatorMapping: undefined,
_indexedpaths: undefined,
query: {},
childSchemas: [],
s: [Object],
options: [Object],
'$globalPluginsApplied': true },
collection:
NativeCollection {
collection: [Object],
opts: [Object],
name: 'users',
collectionName: 'users',
conn: [Object],
queue: [],
buffer: false,
emitter: [Object] },
Query: { [Function] base: [Object] },
'$__insertMany': [Function],
insertMany: [Function] } }
i cannot figure out where i am wrong. any suggestions are highly appreciated.
Strip quotes from your id. Your error says:
stringValue: '"5875d76e1df97635623061c5"',
See the " at start and end? It's part of the string. I don't know if your middleware, or frontend or whoever puts it, so either strip it yourself or pass it before.
Try this:
UserSchema.findOne({
_id: req.user._id.replace(/"/g, '')
})
I'm trying to produce a lean record for a REST API that include virtual fields.
The official documentation for how to implement virtual fields for Mongoose:
http://mongoosejs.com/docs/guide.html
My model:
var keystone = require('keystone')
, Types = keystone.Field.Types
, list = new keystone.List('Vendors');
list.add({
name : {
first: {type : Types.Text}
, last: {type : Types.Text}
}
});
list.schema.virtual('name.full').get(function() {
return this.name.first + ' ' + this.name.last;
});
list.register();
Now, let's query the model:
var keystone = require('keystone'),
vendors = keystone.list('Vendors');
vendors.model.find()
.exec(function(err, doc){
console.log(doc)
});
Virtual field name.full is not here:
[ { _id: 563acf280f2b2dfd4f59bcf3,
__v: 0,
name: { first: 'Walter', last: 'White' } }]
But if we do this:
vendors.model.find()
.exec(function(err, doc){
console.log(doc.name.full); // "Walter White"
});
Then the virtual shows.
I guess the reason is that when I do a console.log(doc) the Mongoose document.toString() method is invoked which does not include virtuals by default. Fair enough. That's understandable.
To include the virtuals in any of the conversion methods you have to go:
doc.toString({virtuals: true})
doc.toObject({virtuals: true})
doc.toJSON({virtuals: true})
However, this includes keys I don't want for my REST API to pump out to my users:
{ _id: 563acf280f2b2dfd4f59bcf3,
__v: 0,
name: { first: 'Walter', last: 'White', full: 'Walter White' },
_: { name: { last: [Object], first: [Object] } },
list:
List {
options:
{ schema: [Object],
noedit: false,
nocreate: false,
nodelete: false,
autocreate: false,
sortable: false,
hidden: false,
track: false,
inherits: false,
searchFields: '__name__',
defaultSort: '__default__',
defaultColumns: '__name__',
label: 'Vendors' },
key: 'Vendors',
path: 'vendors',
schema:
Schema {
paths: [Object],
subpaths: {},
virtuals: [Object],
nested: [Object],
inherits: {},
callQueue: [],
_indexes: [],
methods: [Object],
statics: {},
tree: [Object],
_requiredpaths: [],
discriminatorMapping: undefined,
_indexedpaths: undefined,
options: [Object] },
schemaFields: [ [Object] ],
uiElements: [ [Object], [Object] ],
underscoreMethods: { name: [Object] },
fields: { 'name.first': [Object], 'name.last': [Object] },
fieldTypes: { text: true },
relationships: {},
mappings:
{ name: null,
createdBy: null,
createdOn: null,
modifiedBy: null,
modifiedOn: null },
model:
{ [Function: model]
base: [Object],
modelName: 'Vendors',
model: [Function: model],
db: [Object],
discriminators: undefined,
schema: [Object],
options: undefined,
collection: [Object] } },
id: '563acf280f2b2dfd4f59bcf3' }
I can always of course just delete the unwanted keys, but this doesn't seem quite right:
vendors.model.findOne()
.exec(function(err, doc){
var c = doc.toObject({virtuals: true});
delete c.list;
delete c._;
console.log(c)
});
This produces what I need:
{ _id: 563acf280f2b2dfd4f59bcf3,
__v: 0,
name: { first: 'Walter', last: 'White', full: 'Walter White' },
id: '563acf280f2b2dfd4f59bcf3' }
Is there not a better way of getting a lean record?
I think you want the select method.. something like this:
vendors.model.findOne()
.select('_id __v name').
.exec(function(err, doc){
console.log(c)
});
Also personally I prefer setting virtuals: true on the schema rather than the document, but depends on use case I guess.
One solution would be to use a module like Lodash (or Underscore) which allows you pick a whitelist of property names:
vendors.model.findOne()
.exec(function(err, doc){
var c = _.pick(doc, ['id', 'name.first', 'name.last', 'name.full']);
console.log(c)
});
Given your use-case of serving this data via REST API, I think explicitly defining a whitelist of property names is safer. You could even define a virtual property on your schema which returns the predefined whitelist:
list.schema.virtual('whitelist').get(function() {
return ['id', 'name.first', 'name.last', 'name.full'];
});
and use it in multiple places, or have different versions of your whitelist, all managed at the model layer.