I'm writing a script to test automatic. First I create a shipment with random items. After that I make a POST request. Everything is working fine, but the POST request keeps giving the same data. But my console prints other data.
Does anybody know what I am doing wrong? Is it maybe impossible to do POST requests in a for loop?
/// <reference types="cypress" />
describe('Create random shipments, Sign in, scan items, to transit', () => {
beforeEach(() => {
cy.visit('http://localhost:3000/')
})
it('Sign in, scan items, to transit', () => {
const username = '<username>'
const password = '<password>'
// Create default shipment
const shipmentText = '{'+
'"content": [],' +
'"date": "2022-05-05",' +
'"sender": { "company": "61d609e319b2c600129f71bb", "location": "61d609e319b2c600129f71bc" },' +
'"receiver": {},' +
'"orderNumber": "123456-20",' +
'"transportNumber": "TransportNumber {{routeNaam}}",' +
'"transportStopNumber": "Stop1",' +
'"note": "<noteText>"}';
const shipment = JSON.parse(shipmentText);
// Create locations Test20, Test19, Test17
const text = '{"locations":[' +
'{"company": "6228be12e4a3460011f94c13","location": "6228be12e4a3460011f94c14"},' +
'{"company": "6228a461e4a3460011f94676","location": "6228a461e4a3460011f94677"}]}';
const objLocations = JSON.parse(text);
// Create coreItems from .....
const itemText = '{"items":[' +
'{"coreItem": "6138c0ec64f3ea001196e5aa","quantity": 0,"status": "WHOLE","uniqueIds": []},' +
'{ "coreItem": "6138bff564f3ea001196e540", "quantity": 0, "status": "WHOLE", "uniqueIds": [] },' +
'{ "coreItem": "6138bfa464f3ea001196e51c", "quantity": 0, "status": "WHOLE", "uniqueIds": [] },' +
'{ "coreItem": "619e4fe2485d2b00112d0262", "quantity": 0, "status": "WHOLE" }]}';
const objItems = JSON.parse(itemText);
const laagCoreId = "6138c0ec64f3ea001196e5aa"
const middelCoreId = "6138bff564f3ea001196e540"
const hoogCoreId = "6138bfa464f3ea001196e51c"
const opzetCoreId = "619e4fe2485d2b00112d0262"
// Loop through the different companies
for (let i = 0; i < Object.values(objLocations.locations).length; i++) {
// Get company id and location
const element = Object.values(objLocations.locations)[i];
cy.log("company:" + element.company, "location:" + element.location)
// Loop through different coreItems
for (let i = 0; i < Object.values(objItems.items).length; i++) {
// Create random quantity between 1 - 10
Object.values(objItems.items)[i].quantity = Math.floor(Math.random() * 10) + 1;
let uids = []
let qty = 0
// Check item
// Create for each quantity a uid
if (Object.values(objItems.items)[i].coreItem == laagCoreId) {
qty = parseInt(Object.values(objItems.items)[i].quantity)
for (let i = 0; i < qty; i++) {
let uid = 20000000+Math.floor(Math.random() * 1000000) + 1;
uids.push(String(uid))
}
}
else if (Object.values(objItems.items)[i].coreItem == middelCoreId) {
qty = parseInt(Object.values(objItems.items)[i].quantity)
for (let i = 0; i < qty; i++) {
let uid = 30000000+Math.floor(Math.random() * 1000000) + 1;
uids.push(String(uid))
}
}
else if (Object.values(objItems.items)[i].coreItem == hoogCoreId) {
qty = parseInt(Object.values(objItems.items)[i].quantity)
for (let i = 0; i < qty; i++) {
let uid = 40000000+Math.floor(Math.random() * 1000000) + 1;
uids.push(String(uid))
}
}
// Add uids array to coreItems
Object.values(objItems.items)[i].uniqueIds = uids
}
// Copy shipment
let copyShipment = shipment
// Change content to coreItems with qty and uids
copyShipment.content = objItems.items
// Cange receiver
copyShipment.receiver = Object.values(objLocations.locations)[i]
cy.log(JSON.stringify(copyShipment))
cy.request({
method: 'POST',
url: '<url>',
headers: {
'Content-Type': 'application/json',
'api-token' : '<token>',
},
body: copyShipment
})
.should(
(response) => {
expect(response.status).to.eq(200)
},
)
.then(
(response) => {
cy.log(JSON.stringify(response))
}
)
}
})
})
For loops don't work nicely with asynchronous commands like cy.request(), but without running it I would expect the code you have to work.
One quick trick to try is to wrap the cy.request() in a cy.then(). This defers the request setup and hopefully gives you the correct copyShipment value each time.
...
cy.log(JSON.stringify(copyShipment))
cy.then(() => {
cy.request({
method: 'POST',
url: '<url>',
headers: {
...
},
body: copyShipment
})
.should(...)
})
Related
I am creating a script that takes an existing Google Calendar and matches another calendar with its information. For example, if an event is added in the existing calendar, the other calendar will add an event. If an event date is altered in the existing calendar, the other calendar will delete the event that previously matched and create one to match the altered event. I am having trouble with deleting the events.
I am unsure why I get the error "Failed with error listed_event.deleteEvent is not a function". I have tried for a few days and still have no clue what the issue could be in my code. The line in question is bolded with asterisks, although I have suspicions the issues lie elsewhere.
Any help would be greatly appreciated.
function CleaningCalendar() {
const CleaningId = 'primary';
// Add query parameters in optionalArgs
const HospitableId = 's4h3vvv6r47c3uqiknjhr4hrprgjua5g#import.calendar.google.com';
const optionalArgs = {
timeMin: (new Date()).toISOString(),
showDeleted: false,
singleEvents: true,
maxResults: 300,
orderBy: 'startTime'
// use other optional query parameter here as needed.
};
try {
// call Events.list method to list the calendar events using calendarId optional query parameter
var HospitableEvents = Calendar.Events.list(HospitableId, optionalArgs).items;
var CleaningEvents = Calendar.Events.list(CleaningId, optionalArgs).items;
const property_list = ["BREITHAUPT", "SPRING", "ELLIS 1", "ELLIS 2", "ELLIS 3", "ELLIS 5", "UNION 1", "UNION 2", "UNION 3"]
if (HospitableEvents.length === 0) {
Logger.log('No upcoming events found');
return;
}
for (let i = 0; i < HospitableEvents.length; i++){
event = HospitableEvents[i];
const start_date = event.start.dateTime;
//The fourth semi-colon in the Hospitable Calendar event description pertains to the property name
let first_colon_loc = event.description.indexOf(":");
let second_colon_loc = event.description.slice(first_colon_loc + 1).indexOf(":");
let third_colon_loc = event.description.slice(first_colon_loc + second_colon_loc + 2).indexOf(":");
let fourth_colon_loc = event.description.slice(first_colon_loc + second_colon_loc + third_colon_loc + 3).indexOf(":");
let property_colon_loc = first_colon_loc + second_colon_loc + third_colon_loc + fourth_colon_loc + 5;
let end_of_property_name = event.description.slice(property_colon_loc).indexOf("\n");
let property_name = event.description.slice(property_colon_loc, property_colon_loc + end_of_property_name);
var cleaning_event = {
'summary': property_name,
'location': '',
'description': '',
'start': {
'dateTime': start_date,
'timeZone': 'America/New_York'
},
'end': {
'dateTime': start_date,
'timeZone': 'America/New_York'
},
'recurrence': [
'RRULE:FREQ=DAILY;COUNT=1'
],
'attendees': [''],
'reminders': {
'useDefault': false,
'overrides': [
{'method': 'email', 'minutes': 24 * 60},
{'method': 'popup', 'minutes': 10}
]
}
};
if (property_list.includes(property_name)){
count = 0
for (let i = 0; i < CleaningEvents.length; i++){
if ((property_name == CleaningEvents[i].summary) && (event.start.dateTime == CleaningEvents[i].start.dateTime)){
count = count + 1;
continue;
}}
if (count == 0){
created_event = CalendarApp.getDefaultCalendar().createEvent(property_name,
new Date(start_date),
new Date(start_date));
}}
else{
Logger.log(HospitableEvents[i]);
Logger.log("The above is not valid");
}
}
for (let k = 0; k < CleaningEvents.length; k++){
listed_event = CleaningEvents[k];
var count = 0;
for (let j = 0; j < HospitableEvents.length; j++){
event = HospitableEvents[j];
const start_date = event.start.dateTime;
//The fourth semi-colon in the Hospitable Calendar event description pertains to the property name
let first_colon_loc = event.description.indexOf(":");
let second_colon_loc = event.description.slice(first_colon_loc + 1).indexOf(":");
let third_colon_loc = event.description.slice(first_colon_loc + second_colon_loc + 2).indexOf(":");
let fourth_colon_loc = event.description.slice(first_colon_loc + second_colon_loc + third_colon_loc + 3).indexOf(":");
let property_colon_loc = first_colon_loc + second_colon_loc + third_colon_loc + fourth_colon_loc + 5;
let end_of_property_name = event.description.slice(property_colon_loc).indexOf("\n");
let hospitable_name = event.description.slice(property_colon_loc, property_colon_loc + end_of_property_name);
if ((listed_event.summary == hospitable_name) && (listed_event.start.dateTime == event.start.dateTime)){
count = count + 1;
continue;
}
}
if (count == 0){
**listed_event.deleteEvent();**
Logger.log(listed_event);
}}
}
catch (err) {
// TODO (developer) - Handle exception from Calendar API
Logger.log('Failed with error %s', err.message);
}
}
I am trying to make a dice slash command with a command handler that posts a picture of the dice, but it says url1 undefined. When I try just posting the pictures directly, it says interaction failed: this interaction has already been acknowledged.
module.exports= {
name: "diceslash",
description:"dice slashcommand",
execute(interaction){
const diceroll = Math.floor(Math.random() * 6) + 1
const dices = Math.floor(Math.random() * 6) + 1
const ans = diceroll + dices;
if (diceroll == 1){
const url1 = 'https://imgur.com/a/YdAmiRe';
}
if (diceroll == 2){
const url1 = 'https://imgur.com/a/w35gKMR';
}
if (diceroll == 3){
const url1 = 'https://imgur.com/a/MkDVhQS';
}
if (diceroll == 4){
const url1 = 'https://imgur.com/a/WCuaCbL';
}
if (diceroll == 5){
const url1 = 'https://imgur.com/a/0xyPIkx';
}
if (diceroll == 6){
const url1 = 'https://imgur.com/a/urv1H42';
}
if (dices == 1){
const url2 = 'https://imgur.com/a/YdAmiRe';
}
if (dices == 2){
const url2 = 'https://imgur.com/a/w35gKMR';
}
if (dices == 3){
const url2 = 'https://imgur.com/a/MkDVhQS';
}
if (dices == 4){
const url2 = 'https://imgur.com/a/WCuaCbL';
}
if (dices == 5){
const url2 = 'https://imgur.com/a/0xyPIkx';
}
if (dices == 6){
const url2 = 'https://imgur.com/a/urv1H42';
}
interaction.reply ({content: url1+" "+url2})
interaction.reply({content: "you got "+ ans})
}
}
const is block scoped, so url1 and url2 are only available inside the if statements. Outside of those blocks, these variables are undefined.
You probably shouldn't use so many if statements though. Just store the images in an array or a map and pick one of those like this:
module.exports = {
name: 'diceslash',
description: 'dice slashcommand',
execute(interaction) {
const dices = [
'https://imgur.com/a/YdAmiRe',
'https://imgur.com/a/w35gKMR',
'https://imgur.com/a/MkDVhQS',
'https://imgur.com/a/WCuaCbL',
'https://imgur.com/a/0xyPIkx',
'https://imgur.com/a/urv1H42',
];
const dice1 = Math.floor(Math.random() * 6) + 1;
const dice2 = Math.floor(Math.random() * 6) + 1;
const ans = dice1 + dice2;
// array's index starts at zero
const url1 = dices[dice1 - 1];
const url2 = dices[dice2 - 1];
interaction.reply({ content: `${url1} ${url2} \n you got ${ans}` });
},
};
You could also store the dices in an object with their URLs and values and simplify it like this:
module.exports = {
name: 'diceslash',
description: 'dice slashcommand',
execute(interaction) {
const dices = [
{ url: 'https://imgur.com/a/YdAmiRe', value: 1 },
{ url: 'https://imgur.com/a/w35gKMR', value: 2 },
{ url: 'https://imgur.com/a/MkDVhQS', value: 3 },
{ url: 'https://imgur.com/a/WCuaCbL', value: 4 },
{ url: 'https://imgur.com/a/0xyPIkx', value: 5 },
{ url: 'https://imgur.com/a/urv1H42', value: 6 },
];
// helper function to pick a random item from an array
const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];
const dice1 = pick(dices);
const dice2 = pick(dices);
const ans = dice1.value + dice2.value;
interaction.reply({ content: `${dice1.url} ${dice2.url}` });
interaction.followUp({ content: `you got ${ans}` });
},
};
As for the second part of your question; the error is thrown because you try to reply to an interaction twice. An interaction can only be responded to once. You could either send a single response (see my first snippet) or use the followUp() method for the second message (see the second snippet).
I'm calling an API and getting data going through its pagination. When I get to the last page, though, the obejct giving me the last page is empty and it's throwing the following error: TypeError: Cannot convert undefined or null to object Besides, I don't any data from that last page.
Here's the pagination information I get:
{"count":100,"total":545,"_links":
{
"self":{
"href":"\/candidates?page=0&per_page=100"
},
"next":{
"href":"\/candidates?per_page=100"
},
"last":{
"href":"\/candidates?page=6&per_page=100"
}
},
Here's the code I'm using to get the data:
function allcandidates() {
const url = "https://api.catsone.com/v3/candidates";
const params = {
'muteHttpExceptions': true,
'method': 'GET',
'redirect': 'follow',
'headers': {
'Content-Type': 'application/json',
'Authorization': 'Token ' + API_KEY
}
};
let pageNum = 1;
let lastPgNo;
let data = {}, output = [];
do {
let currentUrl = url + '?' + 'per_page=100' + '&' + 'page=' + pageNum;
//One of their URL parameter is "per_page", which is 25 result/page and it go up to 100. I'm not sure if the fact that the last page doesn't have all 100 results may result in an error, too.
const response = UrlFetchApp.fetch(currentUrl, params);
const respCode = response.getResponseCode();
if (respCode != 200) {
Browser.msgBox('The server seems to be temporarily down. Please try again later.');
return;
}
//Gets the last page number
const getText = response.getContentText();
const lastPageObj = JSON.parse(getText)['_links']['last'];
const lastPgVal = Object.values(lastPageObj); //This is where the error occurs
const lastPgText = lastPgVal.toString();
lastPgNo = Number(lastPgText.split('?page=').pop().split('&')[0])
//Gets current page
const currentPageObj = JSON.parse(getText)['_links']['self'];
const currentPgVal = Object.values(currentPageObj);
const nextPgText = currentPgVal.toString();
var currentPgNo = Number(nextPgText.split('?page=').pop().split('&')[0])
const dataSet = JSON.parse(getText)['_embedded']['candidates'];
for (let i = 0; i < dataSet.length; i++) {
data = dataSet[i];
output.push([data.id]);
}
pageNum = pageNum + 1;
} while (pageNum <= lastPgNo);
}
You might use an if statement and continue. I.E. replace
const lastPgVal = Object.values(lastPageObj);
by
if(lastPageObj){
const lastPgVal = Object.values(lastPageObj);
} else {
continue;
}
Another option is to use try...catch
Resources
https://developer.mozilla.org/en-US/docs/Glossary/Truthy
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
I try to export all contacts from hubspot to spreadsheet,
but I do not know how I can do it
You would be wise to use the people api since the Contact API will begin to be shut down after June 15. I've provided a function that I use.
You welcome to it.
Use what you wish. Modify as needed.
function displayCurrentContacts() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Contacts');
sh.clearContents();
const vs = [['Name', 'Emails']];
const resp = People.People.Connections.list('people/me', { personFields: "emailAddresses,names,organizations" });
//Logger.log(resp);
const data = JSON.parse(resp);
let m = 0;
let n = 0;
data.connections.forEach((ob1, i) => {
if (ob1.emailAddresses && ob1.emailAddresses.length > 0) {
let emails = [... new Set(ob1.emailAddresses.map(ob2 => ob2.value))];//used set to insure I get unique list
//let emails = ob1.emailAddresses.map(ob2 => ob2.value);
let name;
m += emails.length;
if (ob1.names && ob1.organizations) {
name = ob1.names[0].displayName + '\n' + ob1.organizations[0].name;
++n;
} else if (ob1.names) {
name = ob1.names[0].displayName;
++n;
} else if (ob1.organizations) {
name = ob1.organizations[0].name;
++n;
}
vs.push([name, emails.sort().join('\n')])
}
});
vs.push([n, m])
sh.getRange(1, 1, vs.length, vs[0].length).setValues(vs)
sh.getRange(2, 1, sh.getLastRow() - 2, sh.getLastColumn()).sort({ column: 1, sortAscending: true });
}
Hi I'm currently working on a Twitter bot with the Twitter API and Node.JS. I want the bot to return all of my followers and some of their features in an javascript object. Something like :
{['id', 'screen_name', 'name', 'screen_name', 'followers_count',
'friends_count']}
RN my code is :
var Twitter = new TwitterPackage(config);
var options =
{
screen_name: 'mowsolicious',
};
Twitter.get('followers/ids', options, function (err, data) { // returns a list of ids
var nbFollowers = data.ids.length
var id = []
console.log(nbFollowers) // how many followers I have
for (i=0 ; i <= nbFollowers ; i++) {
ids = data.ids
var id = ids[i]
Twitter.get('users/show/' + id, function(err, data) {
console.log(id + " - " + data.name + " - " + data.screen_name + " - " + data.followers_count + " - " + data.friends_count)
})
}
})
I'm pretty sure something is terribly wrong with my method (more precisely when I put the Twitter.get thing in the loop) and it returns a bunch of undefined in the console.
I tried to work with the API doc but I'm experiencing some troubles understanding it. If someone could help that would be great.
Thank you
Most likely, you get undefined because the user is not found :
[ { code: 50, message: 'User not found.' } ]
Checking err variable would take care of that. But looking at GET followers/id documentation, you should use GET users/lookup to efficiently request mutliple user objects (up to 100 user per request with user id delimited by comma)
Also, I assume you'd like a unique callback to be called when all requests are completed, using Promises will take care of that :
var res_array = [];
function getUserInfo(id_list) {
return Twitter.get('users/lookup', {
"user_id": id_list
}).then(function(data) {
res_array.push(data);
})
.catch(function(error) {
throw error;
})
}
Twitter.get('followers/ids', function(err, data) {
if (err) {
console.log(err);
return;
}
console.log("total followers : " + data.ids.length);
var requestNum = Math.floor(data.ids.length / 100);
var remainder = data.ids.length % 100;
var promises_arr = [];
for (var i = 0; i < requestNum; i++) {
promises_arr.push(getUserInfo(data.ids.slice(i * 100, i * 100 + 100).join(",")));
}
if (remainder != 0) {
promises_arr.push(getUserInfo(data.ids.slice(requestNum * 100, requestNum * 100 + 100).join(",")));
}
Promise.all(promises_arr)
.then(function() {
for (var i in res_array) {
for (var j in res_array[i]) {
var user = res_array[i][j];
console.log(user.id + " - " +
user.name + " - " +
user.screen_name + " - " +
user.followers_count + " - " +
user.friends_count)
}
}
})
.catch(console.error);
})
List of followers can be retrieved with superface sdk , try it based on the example below
npm install #superfaceai/one-sdk
npx #superfaceai/cli install social-media/followers
const { SuperfaceClient } = require('#superfaceai/one-sdk');
const sdk = new SuperfaceClient();
async function run() {
// Load the installed profile
const profile = await sdk.getProfile('social-media/followers');
// Use the profile
const result = await profile
.getUseCase('GetFollowers')
.perform({
profileId: '429238130'
});
return result.unwrap();
}
run();
This works pretty fine
import fetch from 'node-fetch'
async function getFollowers(username) {
const response = await fetch(`https://api.twitter.com/1.1/followers/list.json?screen_name=${username}`, {
headers: {
Authorization: `Bearer ${<yourbearertoken>}`
}
});
// Parse the response as JSON
const data = await response.json();
return data.users;
}
const followers = await getFollowers("<username>");