I'm building a content middleware which gather contents from our external publishers. The publishers will share their contents either in rss or json and the key/value field would be different from each other. To make thing easier, I created a config file where I can pre-defined the key/value and the feed type. The problem is, how can I dynamically return this config value based on publishers name.
Example: To get Publisher #1 feed type, I just can use config.articles.rojak_daily.url_feed
my config file /config/index.js
module.exports = {
batch:100,
mysql: {
database: process.env.database,
host: process.env.host,
username: process.env.username,
password: process.env.password
},
articles:{
rojak_daily:{ // Publisher 1
url: 'xxx',
url_feed: 'rss',
id: null,
Name: 'title',
Description: 'description',
Link: 'link',
DatePublishFrom: 'pubDate',
LandscapeImage: 's3image',
SiteName: 'Rojak Daily',
SiteLogo: null
},
rojak_weekly:{ // publisher 2
url: 'xxx',
url_feed: 'json',
id: null,
Name: 'Name',
Description: 'Desc',
Link: 'link',
DatePublishFrom: 'pubDate',
LandscapeImage: 's3image',
SiteName: 'Rojak Weekly',
SiteLogo: null
}
}
}
my main application script
const config = require('#config'); // export from config file
class Main {
constructor(){
this.publishers = ['rojak_daily','rojak_weekly'];
}
// Main process
async startExport(){
try{
for(let publisher of this.publishers){
const feedType = await this.getFeedType(publisher)
const result = (feedType == 'rss')? await this.rss.start(publisher): await this.json.start(publisher)
return result
}
}catch(err){
console.log("Error occured: ", err)
}
}
// Get feed type from config
async getFeedType(publisher){
return await config.articles.rojak_daily.url_feed;
// this only return publisher 1 url feed.
// my concern is to dynamically passing variable
// into this config file (example: config.articles.<publisher>.url_feed)
}
}
module.exports = Main
async getFeedType(publisher){
return await config.articles[publisher].url_feed;
}
You can access properties of objects by variable
You could either loop over the articles by using Object.entries(articles) or Object.values(articles) in conjunction with Array.prototype.forEach(), or since you already have the name of the publisher you could access that entry with config.articles[publisher].url_feed, like so:
const config = {
articles: {
rojak_daily: { // Publisher 1
url: 'xxx',
url_feed: 'rss',
id: null,
Name: 'title',
Description: 'description',
Link: 'link',
DatePublishFrom: 'pubDate',
LandscapeImage: 's3image',
SiteName: 'Rojak Daily',
SiteLogo: null
},
rojak_weekly: { // publisher 2
url: 'xxx',
url_feed: 'json',
id: null,
Name: 'Name',
Description: 'Desc',
Link: 'link',
DatePublishFrom: 'pubDate',
LandscapeImage: 's3image',
SiteName: 'Rojak Weekly',
SiteLogo: null
}
}
}
const publishers = ['rojak_daily', 'rojak_weekly']
function getFeedType(publisher) {
return config.articles[publisher].url_feed;
}
publishers.forEach(publisher => console.log(getFeedType(publisher)));
Related
Hello guys,
I have a question
I try to smart contract functions from erc.json standarts with JavaScript. To example: I need a random number function with metamask user address(account number) referance for backend
To basicly:
Example JSON values:
{
inputs: [{ internalType: 'address', name: 'UserKey', type: 'address' }],
name: 'RandomNumber',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
Example smart contract function:
const daiToken = new web3.eth.Contract(
ContractABI, // ABI
address, // Sender address
chainId
)
daiToken.methods
.RandomNumber(address)
.call(ContractABI)
.then(function (result) {
console.log(result)
})
.catch(function (err) {
console.log(err, 'err')
})
And here is the console prints:
i hope i explained :)
and happy weekends..
(updated new error)
Are you tried to change <React.StrictMode><App /><React.StrictMode> to <App /> in your index.js file?
I am having the following response; how can I verify its been created by having a response contains userid ?
({
id: '612bd3f42ca01806398da144',
data: Object({
createdOn: '2021-08-29T18:37:39.693Z',
lastUpdatedBy: null,
userId: '60f469cf784379051298e96d',
displayName: 'Nadia',
postText: null,
postImages: [],
pluginInstance: Object({
pluginInstanceId: '1627334094776-047554258642281355',
pluginInstanceTitle: 'communityFeedPlugin'
}),
isPublic: false,
_buildfire: Object({
index: Object({
array1: [Object({
string1: 'userId_60f469cf784379051298e96d'
}), Object({
string1: 'displayName_nadia'
}), Object({
string1: 'pluginTitle_communityfeedplugin'
}), Object({
string1: 'isPublic_0'
})]
})
})
}),
tag: 'posts'
})
If you use express rest api you can use like this.
const exists = await posts.findOne({ "data.userid": userid });
if(exists) {
return res.json({ success: false, message: "User already exists"})
}
If I get it right, you need to know if the userId property is present/truthy.
Given that the response is stored in a jsonBody variable, use an if statement like so:
if (jsonBody.data.userId) {
...
}
Also, make sure the response is parsed in JSON properly, so that you can navigate it.
If you need to know whether the response exists in the first place or not, you can add another if check:
if (jsonBody) {
...
if (jsonBody.data.userId) {...}
...
}
Or join both checks in one if statement:
if (jsonBody && jsonBody.data.userId) {...}
Anyways, it's good practice to consume backends that comunicate correctly the request status, so that you can write cleaner code avoiding this types of checks and relying on status codes for the most part.
worked in this form :
it('Add public post with post image and text', function(done) {
Posts.addPost({isPublic : true , postImages :'image test',postText : 'post text sample'},(err,resp) => {
expect(resp.data).toEqual(jasmine.objectContaining({
postImages: 'image test',
postText:'post text sample',
userId: authManager.currentUser._id,
isPublic: true
}));
done();
});
});
I am trying to develop an API to upload the intent to Dialogflow V2. I have tried below snippet, which it is not working however if trying to communicate with Dialogflow it does work (detect intent)and does get a reply from the Dialogflow for queries.
PERMISSION
I AM & ADMIN > SERVICE ACCOUNTS > DIALOGFLOW ADMIN
ERROR
Error: 7 PERMISSION_DENIED: IAM permission 'dialogflow.entityTypes.create' on 'projects/dexter-47332/agent' denied.
BLOGS/ REFERENCES
Dialogflow easy way for authorization
https://github.com/dialogflow/dialogflow-nodejs-client-v2/blob/master/samples/resource.js#L26
https://www.npmjs.com/package/dialogflow
https://developers.google.com/apis-explorer/
https://cloud.google.com/docs/authentication/production
//------- keys.json (test 1)
{
"type": "service_account",
"project_id": "mybot",
"private_key_id": "123456asd",
"private_key": "YOURKEY",
"client_email": "yourID#mybot.iam.gserviceaccount.com",
"client_id": "098091234",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/yourID%40mybot.iam.gserviceaccount.com"
}
//--------------------- ** (test 2) ** ---------
let privateKey = 'key';
let clientEmail = "email";
let config = {
credentials: {
private_key: privateKey,
client_email: clientEmail
}
}
function createEntityTypes(projectId) {
// [START dialogflow_create_entity]
// Imports the Dialogflow library
const dialogflow = require('dialogflow');
// ******** Instantiates clients (Test 1)********
const entityTypesClient = new dialogflow.EntityTypesClient({
'keyFilename': './keys.json'
});
const intentsClient = new dialogflow.IntentsClient({
'keyFilename': './keys.json'
});
// ******** Instantiates clients (Test 2)********
const entityTypesClient = new dialogflow.EntityTypesClient(config);
const intentsClient = new dialogflow.IntentsClient(config);
// The path to the agent the created entity type belongs to.
const agentPath = intentsClient.projectAgentPath(projectId);
const promises = [];
// Create an entity type named "size", with possible values of small, medium
// and large and some synonyms.
const sizeRequest = {
parent: agentPath,
entityType: {
displayName: 'test',
kind: 'KIND_MAP',
autoExpansionMode: 'AUTO_EXPANSION_MODE_UNSPECIFIED',
entities: [{
value: 'small',
synonyms: ['small', 'petit']
},
{
value: 'medium',
synonyms: ['medium']
},
{
value: 'large',
synonyms: ['large', 'big']
},
],
},
};
promises.push(
entityTypesClient
.createEntityType(sizeRequest)
.then(responses => {
console.log('Created size entity type:');
logEntityType(responses[0]);
})
.catch(err => {
console.error('Failed to create size entity type ----->:', err);
})
);
}
createEntityTypes(projectId);
You can use JWT(JSON Web Tokens) for authenticating with service accounts like in this example
const serviceAccount = { }; // JSON key contents {"type": "service_account",...
const serviceAccountAuth = new google.auth.JWT({
email: serviceAccount.client_email,
key: serviceAccount.private_key,
scopes: 'https://www.googleapis.com/auth/calendar'
});
For more OAuth2.0 scopes for Google APIs you can see the full list here.
I encountered the same error. I corrected it by deleting the current service account and creating a new one and selected the "owner" option for the role.
The associated service-account has to have the role "Dialogflow API Admin" to be able to create intents and entities.
I think you must provide a name parameter there in the sizeRequest and make it equal to an empty string.
Take a look at the code snippet.
let request = {
parent: `projects/${PROJECID}/agent`,
entityType: {
name: '',
autoExpansionMode: 'AUTO_EXPANSION_MODE_DEFAULT',
displayName: 'size_type',
enableFuzzyExtraction: false,
entities: [
{
value: 'Big',
synonyms: ['big', 'large', 'huge']
},
{
value: 'Medium',
synonyms: ['medium', 'not big']
}
],
kind: 'KIND_MAP'
},
languageCode: 'en'
};
Please let me know if this helps.
I'm fairly new to KeystoneJS and struggle with pre-populating a database through seeds / updates. I have no problem with independent properties but struggle with properties with relationships.
I have for example a Location Model that includes photos.
var Location = new keystone.List('Location', {
sortable: true,
autokey: {
path: 'slug',
from: 'name',
unique: true
}
});
Location.add({
name: {
type: Types.Text,
required: true,
initial: true
},
photos: {
type: Types.Relationship,
ref: 'Photo',
many: true
}
}
and the Photo Model is as such:
var Photo = new keystone.List('Photo', {
autokey: {
path: 'slug',
from: 'title',
unique: true
}
});
Photo.add({
title: {
type: Types.Text,
initial: true,
index: true
},
image: {
type: Types.CloudinaryImage,
required: true,
initial: false
}
});
Photo.relationship({
ref: 'Location',
path: 'photos',
refPath: 'photos'
});
Within the update folder I'm trying to seed the database with pre-loaded data. Both Location and Photo models get populated individually but I am failing to pre-populate the relationship within both within the Admin UI and lacks knowledge on how to solve. I did quite some research, tried different things such as using __ref and _ids but couldn't make it work. I could not find the answer within the KeystoneJS documentation either. Maybe there is something obvious that I'm actually missing.
exports.create = {
Location: [
{
name: 'London',
photos: [
// <-- how to do it here?
]
},
{
name: 'New York',
photos: [
// <-- how to do it here?
]
}
]
};
Would anyone know the right way to pre-populate KeystoneJs database relationships? Thank you very much.
I managed to solve by mapping through the photos and replace by the actual photo found by title. Here is how I did in case it can help someone else:
exports = module.exports = function (next) {
Promise.all([
{
name: 'London',
photos: ['london_1', 'london_2']
},
{
name: 'New York',
photos: ['new_york_1', 'new_york_2']
}
].map(function (location) {
var _photos = location.photos || [];
location.photos = [];
return Promise.all([
_photos.map(function (title) {
return Photo.model.findOne({ title: title })
.then(function (photo) {
location.photos.push(photo);
});
})
])
.then(function () {
new Location.model(location).save();
});
}))
.then(function () {
next();
})
.catch(next);
};
Let's suppose I have two simple fixture files, one for the user(1) and one for the messages(2).
The Backbone Model for the messages is the following (3).
If I load the "Message Fixture", I would like to have also the related info regarding the user as specified in Message Model.
What is the proper way to active this goal in a spec view (4) by using jasmine test suite?
Please see the comments in (4) for more details.
(1)
// User Fixture
beforeEach(function () {
this.fixtures = _.extend(this.fixtures || {}, {
Users: {
valid: {
status: 'OK',
version: '1.0',
response: {
users: [
{
id: 1,
name: 'olivier'
},
{
id: 2,
name: 'pierre',
},
{
id: 3,
name: 'george'
}
]
}
}
}
});
});
(2)
// Message Fixture
beforeEach(function () {
this.fixtures = _.extend(this.fixtures || {}, {
Messages: {
valid: {
status: 'OK',
version: '1.0',
response: {
messages: [
{
sender_id: 1,
recipient_id: 2,
id: 1,
message: "Est inventore aliquam ipsa"
},
{
sender_id: 3,
recipient_id: 2,
id: 2,
message: "Et omnis quo perspiciatis qui"
}
]
}
}
}
});
});
(3)
// Message model
MessageModel = Backbone.RelationalModel.extend({
relations: [
{
type: Backbone.HasOne,
key: 'recipient_user',
keySource: 'recipient_id',
keyDestination: 'recipient_user',
relatedModel: UserModel
},
{
type: Backbone.HasOne,
key: 'sender_user',
keySource: 'sender_id',
keyDestination: 'sender_user',
relatedModel: UserModel
}
]
});
(4)
// Spec View
describe('MyView Spec', function () {
describe('when fetching model from server', function () {
beforeEach(function () {
this.fixture = this.fixtures.Messages.valid;
this.fixtureResponse = this.fixture.response.messages[0];
this.server = sinon.fakeServer.create();
this.server.respondWith(
'GET',
// some url
JSON.stringify(this.fixtureResponse)
);
});
it('should the recipient_user be defined', function () {
this.model.fetch();
this.server.respond();
// this.fixtureResponse.recipient_user is not defined
// as expected by the relation defined in (3)
expect(this.fixtureResponse.recipient_user).toBeDefined();
});
});
});
});
Take a look at this series of tutorials http://tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html
This is the specific part about Model testing.
Don't know if will solve your problem, but may contain precious info.
this.fixtureResponse is the source data for the model, but when the model is actually created it makes a copy of that data to an internal property. So, when Backbone Relational resolves the relation, it shouldn't change the source data object.
Did you tried with expect(this.model.get('recipient_user')).toBeDefined()?
Backbone-Relational provides the ability to either create a related model from nested entities within JSON retrieved via the model's fetch or to lazily load related models using fetchRelated.
You're providing Backbone-Relational with the message model data but no way to retrieve the user model data. You could add another response returning the appropriate related user data and call fetchRelated on the message model.
Alternatively inline the user data into the message response and the user model will be created automatically and added as a relation on the message model.