How to get a link from from feed-watcher updates - node.js

I'm trying to build medium integration so when I new post arrives on medium, bot will then send the post link to the discord channel. The Problem is I don't know how to take data from the feed response so I can use it in the message. Once I receive the response from the feed, it looks like this.
{
title: 'Hopefully will be done soon',
description: '<p>Still making final testing!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3d067e89b091" width="1" height="1" alt="">',
summary: null,
date: 2021-09-12T01:26:33.000Z,
pubdate: 2021-09-12T01:26:33.000Z,
pubDate: 2021-09-12T01:26:33.000Z,
link: 'https://rasmont.medium.com/hopefully-will-be-done-soon-3d067e89b091?source=rss-762047c9bd39------2',
guid: 'https://medium.com/p/3d067e89b091',
author: 'RasmonT',
comments: null,
origlink: null,
image: {},
source: {},
categories: [],
enclosures: [],
'rss:#': {},
'rss:title': { '#': {}, '#': 'Hopefully will be done soon' },
'rss:link': {
'#': {},
'#': 'https://rasmont.medium.com/hopefully-will-be-done-soon-3d067e89b091?source=rss-762047c9bd39------2'
},
'rss:guid': { '#': [Object], '#': 'https://medium.com/p/3d067e89b091' },
'dc:creator': { '#': {}, '#': 'RasmonT' },
'rss:pubdate': { '#': {}, '#': 'Sun, 12 Sep 2021 01:26:33 GMT' },
'atom:updated': { '#': {}, '#': '2021-09-12T01:26:33.080Z' },
'content:encoded': {
'#': {},
'#': '<p>Still making final testing!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3d067e89b091" width="1" height="1" alt="">'
},
meta: {
'#ns': [Array],
'#': [Array],
'#xml': [Object],
'#type': 'rss',
'#version': '2.0',
title: 'Stories by RasmonT on Medium',
description: 'Stories by RasmonT on Medium',
date: 2021-09-12T01:39:23.000Z,
pubdate: 2021-09-12T01:39:23.000Z,
pubDate: 2021-09-12T01:39:23.000Z,
link: 'https://medium.com/#rasmont?source=rss-762047c9bd39------2',
xmlurl: 'https://medium.com/#rasmont/feed',
xmlUrl: 'https://medium.com/#rasmont/feed',
author: 'yourfriends#medium.com',
language: null,
favicon: null,
copyright: null,
generator: 'Medium',
cloud: [Object],
image: [Object],
categories: [],
'rss:#': {},
'rss:title': [Object],
'rss:description': [Object],
'rss:link': [Object],
'rss:image': [Object],
'rss:generator': [Object],
'rss:lastbuilddate': [Object],
'atom:link': [Array],
'rss:webmaster': [Object]
}
},
I tried to parse response so I can take the link from the response like this.
const link = JSON.parse(entry)
console.log('FEED Call response:', link["link"]);
client.on('ready', () => {
watcher.on('new entries', function (entries) {
entries.forEach(function (entry) {
const link = JSON.parse(entry)
console.log('FEED Call response:', link["link"]);
console.log(entry)
})
})
watcher
.start()
.then(function (entries) {
console.log(entries)
})
.catch(function(error) {
console.error(error)
})
})
Any idea how can I receive the data I want from the response so I can use it in the message?
Error: SyntaxError: Unexpected token o in JSON at position 1
I tried to use this, however I don't know how to get the link from the response.
const link = JSON.stringify(entries)
console.log('FEED Call response:', link);
console.log(`Link:`, link[0].link)
Reponse is Link: [Function: link]

You do not have to use JSON.parse at all! The received data is already the object you want. JSON.parse automatically sets its first argument as a string, and that makes it change to the following string:
"[object Object]"
JSON allows the [ but not the o without a quotation mark. The following code will work just fine.
entries.forEach((entry) => {
console.log('FEED Call response:', entry);
console.log(entry[0].link)
})

I found a solution! First we need to stringify data and then parse them to JSON, right after i can pick link from the first array.
const stringifylink = JSON.stringify(entry)
const link = JSON.parse(stringifylink)
console.log('FEED Call response:', link);
console.log('Link:', link[0].link)

Related

how to iterate json with parentheses

I have an api that is returning a json data but that data is wrapped in curly brackets and I am not able to iterate the response. I tried to convert that into string, sliced the brackets and then tries t o convert that back into json but that didn''t work as expected.
The response I receive is below
{
data: [
{ id: 'Price', result: [Object], errors: [] },
{ id: 'rsi', result: [Object], errors: [] },
{ id: 'ema14', result: [Object], errors: [] },
{ id: 'ema24', result: [Object], errors: [] },
{ id: 'ema55', result: [Object], errors: [] },
{ id: 'ema100', result: [Object], errors: [] },
{ id: 'ema200', result: [Object], errors: [] }
]
}
The below is what I tried and facing error
.then( response => {
var string = JSON.stringify(response.data)
var objectstr = string.slice(1,-1)
let objectJson = json.parse(objectstr)
console.log(response.data);
})
without converting it into json response.data[0] gives undefined. if I convert that into string and remove the brackets it doesn't parse that string back into JSON.
ReferenceError: json is not defined
at D:\Crypto\API Learning\Api.js:63:22
at processTicksAndRejections (node:internal/process/task_queues:96:5)
What I want is to get data from response.data as response.data[0].id
there is no need to remove parenthesis, and you are using lower case of JSON.parse here ..let objectJson = json.parse(objectstr).
Try below code assuming that response contains plain object:
var response= {
data: [
{ id: 'Price', result: [Object], errors: [] },
{ id: 'rsi', result: [Object], errors: [] },
{ id: 'ema14', result: [Object], errors: [] },
{ id: 'ema24', result: [Object], errors: [] },
{ id: 'ema55', result: [Object], errors: [] },
{ id: 'ema100', result: [Object], errors: [] },
{ id: 'ema200', result: [Object], errors: [] }
]
};
var string = JSON.stringify(response)
let objectJson = JSON.parse(string)
console.log(objectJson.data); // here you can iterate over data array.

console.log returns "Object" for some fields, instead of body data [spotify-web-api-node]

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.)

List of Maps returns undefined in DynamoDB query

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.

Obtaining activityID from a Choice Prompt in a Waterfall Dialog - Microsoft Bot Framework - Node.js [duplicate]

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

How to understand node-soap "describe" function?

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.

Resources