stream.on('tweet') twitter Bot - node.js

i am facing a problem relating to twitter bot. i was simply trying to get the tweeets with '#topi' mentioned in their status and then send them a reply and also retweet the tweet.
this is how i expect to execute the bot.
wait for tweets
receives the tweet
write the tweet to a local file (just to examine)
reply the tweet with their user_id mentioned
retweet their tweet
wait for next tweet
but the problem i am facing is, up to replying and retweeting it's working well, but since it retweeted the received tweet with the same hashtag in the status it repeats the same procedure for the hashtag as before and receives 'duplicate content error'.
is there anything quick solution for this.
require("dotenv").config();
const twit = require("twit");
const fs = require("fs");
const path = require("path");
const { resolve } = require("path");
const twitter = new twit({
consumer_key: process.env.TWITTER_API_KEY,
consumer_secret: process.env.TWITTER_API_SECRET,
access_token: process.env.TWITTER_ACCESS_TOKEN,
access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
});
console.log("starting bot...");
// function getTweets() {
// const getTweetParams = {
// q: "#birkhe",
// count: 10,
// };
// twitter.get("search/tweets", getTweetParams, (err, data, response) => {
// return console.log(data);
// postTweet();
// });
// }
// var Nepal = ["84.1240", "28.3949"];
var stream = twitter.stream("statuses/filter", {
track: "#topi"
// geo: Nepal
});
console.log("waiting for tweets...");
console.log('----------------------');
stream.on("tweet", async (tweet) => {
console.log("writing received tweets to a file...");
fs.writeFileSync(path.join(__dirname, "tweets.json"), JSON.stringify(tweet));
console.log("writing tweet to a file is completed...");
console.log('----------------------');
const user_name = tweet.user.screen_name;
const name = tweet.user.name;
const tweetId = tweet.id_str;
const receivedTewwtText = tweet.text;
console.log("user Name id:", user_name);
console.log("name id:", name);
console.log("tweetId:", tweetId);
console.log("received text:", receivedTewwtText);
const tweetText = `#${user_name} have a good day!`;
try{
await replyTweet(tweetText);
await retweet(tweetId);
}catch(e){
console.log("the Error is ", e);
}
});
function retweet(id) {
return new Promise((reject, resolve) => {
console.log("posting retweet...");
let postRetweetParams = {
id,
};
twitter.post("statuses/retweet/:id", postRetweetParams, (err, data) => {
if (err) {
console.log("there is an error while posting retweet..");
return reject(err);
}
console.log("retweeted successfully...");
console.log('----------------------');
return resolve(data);
});
});
}
function replyTweet(text) {
return new Promise((resolve, reject) => {
console.log("replting tweet...");
let postTweetParams = {
status: text,
};
twitter.post("statuses/update", postTweetParams, (err, data) => {
if (err) {
console.log("there is an error while replting to a tweet...");
return reject(err);
}
console.log("reply tweet ID is, ", data.id_str);
console.log("replting twit completed...");
console.log('----------------------');
return resolve(data);
});
});
}
starting bot...
waiting for tweets...
----------------------
writing received tweets to a file...
writing tweet to a file is completed...
----------------------
user Name id: LaxmanP71300671
name id: Laxman Pokhrel
tweetId: 1410595913265938445
received text: Hello there #topi
replting tweet...
reply tweet ID is, 1410595936984731648
replting twit completed...
----------------------
posting retweet...
retweeted successfully...
----------------------
the Error is {
created_at: 'Thu Jul 01 13:47:34 +0000 2021',
id: 1410595939673206800,
id_str: '1410595939673206792',
text: 'RT #LaxmanP71300671: Hello there #topi',
truncated: false,
entities: {
hashtags: [ [Object] ],
symbols: [],
user_mentions: [ [Object] ],
urls: []
},
source: 'बिर्खे',
in_reply_to_status_id: null,
in_reply_to_status_id_str: null,
in_reply_to_user_id: null,
in_reply_to_user_id_str: null,
in_reply_to_screen_name: null,
user: {
id: 1407231034958094300,
id_str: '1407231034958094337',
name: 'बिर्खे',
screen_name: 'webtron_birkhe',
location: 'Kathmandu, Nepal',
description: 'म बिर्खे हुँ । म हजुरको सेवामा चौबिसै घण्टा उपलब्ध छु ।',
url: '/*some url*/',
entities: { url: [Object], description: [Object] },
protected: false,
followers_count: 2,
friends_count: 25,
listed_count: 0,
created_at: 'Tue Jun 22 06:57:05 +0000 2021',
favourites_count: 0,
utc_offset: null,
time_zone: null,
geo_enabled: false,
verified: false,
statuses_count: 9,
lang: null,
contributors_enabled: false,
is_translator: false,
is_translation_enabled: false,
profile_background_color: 'F5F8FA',
profile_background_image_url: null,
profile_background_image_url_https: null,
profile_background_tile: false,
profile_image_url: 'http://pbs.twimg.com/profile_images/1407232001204129793/47DUsEQN_normal.jpg',
profile_image_url_https: 'https://pbs.twimg.com/profile_images/1407232001204129793/47DUsEQN_normal.jpg',
profile_banner_url: 'https://pbs.twimg.com/profile_banners/1407231034958094337/1624973880',
profile_link_color: '1DA1F2',
profile_sidebar_border_color: 'C0DEED',
profile_sidebar_fill_color: 'DDEEF6',
profile_text_color: '333333',
profile_use_background_image: true,
has_extended_profile: true,
default_profile: true,
default_profile_image: false,
following: false,
follow_request_sent: false,
notifications: false,
translator_type: 'none',
withheld_in_countries: []
},
geo: null,
coordinates: null,
place: null,
contributors: null,
retweeted_status: {
created_at: 'Thu Jul 01 13:47:27 +0000 2021',
id: 1410595913265938400,
id_str: '1410595913265938445',
text: 'Hello there #topi',
truncated: false,
entities: { hashtags: [Array], symbols: [], user_mentions: [], urls: [] },
source: 'Twitter for Android',
in_reply_to_status_id: null,
in_reply_to_status_id_str: null,
in_reply_to_user_id: null,
in_reply_to_user_id_str: null,
in_reply_to_screen_name: null,
user: {
id: 1348101598157840400,
id_str: '1348101598157840384',
name: 'Laxman Pokhrel',
screen_name: 'LaxmanP71300671',
location: 'Nepal',
description: 'rock🤟',
url: null,
entities: [Object],
protected: false,
followers_count: 2,
friends_count: 18,
listed_count: 0,
created_at: 'Sun Jan 10 02:57:39 +0000 2021',
favourites_count: 4,
utc_offset: null,
time_zone: null,
geo_enabled: false,
verified: false,
statuses_count: 6,
lang: null,
contributors_enabled: false,
is_translator: false,
is_translation_enabled: false,
profile_background_color: 'F5F8FA',
profile_background_image_url: null,
profile_background_image_url_https: null,
profile_background_tile: false,
profile_image_url: 'http://pbs.twimg.com/profile_images/1348102053713727489/xpMY6o-d_normal.jpg',
profile_image_url_https: 'https://pbs.twimg.com/profile_images/1348102053713727489/xpMY6o-d_normal.jpg',
profile_banner_url: 'https://pbs.twimg.com/profile_banners/1348101598157840384/1610247852',
profile_link_color: '1DA1F2',
profile_sidebar_border_color: 'C0DEED',
profile_sidebar_fill_color: 'DDEEF6',
profile_text_color: '333333',
profile_use_background_image: true,
has_extended_profile: true,
default_profile: true,
default_profile_image: false,
following: false,
follow_request_sent: false,
notifications: false,
translator_type: 'none',
withheld_in_countries: []
},
geo: null,
coordinates: null,
place: null,
contributors: null,
is_quote_status: false,
retweet_count: 1,
favorite_count: 0,
favorited: false,
retweeted: true,
lang: 'en'
},
is_quote_status: false,
retweet_count: 1,
favorite_count: 0,
favorited: false,
retweeted: true,
lang: 'en'
}
writing received tweets to a file...
writing tweet to a file is completed...
----------------------
user Name id: webtron_birkhe
name id: बिर्खे
tweetId: 1410595939673206792
received text: RT #LaxmanP71300671: Hello there #topi
replting tweet...
reply tweet ID is, 1410595963484270594
replting twit completed...
----------------------
posting retweet...
there is an error while posting retweet..
please help.

Related

Trying to disable a button but an error popped up

I am making a help command, but I want to disable it when the embed title is the same as the button label. Except this error pops out:
C:\Users\admin\OneDrive\Documents\VSCode\JS\Discord
Bots\Testing3.JS\node_modules\discord.js\src\rest\RequestHandler.js:350
throw new DiscordAPIError(data, res.status, request);
^
DiscordAPIError: Invalid Form Body components[0]: The specified
component type is invalid in this context components[1]: The specified
component type is invalid in this context
at RequestHandler.execute (C:\Users\admin\OneDrive\Documents\VSCode\JS\Discord
Bots\Testing3.JS\node_modules\discord.js\src\rest\RequestHandler.js:350:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async RequestHandler.push (C:\Users\admin\OneDrive\Documents\VSCode\JS\Discord
Bots\Testing3.JS\node_modules\discord.js\src\rest\RequestHandler.js:51:14)
at async MessageManager.edit (C:\Users\admin\OneDrive\Documents\VSCode\JS\Discord
Bots\Testing3.JS\node_modules\discord.js\src\managers\MessageManager.js:132:15)
{ method: 'patch', path:
'/channels/956427421073158194/messages/965228940685897748', code:
50035, httpStatus: 400, requestData: {
json: {
content: undefined,
tts: false,
nonce: undefined,
embeds: [
{
title: 'Economy',
type: 'rich',
description: null,
url: null,
timestamp: null,
color: null,
fields: [ [Object], [Object], [Object], [Object] ],
thumbnail: null,
image: null,
author: null,
footer: null
}
],
components: [
{
custom_id: 'econ',
disabled: true,
emoji: { animated: false, name: '💵', id: null },
label: 'Economy',
style: 1,
type: 2,
url: null
},
{
custom_id: 'info',
disabled: false,
emoji: { animated: false, name: '📃', id: null },
label: 'Info',
style: 2,
type: 2,
url: null
}
],
username: undefined,
avatar_url: undefined,
allowed_mentions: undefined,
flags: 0,
message_reference: undefined,
attachments: undefined,
sticker_ids: undefined
},
files: [] } }
Code:
if (cmd === "help") {
const econ = new Discord.MessageButton()
.setCustomId('econ')
.setEmoji('💵')
.setLabel('Economy')
.setStyle('PRIMARY')
const info = new Discord.MessageButton()
.setCustomId('info')
.setEmoji('📃')
.setLabel('Info')
.setStyle('SECONDARY')
const row = new Discord.MessageActionRow().addComponents([econ, info]);
let helpMsg = await message.channel.send({
embeds: [
{
title: "Economy",
fields: [
{
name: `\`${cPrefix}bal | balance [user]\``,
value: 'Displays your balance or a user\'s balance.'
},
{
name: `\`${cPrefix}dep | deposit <amount>\``,
value: 'Deposits a specified amount of cash to your bank.'
},
{
name: `\`${cPrefix}with | withdraw <amount>\``,
value: 'Withdraws a specified amount of cash to your wallet.'
},
{
name: `\`${cPrefix}addcoins <user> <amount>\``,
value: 'Adds a specified amount of cash to a user. (Administrator)'
}
]
}
],
components: [row]
});
const collector = helpMsg.createMessageComponentCollector({
componentType: 'BUTTON',
time: 60000
});
collector.on('collect', async (b) => {
if (b.user.id === message.author.id) {
if (b.customId === 'econ') {
helpMsg.edit({
embeds: [
{
title: "Economy",
fields: [
{
name: `\`${cPrefix}bal | balance [user]\``,
value: 'Displays your balance or a user\'s balance.'
},
{
name: `\`${cPrefix}dep | deposit <amount>\``,
value: 'Deposits a specified amount of cash to your bank.'
},
{
name: `\`${cPrefix}with | withdraw <amount>\``,
value: 'Withdraws a specified amount of cash to your wallet.'
},
{
name: `\`${cPrefix}addcoins <user> <amount>\``,
value: 'Adds a specified amount of cash to a user. (Administrator)'
}
]
},
],
components: [row.components[0].setDisabled(true), row.components[1].setDisabled(false)]
});
}
if (b.customId === 'info') {
helpMsg.edit({
embeds: [
{
title: "Info",
fields: [
{
name: `${cPrefix}info <user|server> <user: user>`,
value: 'Displays an info of the server or a user'
},
{
name: `${cPrefix}ping`,
value: 'Displays the current client ping and the database connection'
},
{
name: `${cPrefix}help`,
value: 'Umm... You used this command'
},
]
}
],
components: [row.components[0].setDisabled(false), row.components[1].setDisabled(true)]
})
}
} else {
b.reply({ content: 'These buttons are not for you.', ephemeral: true })
}
});
collector.on('end', async () => {
helpMsg.edit({ components: [row.components[0].setDisabled(true), row.components[1].setDisabled(true)] })
});
}
Is there anything wrong in this code?
You can create a new MessageActionRow and set everything to disabled. This code is from my bot's help command (discord.js v13.6.0):
let btnraw = new Discord.MessageActionRow().addComponents(
[
new Discord.MessageButton().setCustomId("home").setStyle("SUCCESS").setLabel("Home"),
new Discord.MessageButton().setCustomId("general").setStyle("PRIMARY").setLabel("General"),
new Discord.MessageButton().setCustomId("info").setStyle("PRIMARY").setLabel("Information"),
new Discord.MessageButton().setCustomId("mod").setStyle("PRIMARY").setLabel("Moderation"),
new Discord.MessageButton().setCustomId("fun").setStyle("PRIMARY").setLabel("Fun"),
]
);
let dbtnraw = new Discord.MessageActionRow().addComponents(
[
new Discord.MessageButton().setCustomId("d_home").setStyle("SUCCESS").setLabel("Home").setDisabled(true),
new Discord.MessageButton().setCustomId("d_general").setStyle("PRIMARY").setLabel("General").setDisabled(true),
new Discord.MessageButton().setCustomId("d_info").setStyle("PRIMARY").setLabel("Information").setDisabled(true),
new Discord.MessageButton().setCustomId("d_mod").setStyle("PRIMARY").setLabel("Moderation").setDisabled(true),
new Discord.MessageButton().setCustomId("d_fun").setStyle("PRIMARY").setLabel("Fun").setDisabled(true),
]
);
Then you can edit the message to replace the original row like this:
helpMsg.edit({components: [d_btnraw]});

Attempting to save data that is streamed from a twitter api

I am trying to save data from tweets to a mongoDB database using node and express.
I am using the twitter api to stream twitter data with a specific hashtags. I just want to save the text content of the post:
Here is how the tweet content shows up when it is console.logged:
(Note this feature works and this is my own posted
{
created_at: 'Tue Mar 15 06:38:58 +0000 2022',
id: 1503621761388134400,
id_str: '1503621761388134410',
text: '#TelecomDisaster Test for project 2',
source: 'Twitter Web App',
truncated: false,
in_reply_to_status_id: null,
in_reply_to_status_id_str: null,
in_reply_to_user_id: null,
in_reply_to_user_id_str: null,
in_reply_to_screen_name: null,
user: {
id: 1472188612494172200,
id_str: '1472188612494172172',
name: 'Dillon Rampersad',
screen_name: 'R_Dillon_25',
location: null,
url: null,
description: null,
translator_type: 'none',
protected: false,
verified: false,
followers_count: 5,
friends_count: 11,
listed_count: 0,
favourites_count: 22,
statuses_count: 63,
created_at: 'Sat Dec 18 12:55:26 +0000 2021',
utc_offset: null,
time_zone: null,
geo_enabled: false,
lang: null,
contributors_enabled: false,
is_translator: false,
profile_background_color: 'F5F8FA',
profile_background_image_url: '',
profile_background_image_url_https: '',
profile_background_tile: false,
profile_link_color: '1DA1F2',
profile_sidebar_border_color: 'C0DEED',
profile_sidebar_fill_color: 'DDEEF6',
profile_text_color: '333333',
profile_use_background_image: true,
profile_image_url: 'http://pbs.twimg.com/profile_images/1472188757956780033/OMlZZeZI_normal.jpg',
profile_image_url_https: 'https://pbs.twimg.com/profile_images/1472188757956780033/OMlZZeZI_normal.jpg',
default_profile: true,
default_profile_image: false,
following: null,
follow_request_sent: null,
notifications: null,
withheld_in_countries: []
},
geo: null,
coordinates: null,
place: null,
contributors: null,
is_quote_status: false,
quote_count: 0,
reply_count: 0,
retweet_count: 0,
favorite_count: 0,
entities: { hashtags: [ [Object] ], urls: [], user_mentions: [], symbols: [] },
favorited: false,
retweeted: false,
filter_level: 'low',
lang: 'en',
timestamp_ms: '1647326338513'
}
I want to save text: '#TelecomDisaster Test for project 2', and created_at: 'Tue Mar 15 06:38:58 +0000 2022', to my database.
I am trying with the function below to save just the text for now but i dont quite understand how to:
const express = require('express')
const router = new express.Router();
var Twitter = require('twit')
const TwitterPosts = require("../db/models/TwitterPosts.model");
//api keys goes here but it removed for safety
var stream = client.stream('statuses/filter', { track: '#TelecomDisaster' })
stream.on('tweet', function (tweet) {
console.log(tweet)
let newtweet = new TwitterPosts({
tweet: req.body.postContent
});
newtweet.save().then((twit) => {
res.send(twit);
console.log(twit);
})
});
module.exports = router;
The model for the schema:
const mongoose = require('mongoose');
const TwitterPostsSchema = new mongoose.Schema({
twitterUsername:{
type: String,
required: false,
minlength:1,
trim: true
},
postContent:{
type: String,
required: false,
minlength:1,
trim: true
},
postDateTime:{
type: Date,
required: false,
default: Date.now
}
})
const TwitterPosts = mongoose.model( 'TwitterPosts', TwitterPostsSchema);
module.exports = TwitterPosts
Whenever it trys to save i get the error
tweet: req.body.postContent
^
ReferenceError: req is not defined
i did not define req but in this use case i dont know how to do that exactly when streaming the tweets.
To conclude i am trying to save tweets to a mongoDB database using node and express. the tweets are streamed as shown above but i dont quite understand how it is saved to the database.
you receive tweet in stream.on listener, so it's just tweet, instead of req.body.postContent:
let newtweet = new TwitterPosts({
tweet: tweet
});
or, according to your schema:
let newtweet = new TwitterPosts({
twitterUsername: tweet.user.name,
postContent: tweet.text,
postDateTime: tweet.created_at
});

.patch() do not saves the parameter to the database in Objection.js with Knex

I am creating Express API and I am using Objection.js as ORM with Knex.js
I have created router for updating user password from the profile with 2 fields (old password and the new password),first it verifies the old password (protection from stealing JWT token). After it returns valid condition then I proceed to hash the new password with bcrypt and update it with .patch() otherwise it will return validation error the old password it is not the correct password. The problem is when I send the same exact request it goes through meaning that .patch not worked and did not save the new password to the database. Can anyone explain some solution to this problem or probably hit me with some documention on how to fix it
The code is bellow:
router.patch('/updatepassword', async (req, res, next) => {
const { id } = req.user;
const {
oldPassword,
newPassword,
} = req.body;
try {
await passwordSchema.validate({
oldPassword,
newPassword,
}, {
abortEarly: false
});
const UserOldPassword = await User.query().select('password').findById(id);
const validOldPassword = await bcrypt.compare(oldPassword, UserOldPassword.password);
if (validOldPassword) {
const hashedPassword = await bcrypt.hash(newPassword, 12);
const defi = User.query().patch({ password: hashedPassword }).where('id', id).returning('*')
.first();
console.log(defi);
res.status(200).json({
message: returnMessage.passwordUpdated
});
} else {
const error = new Error(returnMessage.invalidOldPassword);
res.status(403);
throw error;
}
} catch (error) {
next(error);
}
});
Console log:
QueryBuilder {
_modelClass: [Function: User],
_operations: [
UpdateOperation {
name: 'patch',
opt: [Object],
adderHookName: null,
parentOperation: null,
childOperations: [],
model: [User],
modelOptions: [Object]
},
KnexOperation {
name: 'where',
opt: {},
adderHookName: null,
parentOperation: null,
childOperations: [],
args: [Array]
},
ReturningOperation {
name: 'returning',
opt: {},
adderHookName: null,
parentOperation: null,
childOperations: [],
args: [Array]
},
FirstOperation {
name: 'first',
opt: {},
adderHookName: null,
parentOperation: null,
childOperations: []
}
],
_context: QueryBuilderContext {
userContext: QueryBuilderUserContext { [Symbol()]: [Circular] },
options: InternalOptions {
skipUndefined: false,
keepImplicitJoinProps: false,
isInternalQuery: false,
debug: false
},
knex: null,
aliasMap: null,
tableMap: null,
runBefore: [],
runAfter: [],
onBuild: []
},
_parentQuery: null,
_isPartialQuery: false,
_activeOperations: [],
_resultModelClass: null,
_explicitRejectValue: null,
_explicitResolveValue: null,
_modifiers: {},
_allowedGraphExpression: null,
_findOperationOptions: {},
_relatedQueryFor: null,
_findOperationFactory: [Function: findOperationFactory],
_insertOperationFactory: [Function: insertOperationFactory],
_updateOperationFactory: [Function: updateOperationFactory],
_patchOperationFactory: [Function: patchOperationFactory],
_relateOperationFactory: [Function: relateOperationFactory],
_unrelateOperationFactory: [Function: unrelateOperationFactory],
_deleteOperationFactory: [Function: deleteOperationFactory]
}
PATCH /v1/profile/updatepassword 200 1346.797 ms - 42
Solution: Do not forget to put await on async function.

Sequelize and response request GraphQL

I try to have a response on my request GraphQL.
I tried many things but currently I have always the Sequence response, and no the Buckets response (belongs To relation).
I have 2 tables :
Sequence [id | is_active]
Bucket [id | fk_language_id | fk_sequence_id | is_active]
model/sequence.js
'use strict';
module.exports = (sequelize, DataTypes) => {
// define sequence
const Sequence = sequelize.define('sequence', {
is_active: {type: DataTypes.BOOLEAN}
});
Sequence.associate = function (models) {
models.Sequence.hasMany(models.Bucket, {
foreignKey: 'fk_sequence_id'
});
return Sequence;
};
model/bucket.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const Bucket = sequelize.define('bucket', {
code : {type: DataTypes.STRING},
is_active: {type: DataTypes.BOOLEAN}
});
Bucket.associate = function (models) {
models.Bucket.belongsTo(models.Language, {
foreignKey: 'fk_language_id',
});
models.Bucket.belongsTo(models.Sequence, {
foreignKey: 'fk_sequence_id',
});
};
return Bucket;
};
schema.js
# Sequence
type Sequence {
id: Int!,
code: String,
buckets: [Bucket],
is_active: Boolean
}
# Bucket
type Bucket {
id: Int!,
code: String
blocks: [Block]
is_active: Boolean
}
# SequenceInput
input SequenceInput {
buckets: [BucketInput],
is_active: Boolean
}
# BucketInput
input BucketInput {
code: String,
fk_language_id: Int,
fk_sequence_id: Int,
is_active: Boolean
}
type Query {
sequences: [Sequence]
sequence(id: Int): Sequence
buckets: [Bucket]
bucket(id: Int): Bucket
}
type Mutation {
createSequence(input: SequenceInput): Sequence,
}
Request GraphQL
mutation {
createSequence(input: {
is_active: false,
buckets: [
{fk_language_id: 2, code: "Test"}
]
}) {
is_active,
buckets {
id,
code
}
}
}
But I have this result, the Buckets doesn't load :
{
"data": {
"createSequence": {
"is_active": false,
"buckets": []
}
}
}
my mutation :
...
Sequence : {
buckets(sequence) {
return models.Bucket.findAll({
where: {id: sequence.id}
});
},
...
},
...
Mutation : {
createSequence(_, {input}) {
let sequenceId = 0;
// Create Sequence
return models.Sequence.create(input)
.then((sequence) => {
sequenceId = sequence.id;
console.log('sequence created');
// Create Bucket
// Foreach on buckets
return Promise.map(input.buckets, function (bucket) {
bucket.fk_sequence_id = sequenceId;
console.log('bucket created');
return models.Bucket.create(bucket);
})
})
.then(() => {
console.log('load created', sequenceId);
return models.Sequence.findOne({
where : {id: sequenceId},
include: [
{
model: models.Bucket,
where: { fk_sequence_id: sequenceId }
}
]
}).then((response) => {
console.log(response);
return response;
})
});
},
}
The final console.log show many informations...
sequence {
dataValues:
{ id: 416,
is_active: false,
created_at: 2019-03-29T20:33:56.196Z,
updated_at: 2019-03-29T20:33:56.196Z,
buckets: [ [Object] ] },
_previousDataValues:
{ id: 416,
is_active: false,
created_at: 2019-03-29T20:33:56.196Z,
updated_at: 2019-03-29T20:33:56.196Z,
buckets: [ [Object] ] },
_changed: {},
_modelOptions:
{ timestamps: true,
validate: {},
freezeTableName: true,
underscored: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: { id: 416 },
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: {},
indexes: [],
name: { plural: 'sequences', singular: 'sequence' },
omitNull: false,
createdAt: 'created_at',
updatedAt: 'updated_at',
sequelize:
Sequelize {
options: [Object],
config: [Object],
dialect: [Object],
queryInterface: [Object],
models: [Object],
modelManager: [Object],
connectionManager: [Object],
importCache: [Object],
test: [Object] },
hooks: {} },
_options:
{ isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
include: [ [Object] ],
includeNames: [ 'buckets' ],
includeMap: { buckets: [Object] },
includeValidated: true,
attributes: [ 'id', 'is_active', 'created_at', 'updated_at' ],
raw: true },
isNewRecord: false,
buckets:
[ bucket {
dataValues: [Object],
_previousDataValues: [Object],
_changed: {},
_modelOptions: [Object],
_options: [Object],
isNewRecord: false } ] }
Your mutation resolver returns a Promise, which resolves into a Model instance. The promise in question is returned on this line:
return models.Sequence.create(input)
.
As such, the server will wait until that promise is resolved before passing the value forward. Other actions were also waiting on that promise, but they were not the promises returned, so they will not be waited for.
All you have to do is wait for all of your operations to finish before resolving your promise.
createSequence: async (parent, { input }) => {
const sequence = await models.Sequence.create({
is_active: input.is_active
})
if (!input.buckets) return sequence
// You may have to modify your Sequence.buckets resolver to avoid fetching buckets again.
sequence.buckets = await Promise.all(input.buckets.map(bucket => {
// You can avoid these if checks by implementing stricter input types.
// e.g. buckets: [BucketInput!]!
if (!bucket) return null
return models.Bucket.create({
...bucket,
fk_sequence_id: sequence.id
})
}))
return sequence
}
Also, make sure your Sequence.buckets resolver isn't overwriting buckets with faulty data. The resolver you've provided will try to match bucket primary keys with a sequence primary key instead of matching the correct foreign keys with a primary key.
Here's a resolver that will work:
buckets: (parent) => (
parent.buckets // This line may conflict with some of your code and cause problems.
|| models.Bucket.findAll({
where: {fk_sequence_id: parent.id}
})
)

NodeJS + mongoose - user dynamic database globally

I am using NodeJS, ExpressJS, express-session, connect-mongo and mongoose. I want to create a database for every user. On login the database connection should be globally to use.
This is the: loginController
exports.loginPost = (req, res, next) => {
const email = req.body.email;
const pass = req.body.password;
const pin = req.body.pin;
if (email && pass && pin) {
User.findOne({ email })
.then(u => {
bcrypt.compare(pass, u.password, (err, result) => {
if (!err) {
bcrypt.compare(pin, u.pin, (err2, result2) => {
if (!err2) {
let msg = {};
global.userDB = null;
msg.success = [{ text: "You are now logged in..." }];
req.session.loggedIn = true;
req.session.userId = u._id;
req.session.role= u.role;
const Mongoose = require("mongoose").Mongoose;
const inst = new Mongoose();
let db = "user-" + orgid;
global.userDB = inst.connect(
"mongodb://localhost:27017?authSource=dbWithUserCredentials",
{
useNewUrlParser: true,
auth: { authSource: "admin" },
user: "root",
pass: "root",
dbName: db,
autoReconnect: true
}
);
return res.redirect("/");
} else {
console.log(err2);
}
});
} else {
return res.render("login", {
req,
msg: null
});
}
});
})
.catch(err => {
return res.render("login", {
req,
msg: err
});
});
}
};
This is the adressModel:
const aschema = global.userDB.Schema;
var AdressSchema = new aschema({
name: {
type: String
}
});
var Address = global.userDB.model("Adress", AdressSchema);
module.exports = Address;
When I'm running a page where I'm using this model, i see this on the console when I'm using this command: "console.log(global.userDB)";
NativeConnection {
base:
Mongoose {
connections: [ [Circular] ],
models: {},
modelSchemas: {},
options: { pluralization: true },
plugins: [ [Array], [Array], [Array] ] },
collections: {},
models: {},
config: { autoIndex: true },
replica: false,
hosts: null,
host: 'localhost',
port: 27017,
user: 'root',
pass: 'root',
name: 'user-undefined',
options:
{ pass: 'root',
user: 'root',
auth: { authSource: 'admin' },
useNewUrlParser: true,
db: { forceServerObjectId: false, w: 1 },
server: { socketOptions: {}, auto_reconnect: true },
replset: { socketOptions: {} },
mongos: undefined },
otherDbs: [],
states:
[Object: null prototype] {
'0': 'disconnected',
'1': 'connected',
'2': 'connecting',
'3': 'disconnecting',
'4': 'unauthorized',
'99': 'uninitialized',
disconnected: 0,
connected: 1,
connecting: 2,
disconnecting: 3,
unauthorized: 4,
uninitialized: 99 },
_readyState: 2,
_closeCalled: false,
_hasOpened: false,
_listening: false,
db:
Db {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
s:
{ databaseName: 'user-undefined',
dbCache: {},
children: [],
topology: [Server],
options: [Object],
logger: [Logger],
bson: BSON {},
authSource: undefined,
readPreference: undefined,
bufferMaxEntries: -1,
parentDb: null,
pkFactory: undefined,
nativeParser: undefined,
promiseLibrary: [Function: Promise],
noListener: false,
readConcern: undefined },
serverConfig: [Getter],
bufferMaxEntries: [Getter],
databaseName: [Getter] } }
Can someone say, why i get an 'undefined' in the database-name, but when I console.log the 'db'-variable there is the correct user._id.
Thanks!

Resources