Two if statements to make cmd differentiate between roles - node.js

I'm wondering if it is possible to use if statements this way so that the command gives separate messages depending on the users role. This is one attempt I've made but the second if statement is unreachable.
module.exports = {
name: "train",
description: "Train to earn some reputation!",
async execute(client, message, args, cmd, discord, profileData) {
const events1 = [
"sample event",
"sample event",
"sample event",
];
const events2 = [
"sample event",
"sample event",
"sample event",
];
const injuries = [
"sample injury",
"sample injury",
"sample injury",
];
const chosenEvent1 = events1.sort(() => Math.random() - Math.random()).slice(0, 1);
const chosenEvent2 = events2.sort(() => Math.random() - Math.random()).slice(0, 1);
const chosenInjury = injuries.sort(() => Math.random() - Math.random()).slice(0, 1);
const randomNumber1 = Math.floor(Math.random() * 29) + 5;
const randomNumber2 = Math.floor(Math.random() * 9) + 1;
if((!message.member.roles.cache.has('roleid#1'))); {
if(Math.floor(Math.random() * 3) === 0) {
await profileModel.findOneAndUpdate(
{
userID: message.author.id,
},
{
$inc: {
health: -randomNumber2,
},
}
);
return message.channel.send(`${chosenInjury} You lost ${randomNumber2} health and gained no reputation.`);
} else {
await profileModel.findOneAndUpdate(
{
userID: message.author.id,
},
{
$inc: {
reputation: randomNumber1,
},
}
);
return message.channel.send(`${chosenEvent1} You earned ${randomNumber1} reputation!`);
}
if((!message.member.roles.cache.has('roleid#2'))); {
return message.channel.send(`${chosenEvent2} You earned ${randomNumber1} reputation!`);
}
}}
};
So ideally if you have RoleID #1, you have a chance of injury or your reputation increases and you get a message with Event1 prompts. If you have RoleID #2, your reputation just increases and you get a message with Event2 prompts. I hope this is clear.

It seems the brackets are bit off and that is why the code is unreachable.
I have also attached an image of the locations where I made code changes. A key consideration is in javascript try to avoid placing semicolons right after an if statement
Please see the small bracket changes I made in your code example:
module.exports = {
name: 'train',
description: 'Train to earn some reputation!',
async execute(client, message, args, cmd, discord, profileData) {
const events1 = ['sample event', 'sample event', 'sample event'];
const events2 = ['sample event', 'sample event', 'sample event'];
const injuries = ['sample injury', 'sample injury', 'sample injury'];
const chosenEvent1 = events1.sort(() => Math.random() - Math.random()).slice(0, 1);
const chosenEvent2 = events2.sort(() => Math.random() - Math.random()).slice(0, 1);
const chosenInjury = injuries.sort(() => Math.random() - Math.random()).slice(0, 1);
const randomNumber1 = Math.floor(Math.random() * 29) + 5;
const randomNumber2 = Math.floor(Math.random() * 9) + 1;
if (!message.member.roles.cache.has('roleid#1')) {
if (Math.floor(Math.random() * 3) === 0) {
await profileModel.findOneAndUpdate(
{
userID: message.author.id,
},
{
$inc: {
health: -randomNumber2,
},
}
);
return message.channel.send(
`${chosenInjury} You lost ${randomNumber2} health and gained no reputation.`
);
} else {
await profileModel.findOneAndUpdate(
{
userID: message.author.id,
},
{
$inc: {
reputation: randomNumber1,
},
}
);
return message.channel.send(`${chosenEvent1} You earned ${randomNumber1} reputation!`);
}
} else if (!message.member.roles.cache.has('roleid#2')) {
return message.channel.send(`${chosenEvent2} You earned ${randomNumber1} reputation!`);
}
},
};

Related

NodeJs Strimzi: KStream KTable join results in very few key matches

I am using nodefluent/kafka-streams to join a KStream and a KTable. This is with Strimzi on Kubernetes. I have set-up in such a way that, every message in KStream will definitely have a matching key in KTable. However, I see only a few (< 10) messages in the final topic. Can you please advise why the overlap is so rare?
const { KafkaStreams } = require("kafka-streams");
const kafkaBroker = process.env.KAFKA_BROKER
const kafkaConfig = {
"noptions": {
"metadata.broker.list": kafkaBroker,
"group.id": "kafka-streams-test-native",
"client.id": "kafka-streams-test-name-native",
"event_cb": true,
"compression.codec": "snappy",
"api.version.request": true,
"socket.keepalive.enable": true,
"socket.blocking.max.ms": 100,
"enable.auto.commit": false,
"auto.commit.interval.ms": 100,
"heartbeat.interval.ms": 250,
"retry.backoff.ms": 250,
"fetch.min.bytes": 100,
"fetch.message.max.bytes": 2 * 1024 * 1024,
"queued.min.messages": 100,
"fetch.error.backoff.ms": 100,
"queued.max.messages.kbytes": 50,
"fetch.wait.max.ms": 1000,
"queue.buffering.max.ms": 1000,
"batch.num.messages": 10000
},
"tconf": {
"auto.offset.reset": "earliest",
"request.required.acks": 1
},
"batchOptions": {
"batchSize": 5,
"commitEveryNBatch": 1,
"concurrency": 1,
"commitSync": false,
"noBatchCommits": false
}
}
const kafkaStreams = new KafkaStreams(kafkaConfig);
const rawData = process.env.KAFKA_TOPIC;
const lookUp = process.env.KAFKA_TOPIC_LKUP;
const alerts = process.env.KAFKA_TOPIC_ALERTS;
const dataStream = kafkaStreams.getKStream(rawData)
const lookUpTable = kafkaStreams.getKTable(lookUp, (message) => {
return {
key: message.key,
value: message.value
};
})
// I don't know, if this should be done.
lookUpTable.consumeUntilCount(2)
const alertsStream = dataStream
.innerJoin(lookUp)
.mapBufferKeyToString()
.mapStringValueToJSONObject()
.map((msg) => {
let key = msg.left.key
let data = msg.left.value
// Some logic
return `${key.toString()}|${JSON.stringify({ data:data })}`
})
.mapStringToKV("|", 0, 1)
Promise.all([
dataStream.start(),
lookUpTable.start(),
alertsStream.to(alerts)
])
.then(() => {
console.log("both consumers and the producer have connected.");
});
I am using KafkaJS to publish messages to rawData and lookUp topics as shown below.
const producer = kafka.producer()
const run = async () => {
await producer.connect()
await producer.send({
topic: process.env.KAFKA_TOPIC_LKUP,
messages: [
{ key: "k1", value: "Data 1" },
{ key: "k2", value: "Data 2" }
],
})
setInterval(async function () {
await producer.send({
topic: process.env.KAFKA_TOPIC,
messages: [
{ key: "k1", value: "Random 1" },
{ key: "k2", value: "Random 2" }
],
})
}, 1000)
}
run().catch(e => console.error(` ${e.message}`, e))

nodejs mongoose CastError (with discordjs)

error image
this is my error, im making on my discord bot with discord.js
and im making stock bot now, heres my sources , i have too much code to upload codes with pastbin https://pastebin.com/Sr8QxBYd (stock.js codes) i searched my examples on internet but i cant find examples like me.
why this problem occurs, and how to solve this problem i want to know these
const { Client, Intents, Collection } = require('discord.js');
const { prefix ,token } = require('./config.json');
const fs = require('fs');
const commandsFile = fs.readdirSync('./commands').filter(file => file.endsWith('.js'))
const client = new Client({intents:32767}); //32767 모든 권한 Intents.FLAGS.GUILDS 권한 약한거
const { DiscordTogether } = require('discord-together');
const mongoose = require('mongoose');
module.exports = client;
const Schema = require("./models/주식");
mongoose.connect("",{
}).then(console.log("DB successfully connected"));
client.discordTogether = new DiscordTogether(client);
client.once('ready', async () => {
console.log('Ready!');
client.user.setActivity("범이야 도움말",{
type:"PLAYING"
})
const Schema_stock = require("./models/주식")
const stockInfo = await Schema_stock.findOne({
stock: "391839729830"
})
const getRandom = (min, max) => Math.floor(Math.random() * (max - min) + min);
let seoulJjVar = getRandom(-20, 20) //서울
let eungaeFdVar = getRandom(-20, 20) //응애
let seondoCfVar = getRandom(-20, 20) //선도
let gukcciVar = getRandom(-20, 20) //국찌
module.exports = {
seoulJjVar,
eungaeFdVar,
gukcciVar,
seondoCfVar
};
await Schema.findOneAndUpdate({stock: "391839729830"}, {
seoulJj: stockInfo.seoulJj - seoulJjVar,
eungaeFd: stockInfo.eungaeFd - eungaeFdVar,
gukcci: stockInfo.gukcci - gukcciVar,
seondoCf: stockInfo.seondoCf - seondoCfVar
})
const interval = {
// tick: 0,
_interval: undefined,
start: function () {
this._interval = setInterval(this.callback.bind(this), 300000);
},
callback: async function () {
// this.tick += 1;
// console.log(this.tick);
// if (this.tick >= 3) clearInterval(this._interval);
seoulJjVar = getRandom(-20, 20) //서울
eungaeFdVar = getRandom(-20, 20) //응애
seondoCfVar = getRandom(-20, 20) //선도
gukcciVar = getRandom(-20, 20) //국찌
await Schema.findOneAndUpdate({stock: "391839729830"}, {
seoulJj: stockInfo.seoulJj - seoulJjVar,
eungaeFd: stockInfo.eungaeFd - eungaeFdVar,
gukcci: stockInfo.gukcci - gukcciVar,
seondoCf: stockInfo.seondoCf - seondoCfVar
})
}
}
interval.start();
});
client.commands = new Collection();
for(const file of commandsFile){
const command = require(`./commands/${file}`)
client.commands.set(command.name , command)
}
client.on('messageCreate' , message=>{
if(!message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const commandName = args.shift();
const command = client.commands.get(commandName);
if (!command) return;
try{
command.execute(message,args);
} catch (error) {
console.error(error);
}
})
client.on('guildMemberUpdate', () => {
if(client.user.id!="범이"){
client.user.id = "범이";
}
})
client.on('userUpdate', () => {
if(client.user.id!="범이"){
client.user.id = "범이";
}
})
client.on('messageCreate',message=>{
if(message.content == `${prefix}유튜브`){
const channel = message.member.voice.channel
if(!channel) return message.reply("음성채널에 접속해주세요!");
client.discordTogether.createTogetherCode(channel.id, 'youtube').then(invite =>{
return message.channel.send(invite.code);
})
}
})
client.login(token);
//index.js
const mongo = require("mongoose")
const d = new mongo.Schema({
money: { type: Number },
userid: { type: String },
date: { type: String },
stocks: {
seoulJj: { type: Number },
eungaeFd: { type: Number },
gukcci: { type: Number },
seondoCf: { type: Number },
imold: { type:Number }
}
})
const MessageModel = module.exports = mongo.model("도박", d);
//./models/도박.js
const mongo = require("mongoose")
const dt = new mongo.Schema({
seoulJj: { type: Number },
eungaeFd: { type: Number },
gukcci: { type: Number },
seondoCf: { type: Number },
stock: { type: String }
})
const MessageModel = module.exports = mongo.model("주식", dt);
//./models/주식.js

Nodejs , AWS Dynamodb how to check if user already exists before creating new record

I am creating AWS lamda function to create a customer ( lead ) , but before creating the customer i need to check if the user already exists . A customer/lead can be identified by combination of email and phone number .
here is my table definition :
dynamodb-tables.ts
export default {
LeadsTable: {
Type: "AWS::DynamoDB::Table",
DeletionPolicy: "Retain",
Properties: {
TableName: "${self:provider.environment.LEADS_TABLE}",
AttributeDefinitions: [{ AttributeName: "id", AttributeType: "S" }],
KeySchema: [{ AttributeName: "id", KeyType: "HASH" }],
ProvisionedThroughput: {
ReadCapacityUnits: "${self:custom.table_throughput}",
WriteCapacityUnits: "${self:custom.table_throughput}",
},
},
},
InterestsTable: {
Type: "AWS::DynamoDB::Table",
DeletionPolicy: "Retain",
Properties: {
TableName: "${self:provider.environment.INTERESTS_TABLE}",
AttributeDefinitions: [
{ AttributeName: "id", AttributeType: "S" },
{ AttributeName: "leadId", AttributeType: "S" },
],
KeySchema: [
{ AttributeName: "id", KeyType: "HASH" },
{ AttributeName: "leadId", KeyType: "RANGE" },
],
ProvisionedThroughput: {
ReadCapacityUnits: "${self:custom.table_throughput}",
WriteCapacityUnits: "${self:custom.table_throughput}",
},
GlobalSecondaryIndexes: [
{
IndexName: "lead_index",
KeySchema: [{ AttributeName: "leadId", KeyType: "HASH" }],
Projection: {
// attributes to project into the index
ProjectionType: "ALL", // (ALL | KEYS_ONLY | INCLUDE)
},
ProvisionedThroughput: {
ReadCapacityUnits: "${self:custom.table_throughput}",
WriteCapacityUnits: "${self:custom.table_throughput}",
},
},
],
},
},
};
here is my model : lead.model.ts
import { v4 as UUID } from "uuid";
// Interfaces
interface IProps {
id?: string;
email: string;
phone: string;
firstName: string;
lastName: string;
}
interface ILeadInterface extends IProps {
createdAt: Date;
updatedAt: Date;
}
export default class LeadModel {
private _id: string;
private _email: string;
private _phone: string;
private _firstName: string;
private _lastName: string;
constructor({
id = UUID(),
email = "",
phone = "",
firstName = "",
lastName = "",
}: IProps) {
this._id = id;
this._email = email;
this._phone = phone;
this._firstName = firstName;
this._lastName = lastName;
}
/**
* Set Id
* #param value
*/
setId(value: string) {
this._id = value !== "" ? value : null;
}
/**
* Get Id
* #return {string|*}
*/
getId() {
return this._id;
}
/**
* Set Email
* #param value
*/
setEmail(value: string) {
this._email = value !== "" ? value : null;
}
/**
* Get Email
* #return {string|*}
*/
getEmail() {
return this._email;
}
/**
* Set Phone
* #param value
*/
setPhone(value: string) {
this._phone = value !== "" ? value : null;
}
/**
* Get Phone
* #return {string|*}
*/
getPhone() {
return this._phone;
}
/**
* Set First Name
* #param value
*/
setFirstName(value: string) {
this._firstName = value !== "" ? value : null;
}
/**
* Get First Name
* #return {string|*}
*/
getFirstName() {
return this._firstName;
}
/**
* Set Last Name
* #param value
*/
setLastName(value: string) {
this._lastName = value !== "" ? value : null;
}
/**
* Get Last Name
* #return {string|*}
*/
getLastName() {
return this._lastName;
}
/**
* Get Base entity mappings
* #return {ILeadInterface}
*/
getEntityMappings(): ILeadInterface {
return {
id: this.getId(),
email: this.getEmail(),
phone: this.getPhone(),
firstName: this.getFirstName(),
lastName: this.getLastName(),
createdAt: new Date(),
updatedAt: new Date(),
};
}
}
My action/ function : create-lead.action.ts
import {
APIGatewayProxyHandler,
APIGatewayEvent,
Context,
APIGatewayProxyResult,
} from "aws-lambda";
import "source-map-support/register";
// Models
import LeadModel from "../../models/lead.model";
import ResponseModel from "../../models/response.model";
// Services
import DatabaseService from "../../services/database.service";
// utils
import { validateAgainstConstraints } from "../../utils/util";
// Define the request constraints
import requestConstraints from "../../constraints/lead/create.constraint.json";
// Enums
import { StatusCode } from "../../enums/status-code.enum";
import { ResponseMessage } from "../../enums/response-message.enum";
/***
* Create lead and insert into database
*
* #api {post} /lead/create
* #apiName Create lead
* #apiGroup lead
* #apiDescription Create lead
*
* #apiParam {string} email The email id of the lead
* #apiParam {string} phone The phone number of the lead
* #apiParam {string} firstName The first name of the lead
* #apiParam {string} lastName The last name of the lead
*
* #apiSuccess {object} data
* #apiSuccess {string} message The response message
* #apiSuccess {string} status The response status
*
* #apiParamExample {json} Request-Example:
* {
* "email": "jj#mailinator.com",
* "phone": "+7352726252",
* "firstName":"jj",
* "lastName":"jo"
* }
*
* #apiSuccessExample {json} Success-Response:
* HTTP/1.1 200 OK
* {
* "data": { "leadId": "468c8094-a756-4000-a919-974a64b5be8e" },
* "message": "Lead successfully created"
* "status": "success"
* }
* *
* #apiErrorExample {json} Error-Response: Validation Errors
* HTTP/1.1 400 Bad Request
* {
* "data": {
* "validation": {
"email": [
"Email can't be blank"
]
}
* },
* "message": "required fields are missing",
* "status": "bad request"
* }
*
* #apiErrorExample {json} Error-Response: Unknown Error
* HTTP/1.1 500 Internal Server Error
* {
* "data": {},
* "message": "Unknown error",
* "status": "error"
* }
*/
export const createLead: APIGatewayProxyHandler = async (
event: APIGatewayEvent,
_context: Context
): Promise<APIGatewayProxyResult> => {
// Initialize response variable
let response;
// Parse request parameters
const requestData = JSON.parse(event.body);
// Validate against constraints
return validateAgainstConstraints(requestData, requestConstraints)
.then(async () => {
// Initialise database service
const databaseService = new DatabaseService();
// Initialise and hydrate model
const leadModel = new LeadModel(requestData);
// Get model data
const data = leadModel.getEntityMappings();
// Initialise DynamoDB PUT parameters
const params = {
TableName: process.env.LEADS_TABLE,
Item: {
id: data.id,
email: data.email,
phone: data.phone,
firstName: data.firstName,
lastName: data.lastName,
createdAt: data.createdAt,
updatedAt: data.updatedAt,
},
};
// check if lead is uneque
const unequeCheckParams = {
TableName: process.env.LEADS_TABLE,
FilterExpression: "#email = :emailval OR #phone = :phoneval",
ExpressionAttributeNames: {
"#email": "email",
"#phone": "phone",
},
ExpressionAttributeValues: {
":emailval": data.email,
":phoneval": data.phone,
},
};
const isLead = await databaseService.query(unequeCheckParams);
if (isLead) {
throw new ResponseModel(
{},
409,
`create-error: ${ResponseMessage.CREATE_LEAD_FAIL_DUPLICATE}`
);
}
// Inserts item into DynamoDB table
await databaseService.create(params);
return data.id;
})
.then((leadId) => {
// Set Success Response
response = new ResponseModel(
{ leadId },
StatusCode.OK,
ResponseMessage.CREATE_LEAD_SUCCESS
);
})
.catch((error) => {
// Set Error Response
response =
error instanceof ResponseModel
? error
: new ResponseModel(
{},
StatusCode.ERROR,
ResponseMessage.CREATE_LEAD_FAIL
);
})
.then(() => {
// Return API Response
return response.generate();
});
};
My database service looks something like this : database.service.ts
/* eslint-disable no-await-in-loop */
import * as AWS from "aws-sdk";
// Models
import ResponseModel from "../models/response.model";
// Interfaces
import IConfig from "../interfaces/config.interface";
// Enums
import { StatusCode } from "../enums/status-code.enum";
import { ResponseMessage } from "../enums/response-message.enum";
// Put
type PutItem = AWS.DynamoDB.DocumentClient.PutItemInput;
type PutItemOutput = AWS.DynamoDB.DocumentClient.PutItemOutput;
// Batch write
type BatchWrite = AWS.DynamoDB.DocumentClient.BatchWriteItemInput;
type BatchWriteOutPut = AWS.DynamoDB.DocumentClient.BatchWriteItemOutput;
// Update
type UpdateItem = AWS.DynamoDB.DocumentClient.UpdateItemInput;
type UpdateItemOutPut = AWS.DynamoDB.DocumentClient.UpdateItemOutput;
// Query
type QueryItem = AWS.DynamoDB.DocumentClient.QueryInput;
type QueryItemOutput = AWS.DynamoDB.DocumentClient.QueryOutput;
// Get
type GetItem = AWS.DynamoDB.DocumentClient.GetItemInput;
type GetItemOutput = AWS.DynamoDB.DocumentClient.GetItemOutput;
// Delete
type DeleteItem = AWS.DynamoDB.DocumentClient.DeleteItemInput;
type DeleteItemOutput = AWS.DynamoDB.DocumentClient.DeleteItemOutput;
type Item = { [index: string]: string };
const {
STAGE,
DYNAMODB_LOCAL_STAGE,
DYNAMODB_LOCAL_ACCESS_KEY_ID,
DYNAMODB_LOCAL_SECRET_ACCESS_KEY,
DYNAMODB_LOCAL_ENDPOINT,
} = process.env;
const config: IConfig = { region: "eu-west-1" };
if (STAGE === DYNAMODB_LOCAL_STAGE) {
config.accessKeyId = DYNAMODB_LOCAL_ACCESS_KEY_ID; // local dynamodb accessKeyId
config.secretAccessKey = DYNAMODB_LOCAL_SECRET_ACCESS_KEY; // local dynamodb secretAccessKey
config.endpoint = DYNAMODB_LOCAL_ENDPOINT; // local dynamodb endpoint
}
AWS.config.update(config);
const documentClient = new AWS.DynamoDB.DocumentClient();
export default class DatabaseService {
getItem = async ({ key, hash, hashValue, tableName }: Item) => {
const params = {
TableName: tableName,
Key: {
id: key,
},
};
if (hash) {
params.Key[hash] = hashValue;
}
const results = await this.get(params);
if (Object.keys(results).length) {
return results;
}
console.error("Item does not exist");
throw new ResponseModel(
{ id: key },
StatusCode.BAD_REQUEST,
ResponseMessage.INVALID_REQUEST
);
};
create = async (params: PutItem): Promise<PutItemOutput> => {
try {
return await documentClient.put(params).promise();
} catch (error) {
console.error(`create-error: ${error}`);
throw new ResponseModel({}, 500, `create-error: ${error}`);
}
};
batchCreate = async (params: BatchWrite): Promise<BatchWriteOutPut> => {
try {
return await documentClient.batchWrite(params).promise();
} catch (error) {
console.error(`batch-write-error: ${error}`);
throw new ResponseModel({}, 500, `batch-write-error: ${error}`);
}
};
update = async (params: UpdateItem): Promise<UpdateItemOutPut> => {
try {
// result.Attributes
return await documentClient.update(params).promise();
} catch (error) {
console.error(`update-error: ${error}`);
throw new ResponseModel({}, 500, `update-error: ${error}`);
}
};
query = async (params: QueryItem): Promise<QueryItemOutput> => {
try {
return await documentClient.query(params).promise();
} catch (error) {
console.error(`query-error: ${error}`);
throw new ResponseModel({}, 500, `query-error: ${error}`);
}
};
get = async (params: GetItem): Promise<GetItemOutput> => {
console.log("DB GET - STAGE: ", STAGE);
console.log("DB GET - params.TableName: ", params.TableName);
console.log("DB GET - params.Key: ", params.Key);
try {
return await documentClient.get(params).promise();
} catch (error) {
console.error(`get-error - TableName: ${params.TableName}`);
console.error(`get-error: ${error}`);
throw new ResponseModel({}, 500, `get-error: ${error}`);
}
};
delete = async (params: DeleteItem): Promise<DeleteItemOutput> => {
try {
return await documentClient.delete(params).promise();
} catch (error) {
console.error(`delete-error: ${error}`);
throw new ResponseModel({}, 500, `delete-error: ${error}`);
}
};
getAllData = async (params: QueryItem) => {
try {
const _getAllData = async (params, startKey) => {
if (startKey) {
params.ExclusiveStartKey = startKey;
}
return documentClient.query(params).promise();
};
let lastEvaluatedKey = null;
let rows = [];
do {
const result = await _getAllData(params, lastEvaluatedKey);
rows = rows.concat(result.Items);
lastEvaluatedKey = result.LastEvaluatedKey;
} while (lastEvaluatedKey);
return rows;
} catch (error) {
console.error(`get-error: ${error}`);
throw new ResponseModel({}, 500, `get-error: ${error}`);
}
};
}
My create action is hiting following error :
query-error: ValidationException: Either the KeyConditions or KeyConditionExpression parameter must be specified in the request
How can i solved this , or is there a better approch
What I would suggest is using a Conditional Put.
AWS doc: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html#Expressions.ConditionExpressions.PreventingOverwrites
The PutItem operation overwrites an item with the same key (if it exists). If you want to avoid this, use a condition expression. This allows the write to proceed only if the item in question does not already have the same key.
aws dynamodb put-item \
--table-name ProductCatalog \
--item file://item.json \
--condition-expression "attribute_not_exists(Id)"
If the condition expression evaluates to false, DynamoDB returns the following error message: The conditional request failed.
With your code it would look something like that:
const params = {
TableName: ...,
Item: ...,
ConditionExpression: 'attribute_not_exists(#a)',
ExpressionAttributeNames: { '#a': '...' },
};
create = async (params: PutItem): Promise<PutItemOutput> => {
try {
return await documentClient.put(params).promise();
} catch (error) {
if (error is 'The conditional request failed') return; // pseudo code
console.error(`create-error: ${error}`);
throw new ResponseModel({}, 500, `create-error: ${error}`);
}
};

Merge array on different key in nodejs

dailyTask=[ { subject: 'Documentation', owner_id: 1 }, { subject: 'SERVICES', owner_id: 2 } ];
emails=[ { employee_id: 1, email_id: 'abcd#gmail.com' }, { employee_id: 2, email_id: 'abcdef#gmail.com' } ];
merge two arrays on keys owner_id and employee_id and the required result is shown below
output=[ {employee_id:1,owner_id:1,email_id:'abcd#gmail.com',subject:'Documentation'}, {employee_id:2,owner_id:2,email_id:'abcdef#gmail.com',subject:'SERVICES'} ];
You can achieve this using Array.reduce & Object.values
const dailyTasks = [{subject:'Documentation',owner_id:1},{subject:'SERVICES',owner_id:2}];
const emails = [{employee_id:1,email_id:'abcd#gmail.com'},{employee_id:2,email_id:'abcdef#gmail.com'}];
const mergeArrays = (tasks, emails) => {
return Object.values(tasks.reduce((acc,task) => {
//fetch the matching email from the list of emails based on employee_id and owner_id
const matchingEmail = emails.find(({employee_id}) => employee_id === task.owner_id);
//add/update the object with the task & matching email
acc[task.owner_id] = {
...(acc[task.owner_id] || {}),
...task,
...matchingEmail
}
return acc;
}, {}));
}
console.log(mergeArrays(dailyTasks, emails));
.as-console-wrapper {
max-height: 100% !important;
}

Paypal not returning custom variable

I'm trying to complete a paypal transaction using paypal-rest-sdk, everything is set up and working, however, I need to get the clientId back from paypal in the success route in order to save it in my client_feature_payment model. I found that we can set a "custom" field where we can set anything and that'll be sent back by paypal but this feautre is available in classic paypal sdk only and not available in rest-sdk one.
Is there any workaround for this?
//Paypal objects and methods from rest-sdk:
client_page: {
args: {
clientId: {
type: GraphQLString
}
},
type: ClientType,
resolve: async (_, args) => {
if (args.clientId) {
let clientMongoId = fromGlobalId(args.clientId).id;
let client = await Client.queryOne("id")
.eq(clientMongoId)
.exec();
let clientName = client.name;
let clientSecret = client.secret;
let company = await Company.queryOne("id")
.eq(client.companyId)
.exec();
let companyName = company.name;
let service = await Service.queryOne("id")
.eq(client.serviceId)
.exec();
let serviceName = service.name;
let clientFeature = await ClientFeature.query("clientId")
.eq(clientMongoId)
.exec();
let totalFeatures = [];
let clientFeatureId = [];
for (let i = 0; i < clientFeature.length; i++) {
clientFeatureId.unshift(clientFeature[i].id);
let feature = await Feature.query("id")
.eq(clientFeature[i].featureId)
.exec();
let newFeature;
feature.map(
feature =>
(newFeature = [
feature.name,
feature.cost,
feature.trial,
feature.frequency
])
);
totalFeatures.unshift(newFeature);
}
let trial, freq;
let cost = [];
totalFeatures.map(item => {
if (item[2] && item[3]) {
trial = item[2];
freq = item[3];
}
cost.unshift(item[1]);
});
const finalCost = cost.reduce((accumulator, currentValue) => {
return accumulator + currentValue;
}, 0);
let paypalFreq;
let frequencyInterval;
var isoDate = new Date(Date.now() + 1 * 60 * 1000);
switch (freq) {
case "bi-weekly":
paypalFreq = "DAY";
frequencyInterval = "7";
break;
case "monthly":
paypalFreq = "MONTH";
frequencyInterval = "1";
break;
case "3 months":
paypalFreq = "MONTH";
frequencyInterval = "3";
break;
case "6 months":
paypalFreq = "MONTH";
frequencyInterval = "6";
break;
case "1 year":
paypalFreq = "YEAR";
frequencyInterval = "1";
break;
default:
break;
}
var billingPlanAttributes = {
description:
"Create Plan for Trial & Frequency based payment for features and services used by customer",
merchant_preferences: {
auto_bill_amount: "yes",
cancel_url: "http://localhost:3000/cancel",
initial_fail_amount_action: "continue",
max_fail_attempts: "1",
return_url: "http://localhost:3000/success",
setup_fee: {
currency: "USD",
value: "0"
}
},
name: "Client Services & Features Charge",
payment_definitions: [
{
amount: {
currency: "USD",
value: finalCost
},
cycles: "0",
frequency: paypalFreq,
frequency_interval: frequencyInterval,
name: "Regular 1",
type: "REGULAR"
},
{
amount: {
currency: "USD",
value: "0"
},
cycles: "1",
frequency: "DAY",
frequency_interval: trial,
name: "Trial 1",
type: "TRIAL"
}
],
type: "INFINITE"
};
var billingPlanUpdateAttributes = [
{
op: "replace",
path: "/",
value: {
state: "ACTIVE"
}
}
];
var billingAgreementAttr = {
name: "Fast Speed Agreement",
description: "Agreement for Fast Speed Plan",
start_date: isoDate,
plan: {
id: "P-0NJ10521L3680291SOAQIVTQ"
},
payer: {
payment_method: "paypal",
payer_info: {
payer_id: clientMongoId
}
},
shipping_address: {
line1: "StayBr111idge Suites",
line2: "Cro12ok Street",
city: "San Jose",
state: "CA",
postal_code: "95112",
country_code: "US"
}
};
// Create the billing plan
let billingPlan = await new Promise((resolve, reject) => {
paypal.billingPlan.create(
billingPlanAttributes,
(error, billingPlan) => {
if (error) {
throw error;
} else {
resolve(billingPlan);
}
}
);
});
// let billingPlan = await billingPlanPromise;
// Activate the plan by changing status to Active
let billingAgreementAttributes = await new Promise(
(resolve, reject) => {
paypal.billingPlan.update(
billingPlan.id,
billingPlanUpdateAttributes,
(error, response) => {
if (error) {
throw error;
} else {
billingAgreementAttr.plan.id = billingPlan.id;
resolve(billingAgreementAttr);
}
}
);
}
);
// Use activated billing plan to create agreement
let approval_url = await new Promise((resolve, reject) => {
paypal.billingAgreement.create(
billingAgreementAttributes,
(error, billingAgreement) => {
if (error) {
throw error;
} else {
for (
var index = 0;
index < billingAgreement.links.length;
index++
) {
if (billingAgreement.links[index].rel === "approval_url") {
var approval_url = billingAgreement.links[index].href;
let newApprovalUrl =
approval_url + `&custom=${clientFeatureId}`;
resolve(newApprovalUrl);
// See billing_agreements/execute.js to see example for executing agreement
// after you have payment token
}
}
}
}
);
});
let data = {
companyId: companyName,
serviceId: serviceName,
name: clientName,
secret: clientSecret,
features: totalFeatures,
endpoint: approval_url
};
return Object.assign(data);
}
}
},
The success route:
app.get("/success", (req, res) => {
console.log("This is response", res);
let paymentToken = req.query.token;
paypal.billingAgreement.execute(paymentToken, {}, function(
error,
billingAgreement
) {
if (error) {
throw error;
} else {
console.log("Billing agreement", billingAgreement);
let date = billingAgreement.start_date;
let amountString =
billingAgreement.plan.payment_definitions[1].amount.value;
let trial =
billingAgreement.plan.payment_definitions[0].frequency_interval;
let frequencyInterval =
billingAgreement.plan.payment_definitions[1].frequency_interval;
let frequency = billingAgreement.plan.payment_definitions[1].frequency;
let totalFrequency = frequencyInterval + " " + frequency;
let period = [trial, totalFrequency];
let amount = parseInt(amountString);
try {
Payment.create({
id: uuidv1(),
date: date,
amount: amount,
period: period
});
} catch (err) {
throw new Error(err);
}
res.render("index");
}
});
});
My implementation looks very different, but I can output any payment details. My payment.execute() looks like so:
const express = require("express");
const paypal = require("paypal-rest-sdk");
const app = express;
paypal.configure({
mode: "sandbox", //sandbox or live
client_id:
"...",
client_secret:
"..."
});
app.set("view engine", "ejs");
app.get("/", (req, res) => res.render("index"));
app.post("/pay", (req, res) => {
const create_payment_json = {
intent: "sale",
payer: {
payment_method: "paypal"
},
redirect_urls: {
return_url: "http://localhost:3000/success",
cancel_url: "http://localhost:3000/cancel"
},
transactions: [
{
item_list: {
items: [
{
name: "Item",
sku: "001",
price: "3.33",
currency: "USD",
quantity: 1
}
]
},
amount: {
currency: "USD",
total: "3.33"
},
description:
"Hope this helps."
}
]
};
paypal.payment.create(create_payment_json, function(error, payment) {
if (error) {
throw error;
} else {
// console.log("Create Payment Response");
// console.log(payment.id);
// res.send('test')
for (let i = 0; i < payment.links.length; i++) {
if (payment.links[i].rel === "approval_url") {
res.redirect(payment.links[i].href);
}
}
}
});
});
app.get("/success", (req, res) => {
const payerId = req.query.PayerID;
const paymentId = req.query.paymentId;
const execute_payment_json = {
payer_id: payerId,
transactions: [
{
amount: {
currency: "USD",
total: "3.33"
}
}
]
};
paypal.payment.execute(paymentId, execute_payment_json, function(
error,
payment
) {
if (error) {
console.log(error.response);
throw error;
} else {
console.log(JSON.stringify(payment));
}
});
});
app.get("/cancel", (req, res) => {
res.send("Cancelled");
});
app.listen(3000, () => console.log("Server Started"));

Resources