How do you download an attachment with Gmail API with nodejs? - javascript

Im trying to make a node app on my local computer that does this:
1) Looks at my gmail inbox.
2) If an email has a certain label and an attachment, download it.
Im on step 2.
The part Im confused about is the part about 'parts'.
https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get
Googles sample code:
function getAttachments(userId, message, callback) {
var parts = message.payload.parts;
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
if (part.filename && part.filename.length > 0) {
var attachId = part.body.attachmentId;
var request = gapi.client.gmail.users.messages.attachments.get({
'id': attachId,
'messageId': message.id,
'userId': userId
});
request.execute(function(attachment) { // <--- that attachment param
callback(part.filename, part.mimeType, attachment);
});
}
}
}
It seems that 'attachment' contains the attachment data.
Here is my code:
const gmail = google.gmail({version: 'v1', auth});
gmail.users.messages.list({
userId: 'me',
'q':'subject:my-test has:nouserlabels has:attachment'
}, (err, res) => {
if (err) return console.log('1 The API returned an error: ' + err);
const msgs = res.data.messages;
if(typeof msgs !== 'undefined'){
console.log('Messages:');
msgs.forEach( msg => {
console.log(`- ${msg.id}`);
gmail.users.messages.get({
userId: 'me',
id: msg.id,
format:'full'
},(err, res) => {
if (err) return console.log('2 The API returned an error: ' + err);
// Wheres the data????? //
console.log('A')
console.log(res.data.payload.parts)
console.log('B')
console.log(res.data.payload.parts[1])
console.log('C')
console.log(res.data.payload.parts[1].body)
})
});
} else {
console.log('no messages found')
}
});

I've just used this to retrieve the docs from my favorite accountant.
const fsPromises = require('fs/promises');
const path = require('path');
const {google} = require('googleapis');
const readline = require('readline');
const fs = require('fs');
.... code from https://developers.google.com/gmail/api/quickstart/nodejs for auth
const fromEmail = process.argv[2];
const shortFromEmail = fromEmail.substring(0, fromEmail.indexOf('#'));
/**
* Lists the labels in the user's account.
*
* #param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
async function main(auth) {
const gmail = google.gmail({version: 'v1', auth})
// console.log('list messages with attachments auth: ' + JSON.stringify(auth))
const {data} = await gmail.users.messages.list({
userId: 'me',
'q':`from:${fromEmail} has:nouserlabels has:attachment`,
// maxResults: 5
});
console.log(data);
let {messages} = data;
await messages.reduce(async function (accProm, messageId) {
await accProm;
const {data: message} = await gmail.users.messages.get({
userId: 'me',
id: messageId.id,
format: 'full'
});
// console.log(JSON.stringify(message, null, 2));
let messagePayloadParts = message.payload.parts
const attachments = await messagePayloadParts.reduce(async function (acc2Prom, part) {
const acc2 = await acc2Prom;
if (!part.body.size || part.body.attachmentId == undefined) {
return acc2;
}
const internalDate = new Date(parseInt(message.internalDate, 10));
const datestring = internalDate.getFullYear() + " " + (internalDate.getMonth()+1).toString().padStart(2, "0") + " " + internalDate.getDate().toString().padStart(2, "0");
console.log(datestring, shortFromEmail, part.filename, part)
let fileExt;
switch (part.mimeType) {
case 'application/octet-stream': fileExt = ''; break;
case 'application/pdf': fileExt = 'pdf'; break;
case 'message/rfc822': fileExt = 'eml'; break;
case 'image/jpeg': fileExt = 'jpg'; break;
case 'image/png': fileExt = 'png'; break;
case 'application/msword': fileExt = 'doc'; break;
default: console.error('unknownMimeType', part.mimeType); boom;
}
const dirname = `${datestring} ${shortFromEmail}`;
const filename = part.filename ? part.filename : `noname_${part.body.attachmentId.substring(0,8)}.${fileExt}`
const attachmentPath = path.join(dirname, filename);
const s = await fsPromises.stat(attachmentPath).catch(e => undefined);
if (s) { return acc2 };
const {data: attachment} = await gmail.users.messages.attachments.get({
userId: 'me',
messageId: message.id,
id: part.body.attachmentId,
});
const { size, data: dataB64 } = attachment;
await fsPromises.mkdir(dirname, {recursive: true});
await fsPromises.writeFile(attachmentPath, Buffer.from(dataB64, 'base64'));
return acc2;
// console.log('callback: ' + JSON.stringify(attachments))
}, Promise.resolve([]));
}, Promise.resolve());
}

Related

It doesn't show me the data in the terminal when i send the post request twice

I am trying to create a middleware that receive a form-data and return the fieldname, contentType and the value. So when I send the firts post the data view in the terminal but if I send the same request again doesn't show me the data in the terminal.
And if a toggle the image, the data come show in the terminal
This is my code:
server:
const express = require("express");
const Upes = require("../upes");
const app = express();
const start = new Upes();
app.post("/", start.setup.bind(start), (req, res) => {
res.send("all right");
});
app.listen(3000, () => {
console.log("The server is active");
});
the index of my middleware:
const getData = require("./utils/getData");
const parseContentType = require("./utils/parseContentType");
class Upes {
setup(req, res, next) {
const contentType = parseContentType(req.headers["content-type"]);
if (!contentType) {
throw new Error("Malformed content-type");
}
const SUBTYPES = ["form-data", "x-www-form-urlencoded"];
if (!SUBTYPES.includes(contentType.subtype)) {
throw new Error(
"The subtypes does not match the following subtypes: " + SUBTYPES
);
}
getData(req, contentType.params.boundary, (data) => {
console.log(data);
});
next();
}
}
module.exports = Upes;
The function that receive the data and processes it:
function getData(req, boundary, callback) {
let chunk = "";
let data = [];
req.on("data", (buffer) => {
chunk += buffer.toString();
});
req.on("end", () => {
// Split the chunk in blocks
const blocks = getBlock(chunk, boundary);
blocks.forEach((block) => {
let [params, value] = block.split("\r\n\r\n");
params = params.split(";");
let fieldname = params[1].split("=")[1].replaceAll('"', "");
let contentType = () => {
const condition = params.length === 3;
if (condition) {
let type = params[2].split(":")[1].replace(" ", "");
return type;
}
return "text-plain";
};
const payload = {
fieldname: fieldname,
contentType: contentType(),
value: "", // value.replace("\r\n", "")
};
data.push(payload);
});
callback(data);
});
}
function getBlock(body, boundary) {
boundary = boundary.replaceAll("-", "");
return body.replaceAll("-", "").split(`${boundary}`).slice(1, -1);
}
module.exports = getData;
Send the same request 20 times
I don't know what happend, please can someone help me?

Ledger device: Invalid data received (0x6a80) #404

When I try to transfer chainlink on goerli network with ledger I get this error:
TransportStatusError: Ledger device: Invalid data received (0x6a80)
contractAddress: 0x326c977e6efc84e512bb9c30f76e30c160ed06fb
I can send dai but when i wanna send chainlink I get this error.
My environment:
windows
Device (Nano S)
I'm using this libraries :
{
"#ledgerhq/hw-app-eth": "^6.31.0",
"#ledgerhq/hw-transport-webhid": "^6.27.11",
}
this is the transaction:
{
"gasLimit": "0x8792",
"to": "0x326c977e6efc84e512bb9c30f76e30c160ed06fb",
"data": "0xa9059cbb00000000000000000000000014be4dc6e2e7562eb80f20fa4f8dbd072b8a56670000000000000000000000000000000000000000000000000de0b6b3a7640000",
"nonce": "0x4b",
"chainId": "0x5",
"type": 2,
"maxPriorityFeePerGas": "0x59682f00",
"maxFeePerGas": "0x101f0aef2a"
}
and this is the code
const web3 = new Web3(getNet(secondAddress));
const abi = getAbi8();
const contract = new web3.eth.Contract(abi, contractAddress.toLowerCase(), { from: wallet.address });
const decimals = await contract.methods.decimals().call();
const value = amount * (10 ** decimals);
const gas = await contract.methods.transfer(toAddress.toLowerCase(), String(value)).estimateGas({ from: wallet.address });
const gasPrice = await web3.eth.getGasPrice();
const transactionCount = await web3.eth.getTransactionCount(wallet.address, 'pending');
const chainId = await getChainId();
let feeData = await getFeeData(secondAddress);
let transaction = {
gasLimit: ethers.utils.hexlify(gas),
to: contractAddress,
data: (contract.methods.transfer(toAddress.toLowerCase(), web3.utils.toHex(value)).encodeABI()),
gasPrice: web3.utils.toHex(Math.floor(gasPrice * 1.3)),
nonce: web3.utils.toHex(transactionCount),
chainId: web3.utils.toHex(chainId),
type: 2
}
if (feeData.maxPriorityFeePerGas) {
transaction.maxPriorityFeePerGas = web3.utils.toHex(feeData.maxPriorityFeePerGas);
delete transaction.gasPrice;
}
if (feeData.maxFeePerGas) {
transaction.maxFeePerGas = web3.utils.toHex(feeData.maxFeePerGas);
}
if (!feeData.maxPriorityFeePerGas) {
transaction.gasPrice = feeData.gasPrice;
}
const gasData = localStorage.getItem('user-gas');
if (gasData) {
const _gasData = JSON.parse(gasData);
if (_gasData.gasLimit) {
transaction.gas = web3.utils.toHex(_gasData?.gasLimit);
}
if (_gasData.gasPrice && !feeData.maxPriorityFeePerGas) {
transaction.gasPrice = web3.utils.toHex(_gasData?.gasPrice * 10 ** 9);
}
if (_gasData.maxGas) {
transaction.maxFeePerGas = web3.utils.toHex(_gasData?.maxGas * 10 ** 9);
}
if (_gasData.maxPriorityFee) {
transaction.maxPriorityFeePerGas = web3.utils.toHex(_gasData?.maxPriorityFee * 10 ** 9);
}
}
if (customGas && !feeData.maxFeePerGas) {
/// convert gasprice from gwei to wei
transaction.gasPrice = web3.utils.toHex(customGas.gasPrice);
}
else if (customGas && feeData.maxFeePerGas) {
transaction.maxPriorityFeePerGas = web3.utils.toHex(customGas.priorityFeePerGas);
}
console.log(transaction)
const serializedTx = ethers.utils.serializeTransaction(transaction).slice(2)
await forgetDevice()
let appEth
try {
let transport = await Transport.request();
appEth = await new Eth(transport)
}
catch (err) {
throw 'Unable to connect with your ledger device , make sure your device is connected and keep the app open';
}
let path = `/44'/60'/${wallet.id - 1}'/0/0`;
if (wallet.ledgerType == 3) {
path = `44'/60'/0'/0/${wallet.id - 1}`;
}
else if (wallet.ledgerType == 2) {
path = `m/44'/60'/0'/${wallet.id - 1}`;
}
const resolution = await ledgerService.resolveTransaction(
serializedTx,
appEth.loadConfig,
{
externalPlugins: true,
erc20: true,
nft: true,
}
);
const signature = await appEth.signTransaction(path, serializedTx, resolution)
signature.r = "0x" + signature.r;
signature.s = "0x" + signature.s;
signature.v = parseInt("0x" + signature.v);
signature.from = wallet.address;
const signedTx = ethers.utils.serializeTransaction(transaction, signature);
return new Promise((resolve, reject) => {
web3.eth.sendSignedTransaction(signedTx, (err, hash) => {
if (!err) {
resolve(hash);
}
else {
reject(err)
}
})
})

send data file to another computer with RTCPeerConnection?

how can I change the code so that the computer1 code connects to the code of computer 2(computer1 and computer2 are not the same computers but on the same network).
It works locally but not when it's two different computers
computer 1 and computer2 code that is used for the connection is defined below
this is the code that does the networking on computer1
async function createConnection() {
abortButton.disabled = false;
sendFileButton.disabled = true;
localConnection = new RTCPeerConnection();//this is the line I think I need to change
console.log('Created local peer connection object localConnection');
sendChannel = localConnection.createDataChannel('sendDataChannel');
sendChannel.binaryType = 'arraybuffer';
console.log('Created send data channel');
sendChannel.addEventListener('open', onSendChannelStateChange);
sendChannel.addEventListener('close', onSendChannelStateChange);
sendChannel.addEventListener('error', onError);
localConnection.addEventListener('icecandidate', async event => {
console.log('Local ICE candidate: ', event.candidate);
await localConnection.addIceCandidate(event.candidate);
});
this is the part of the program that have the role to receive the request and the file data on the computer2
async function server(){
remoteConnection = new RTCPeerConnection();
alert("start");
console.log('Created remote peer connection object remoteConnection');
remoteConnection.addEventListener('icecandidate', async event => {
console.log('Remote ICE candidate: ', event.candidate);
await localConnection.addIceCandidate(event.candidate);
});
remoteConnection.addEventListener('datachannel', receiveChannelCallback);
}
the code that I modified(main.js)
/* eslint no-unused-expressions: 0 */
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
*/
'use strict';
let localConnection;
let remoteConnection;
let sendChannel;
let receiveChannel;
let fileReader;
const bitrateDiv = document.querySelector('div#bitrate');
const fileInput = document.querySelector('input#fileInput');
const abortButton = document.querySelector('button#abortButton');
const downloadAnchor = document.querySelector('a#download');
const sendProgress = document.querySelector('progress#sendProgress');
const receiveProgress = document.querySelector('progress#receiveProgress');
const statusMessage = document.querySelector('span#status');
const sendFileButton = document.querySelector('button#sendFile');
let receiveBuffer = [];
let receivedSize = 0;
let bytesPrev = 0;
let timestampPrev = 0;
let timestampStart;
let statsInterval = null;
let bitrateMax = 0;
server();
sendFileButton.addEventListener('click', () => createConnection());
fileInput.addEventListener('change', handleFileInputChange, false);
abortButton.addEventListener('click', () => {
if (fileReader && fileReader.readyState === 1) {
console.log('Abort read!');
fileReader.abort();
}
});
async function handleFileInputChange() {
const file = fileInput.files[0];
if (!file) {
console.log('No file chosen');
} else {
sendFileButton.disabled = false;
}
}
async function server(){
//const servers = {
//iceServers: [
// {
// urls: ['stun:stun1.l.google.com:19302', //'stun:stun2.l.google.com:19302'],
// },
//],
//iceCandidatePoolSize: 10,
//};
remoteConnection = new RTCPeerConnection();
alert("start");
console.log('Created remote peer connection object remoteConnection');
remoteConnection.addEventListener('icecandidate', async event => {
console.log('Remote ICE candidate: ', event.candidate);
await localConnection.addIceCandidate(event.candidate);
});
remoteConnection.addEventListener('datachannel', receiveChannelCallback);
}
async function createConnection() {
abortButton.disabled = false;
sendFileButton.disabled = true;
//const servers = {
//iceServers: [
// {
// urls: ['stun:stun1.l.google.com:19302', //'stun:stun2.l.google.com:19302'],
// },
//],
//iceCandidatePoolSize: 10,
//};
localConnection = new RTCPeerConnection();
console.log('Created local peer connection object localConnection');
sendChannel = localConnection.createDataChannel('sendDataChannel');
sendChannel.binaryType = 'arraybuffer';
console.log('Created send data channel');
sendChannel.addEventListener('open', onSendChannelStateChange);
sendChannel.addEventListener('close', onSendChannelStateChange);
sendChannel.addEventListener('error', onError);
localConnection.addEventListener('icecandidate', async event => {
console.log('Local ICE candidate: ', event.candidate);
await localConnection.addIceCandidate(event.candidate);
});
try {
const offer = await localConnection.createOffer();
await gotLocalDescription(offer);
} catch (e) {
console.log('Failed to create session description: ', e);
}
fileInput.disabled = true;
}
function sendData() {
const file = fileInput.files[0];
console.log(`File is ${[file.name, file.size, file.type, file.lastModified].join(' ')}`);
// Handle 0 size files.
statusMessage.textContent = '';
downloadAnchor.textContent = '';
if (file.size === 0) {
bitrateDiv.innerHTML = '';
statusMessage.textContent = 'File is empty, please select a non-empty file';
closeDataChannels();
return;
}
sendProgress.max = file.size;
receiveProgress.max = file.size;
const chunkSize = 16384;
fileReader = new FileReader();
let offset = 0;
fileReader.addEventListener('error', error => console.error('Error reading file:', error));
fileReader.addEventListener('abort', event => console.log('File reading aborted:', event));
fileReader.addEventListener('load', e => {
console.log('FileRead.onload ', e);
sendChannel.send(e.target.result);
offset += e.target.result.byteLength;
sendProgress.value = offset;
if (offset < file.size) {
readSlice(offset);
}
});
const readSlice = o => {
console.log('readSlice ', o);
const slice = file.slice(offset, o + chunkSize);
fileReader.readAsArrayBuffer(slice);
};
readSlice(0);
}
function closeDataChannels() {
console.log('Closing data channels');
sendChannel.close();
console.log(`Closed data channel with label: ${sendChannel.label}`);
sendChannel = null;
if (receiveChannel) {
receiveChannel.close();
console.log(`Closed data channel with label: ${receiveChannel.label}`);
receiveChannel = null;
}
localConnection.close();
remoteConnection.close();
localConnection = null;
remoteConnection = null;
console.log('Closed peer connections');
// re-enable the file select
fileInput.disabled = false;
abortButton.disabled = true;
sendFileButton.disabled = false;
}
async function gotLocalDescription(desc) {
await localConnection.setLocalDescription(desc);
console.log(`Offer from localConnection\n ${desc.sdp}`);
await remoteConnection.setRemoteDescription(desc);
try {
const answer = await remoteConnection.createAnswer();
await gotRemoteDescription(answer);
} catch (e) {
console.log('Failed to create session description: ', e);
}
}
async function gotRemoteDescription(desc) {
await remoteConnection.setLocalDescription(desc);
console.log(`Answer from remoteConnection\n ${desc.sdp}`);
await localConnection.setRemoteDescription(desc);
}
function receiveChannelCallback(event) {
console.log('Receive Channel Callback');
receiveChannel = event.channel;
receiveChannel.binaryType = 'arraybuffer';
receiveChannel.onmessage = onReceiveMessageCallback;
receiveChannel.onopen = onReceiveChannelStateChange;
receiveChannel.onclose = onReceiveChannelStateChange;
receivedSize = 0;
bitrateMax = 0;
downloadAnchor.textContent = '';
downloadAnchor.removeAttribute('download');
if (downloadAnchor.href) {
URL.revokeObjectURL(downloadAnchor.href);
downloadAnchor.removeAttribute('href');
}
}
function onReceiveMessageCallback(event) {
console.log(`Received Message ${event.data.byteLength}`);
receiveBuffer.push(event.data);
receivedSize += event.data.byteLength;
receiveProgress.value = receivedSize;
// we are assuming that our signaling protocol told
// about the expected file size (and name, hash, etc).
const file = fileInput.files[0];
if (receivedSize === file.size) {
const received = new Blob(receiveBuffer);
receiveBuffer = [];
downloadAnchor.href = URL.createObjectURL(received);
downloadAnchor.download = file.name;
downloadAnchor.textContent =
`Click to download '${file.name}' (${file.size} bytes)`;
downloadAnchor.style.display = 'block';
const bitrate = Math.round(receivedSize * 8 /
((new Date()).getTime() - timestampStart));
bitrateDiv.innerHTML =
`<strong>Average Bitrate:</strong> ${bitrate} kbits/sec (max: ${bitrateMax} kbits/sec)`;
if (statsInterval) {
clearInterval(statsInterval);
statsInterval = null;
}
closeDataChannels();
}
}
function onSendChannelStateChange() {
if (sendChannel) {
const {readyState} = sendChannel;
console.log(`Send channel state is: ${readyState}`);
if (readyState === 'open') {
sendData();
}
}
}
function onError(error) {
if (sendChannel) {
console.error('Error in sendChannel:', error);
return;
}
console.log('Error in sendChannel which is already closed:', error);
}
async function onReceiveChannelStateChange() {
if (receiveChannel) {
const readyState = receiveChannel.readyState;
console.log(`Receive channel state is: ${readyState}`);
if (readyState === 'open') {
timestampStart = (new Date()).getTime();
timestampPrev = timestampStart;
statsInterval = setInterval(displayStats, 500);
await displayStats();
}
}
}
// display bitrate statistics.
async function displayStats() {
if (remoteConnection && remoteConnection.iceConnectionState === 'connected') {
const stats = await remoteConnection.getStats();
let activeCandidatePair;
stats.forEach(report => {
if (report.type === 'transport') {
activeCandidatePair = stats.get(report.selectedCandidatePairId);
}
});
if (activeCandidatePair) {
if (timestampPrev === activeCandidatePair.timestamp) {
return;
}
// calculate current bitrate
const bytesNow = activeCandidatePair.bytesReceived;
const bitrate = Math.round((bytesNow - bytesPrev) * 8 /
(activeCandidatePair.timestamp - timestampPrev));
bitrateDiv.innerHTML = `<strong>Current Bitrate:</strong> ${bitrate} kbits/sec`;
timestampPrev = activeCandidatePair.timestamp;
bytesPrev = bytesNow;
if (bitrate > bitrateMax) {
bitrateMax = bitrate;
}
}
}
}
Thanks for helping
You can read about peer connections where every peer connection is handled by the RTCPeerConnection object and it defines how the peer connection is set up and how it should include the information about the ICE servers to use.
You can define the ICE servers as following:
localConnection = new RTCPeerConnection({iceServers: [{ url: "stun:"+ ip +":8003" }]})
or
localConnection = new RTCPeerConnection({iceServers: [{ url: + ip + ':port' }]})
or
var servers = {
iceTransportPolicy: 'relay',
iceServers: [{
urls: "turn:[" + ip + "]:3478",
username: "username",
credential: "password"
}
]};
var localConnection = new RTCPeerConnection(servers);
Moreover, You can find the full code here or
here under the folder name filetransfer .

How to make api endpoint target user's localhost when deployed to Heroku

I have this api which works fine when running locally. But, once it is deployed to Heroku i get a error 503 which is because it tries to target localhost on Heroku's server and not the user's localhost. Is there a way to make this target the user's localhost instead?
The frontend is React. Here's the code in React that fetches this api every 5sec.
axiosFunc = () => {
const { user } = this.props.auth;
console.log(user);
axios.get(`api/avaya/${user.id}`).then((res) => console.log(res));
};
timer = (time) => {
const date = new Date(time);
return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
};
componentDidMount() {
this.axiosFunc();
this.interval = setInterval(this.axiosFunc, 5000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
and this is the API on the backend with express
const router = require("express").Router();
const xml2js = require("xml2js");
const Avaya = require("../../models/Avaya");
const User = require("../../models/User");
router.route("/:id").get(async (req, res) => {
const user = await User.findById(req.params.id);
const axios = require("axios");
axios({
method: "post",
baseURL: `http://127.0.0.1:60000/onexagent/api/registerclient?name=${user.username}`,
timeout: 2000,
})
.then((reg) => {
xml2js
.parseStringPromise(reg.data, { mergeAttrs: true })
.then((result) => {
if (result.RegisterClientResponse.ResponseCode[0] === "0") {
const clientId = result.RegisterClientResponse.ClientId[0];
user.avayaClientId = clientId;
user.save();
}
const clientId = user.avayaClientId;
axios({
method: "post",
url: `http://127.0.0.1:60000/onexagent/api/nextnotification?clientid=${clientId}`,
}).then((notification) => {
xml2js
.parseStringPromise(notification.data, { mergeAttrs: true })
.then((result) => {
const notifType = [];
const notifDetails = [];
for (let i in result.NextNotificationResponse) {
notifType.push(i);
}
const arranged = {
NotificationType: notifType[1],
ResponseCode:
result.NextNotificationResponse[notifType[0]][0],
};
for (let i in result.NextNotificationResponse[
notifType[1]
][0]) {
notifDetails.push(i);
}
for (let i = 0; i < notifDetails.length; i++) {
arranged[[notifDetails[i]][0]] =
result.NextNotificationResponse[notifType[1]][0][
notifDetails[i]
][0];
}
for (let i in arranged) {
if ("Outbound" in arranged) {
arranged.CallType = "Outbound";
} else if ("Inbound" in arranged)
arranged.CallType = "Inbound";
else {
arranged.CallType = " ";
}
}
if (
arranged.NotificationType === "VoiceInteractionCreated" ||
arranged.NotificationType === "VoiceInteractionMissed" ||
arranged.NotificationType === "VoiceInteractionTerminated"
) {
const newLogs = new Avaya({
notification: arranged,
});
newLogs.owner = user;
newLogs.save();
user.avayaNotifications.push(newLogs),
user
.save()
.then((logs) => res.json(logs))
.catch((err) => res.status(400).json("Error: " + err));
} else {
res.send("Nothing to record");
}
});
});
});
})
.catch((err) => res.status(503).json(err));
});
router.route("/history/:username").get(async (req, res) => {
const user = await User.findOne({ username: [`${req.params.username}`] });
Avaya.find({ owner: [`${await user.id}`] }).then((user) => res.json(user));
});
module.exports = router;
EDIT: I was able to fix thanks to #Molda
using fetch instead of axios doesn't result in cors error.
New frontend code
getLogs = async () => {
const { user } = this.props.auth;
const reg = await fetch(
`http://127.0.0.1:60000/onexagent/api/registerclient?name=${user.id}`
);
let regData = await reg.text();
let regxml = new XMLParser().parseFromString(regData);
if (regxml.attributes.ResponseCode === "0") {
axios.post(`/api/avaya/register/${user.id}`, regxml);
console.log(regxml.attributes.ResponseCode);
}
let resp = await fetch(`/api/avaya/getid/${user.id}`);
let clientId = await resp.text();
let logs = await fetch(
`http://127.0.0.1:60000/onexagent/api/nextnotification?clientid=${clientId}`
);
let data = await logs.text();
var xml = new XMLParser().parseFromString(data);
axios.post(`/api/avaya/getlogs/${user.id}`, xml);
};
timer = (time) => {
const date = new Date(time);
return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
};
componentDidMount() {
this.getLogs();
this.interval = setInterval(this.getLogs, 5000);
}
New backend code:
const router = require("express").Router();
const Avaya = require("../../models/Avaya");
const User = require("../../models/User");
router.route("/register/:id").post(async (req, res) => {
const user = await User.findById(req.params.id);
const clientId = req.body.attributes.ClientId;
user.avayaClientId = clientId;
user.save();
});
router.route("/getid/:id").get(async (req, res) => {
const user = await User.findById(req.params.id);
res.send(user.avayaClientId);
});
router.route("/getlogs/:id").post(async (req, res) => {
const user = await User.findById(req.params.id);
const arranged = {
NotificationType: req.body.children[0].name,
ResponseCode: req.body.attributes.ResponseCode,
CallType: " ",
};
for (let i in req.body.children[0].attributes) {
if (i === "Outbound") {
arranged.CallType = "Outbound";
}
if (i === "Inbound") {
arranged.CallType = "Inbound";
}
arranged[i] = req.body.children[0].attributes[i];
}
console.log(arranged);
if (
arranged.NotificationType === "VoiceInteractionCreated" ||
arranged.NotificationType === "VoiceInteractionMissed" ||
arranged.NotificationType === "VoiceInteractionTerminated"
) {
const newLogs = new Avaya({
notification: arranged,
});
newLogs.owner = user;
newLogs.save();
user.avayaNotifications.push(newLogs),
user
.save()
.then((logs) => res.json(logs))
.catch((err) => res.status(400).json("Error: " + err));
} else {
res.send("Nothing to record");
}
});
router.route("/history/:username").get(async (req, res) => {
const user = await User.findOne({ username: [`${req.params.username}`] });
Avaya.find({ owner: [`${await user.id}`] }).then((user) => res.json(user));
});
module.exports = router;
I really don't get the part of (requesting with Axios in API)
Is this a third party API ?
But I suggest you to use (.env) which is a file in your root folder contains the development config like base URLs, expire tokens, API keys ... etc
and when you upload to Heroku you have to make a (.env) in Heroku app and but your config
Let's take an example
in my development mode, my .env looks like
app_url = localhost:4000
port = 4000
db = development_api
db_username = root
db_password =
db_engine = mysql2
in my production mode, my .env looks like
app_url = http://appsomething.heroku.com
port = 80
db = production_api
db_username = root
db_password = 3210LDWAK#AALKQ
db_engine = mysql2
and read more about how to use .ENV

How to pass dynamic `groupID` from one js file to another js file

I have attached my code for reference, In that I want to pass dynamic groupID from teamgroupapi.js to teamCategoryApi.js
Code is working fine when I try to pass manually groupID from ApiCategory.js file.
File name teamgroupapi.js
import { getGeneratedApi } from '#test/bender-executor-simple-api-generator';
import ApiGroup from '../_support/ApiGroup.js';
const request = require('supertest');
const fs = require('fs');
const assert = require('assert')
const chakram = require ('chakram');
const expect = chakram.expect;
const swaggerPath = process.env.BENDER_SWAGGER_PATH || 'https://api-s10938402.cc-staging.test.com/documentation/api.yaml';
const token = process.env.BENDER_LOGIN_TOKEN || 'JTFihw2GJbJ87duTihoGW3vBi8MErxTbBJsD4dw6k5MsPmfI0J8lsf9-mRFXufFYYMzEVcEdK8kXEi3EVkojHQ';
console.log(`login token is ${token}`);
const apiUrl = 'https://' + (process.env.CC_URL_API || 'api-s10938402.cc-staging.test.com');
const readJsonTestFile = (testfilename) => {
return JSON.parse(fs.readFileSync(testfilename, 'utf8'));
};
describe('Create Group all api generated', () => {
let api;
let groupID;
let apiGroup;
const groupName = "Test_" + new Date().getTime();
const groupName_rename = "Rename_" + new Date().getTime();
//const groupJson = { "name": groupName };
//const grouprenameJson = { "name": groupName_rename };
beforeAll(async () => {
api = await getGeneratedApi(apiUrl, token, swaggerPath);
console.log(api);
apiGroup = new ApiGroup();
});
beforeEach(async () => {
// TODO setup.cleanupDb();
// await setup.gateway();
});
//Create Group API
test('Create Group', async() => {
try
{
jest.setTimeout(10000);
console.log("Create Group");
//const payload = readJsonTestFile('e2e/example.json');
const groupJson = apiGroup.generateCreateGroupJsonObject(groupName);
const createGroup = await api.postTeamGroups(groupJson);
//const listofGroups = JSON.parse(JSON.stringify(createGroup));
//expect(result.response.statusCode).toBe(201);
expect(createGroup).to.have.status(201);
console.log("Create group successfully executed");
} catch(e){
console.log("Failed to create group");
throw e;
}
});
//Get Group API
test('Get Group API', async() => {
try
{
jest.setTimeout(10000);
console.log("Get Created Group");
let foundIndex = -1;
console.log("Running get group and attempting to get ::: " + groupName);
//Check if previously created Group exists using the GET Group API
//Check the response payload and loop through the response to find the workspace that was created earlier
const getGroup = await api.getTeamGroups(false,false);
//const listofGroups = JSON.parse(JSON.stringify(getGroup));
//console.log("list of groups" + getGroup.body.length);
expect(getGroup).to.have.status(200);
for(var i = 0; i < getGroup.body.length;i++){
if((getGroup.body[i].name == groupName) && (getGroup.body[i].id != '') ) {
foundIndex = i;
break;
}
}
groupID = getGroup.body[i].id;
console.log("Group ID ---->>>>" + getGroup.body[i].id);
console.log("Group Name ---->>>>" + getGroup.body[i].name);
expect(foundIndex).to.be.above(-1);
console.log("Get group successfully executed");
} catch(e){
console.log("Failed to get group");
throw e;
}
});
// Rename Group API
test.skip('Rename Group API with Group ID', async()=> {
try
{
jest.setTimeout(10000);
console.log("Rename already created group");
const groupJson = apiGroup.generateCreateGroupJsonObject(groupName_rename);
const apigroup = await api.postTeamGroupsWithGroupID(groupID,groupJson);
expect(apigroup).to.have.status(200);
console.log("Rename group successfully executed");
} catch(e){
console.log("Failed to rename group");
throw e;
}
});
//Delete Group API
test.skip('Delete Group API', async()=> {
try
{
jest.setTimeout(10000);
console.log("Delete Created Group");
console.log("Running delete group and attemptin to delete ::: " + groupID);
const apigroup = await api.deleteTeamGroupsWithGroupID(groupID);
expect(apigroup).to.have.status(200);
console.log("Delete group successfully executed");
} catch(e){
console.log("Failed to delete group");
throw e;
}
});
});
Separate Json Functions for teamgroupapi.js File name ApiGroup.js
class ApiGroup {
constructor()
{
//super();
}
generateCreateGroupJsonObject(groupName) {
return {
"name": groupName
}
}
}
module.exports = ApiGroup;
File name teamCategoryApi.js
import { getGeneratedApi } from '#test/bender-executor-simple-api-generator';
import ApiCategory from '../_support/ApiCategory.js';
import teamgroupapi from './teamgroupapi.js';
const request = require('supertest');
const fs = require('fs');
const assert = require('assert')
const chakram = require ('chakram');
const expect = chakram.expect;
const swaggerPath = process.env.BENDER_SWAGGER_PATH || 'https://api-s10938402.cc-staging.test.com/documentation/api.yaml';
const token = process.env.BENDER_LOGIN_TOKEN || 'JTFihw2GJbJ87duTihoGW3vBi8MErxTbBJsD4dw6k5MsPmfI0J8lsf9-mRFXufFYYMzEVcEdK8kXEi3EVkojHQ';
console.log(`login token is ${token}`);
const apiUrl = 'https://' + (process.env.CC_URL_API || 'api-s10938402.cc-staging.test.com');
const readJsonTestFile = (testfilename) => {
return JSON.parse(fs.readFileSync(testfilename, 'utf8'));
};
describe('Create category all api generated', () => {
let api;
let categoryID;
let apiCategory;
let groupID;
//let teamGroup;
const categoryName = "Test_" + new Date().getTime();
const categoryName_rename = "Rename_" + new Date().getTime();
//const categoryrenameJson = { "name": categoryName_rename };
beforeAll(async () => {
api = await getGeneratedApi(apiUrl, token, swaggerPath);
console.log(api);
apiCategory = new ApiCategory();
//teamGroup = new teamgroupapi();
//console.log(api);
});
beforeEach(async () => {
// TODO setup.cleanupDb();
// await setup.gateway();
});
//Create Category API
test('Create Category', async () => {
jest.setTimeout(20000);
try {
console.log("Create Category");
/*const groupID = teamGroupApi.groupID;
let api = teamGroupApi.api;*/
/*groupID = teamgroupapi.groupID;
console.log(groupID);*/
const categoryJson = apiCategory.generateCreateCategoryJsonObject(categoryName,groupID);
//const categoryJson = { "name": categoryName, "groupId": groupID, "parent": 0 };
const createCategory = await api.postTeamCategories(categoryJson);
//const listofCategories = JSON.parse(JSON.stringify(createCategory));
//expect(result.response.statusCode).toBe(201);
expect(createCategory).to.have.status(201);
console.log("Create category successfully executed");
}
catch (e)
{
console.log("Failed to create category");
throw e;
}
});
//Get Category API
test.skip('Get Category API', async() => {
jest.setTimeout(20000);
try {
console.log("Get Created Category");
let foundIndex = -1;
//const categoryName = "Test_" + new Date().getTime();
console.log("Running get category and attempting to get ::: " + categoryName);
//Check if previously created Group exists using the GET Group API
//Check the response payload and loop through the response to find the workspace that was created earlier
//let api = teamGroupApi.api;
const getCategory = await api.getTeamCategories();
//const listofCategories = JSON.parse(JSON.stringify(apicategory));
//console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
//console.log("list of category" + apicategory.body.length);
expect(getCategory).to.have.status(200);
for(var i = 0; i < getCategory.body.length;i++){
if((getCategory.body[i].name == categoryName) && (getCategory.body[i].id != '') ) {
foundIndex = i;
break;
}
}
categoryID = getCategory.body[i].id;
console.log("Category Name ---->>>>" + getCategory.body[i].id);
console.log("Category Name ---->>>>" + getCategory.body[i].name);
expect(foundIndex).to.be.above(-1);
console.log("Get Category successfully executed");
}
catch (e)
{
console.log("Failed to get category");
throw e;
}
});
//Rename Category API
test.skip('Rename Category API with categoryID', async()=> {
jest.setTimeout(20000);
try {
console.log("Rename already created category");
const renameCategoryJson = apiCategory.renameCreateCategoryJsonObject(categoryName_rename);
//const groupJson = apiGroup.generateCreateGroupJsonObject(groupName_rename);
const apicategory = await api.postTeamCategoriesWithCategoryID(categoryID,renameCategoryJson);
//const apicategory = await api.postTeamCategoriesWithCategoryID(categoryID,categoryrenameJson);
expect(apicategory).to.have.status(200);
console.log("Rename category successfully executed");
}
catch (e)
{
console.log("Failed to Rename category");
throw e;
}
});
//Delete Category API
test.skip('Delete Category API', async()=> {
jest.setTimeout(20000);
try {
console.log("Delete Created Cateory");
console.log("Running delete category and attemptin to delete ::: " + categoryID);
const apicategory = await api.deleteTeamCategoriesWithCategoryID(categoryID);
expect(apicategory).to.have.status(200);
console.log("Delete category successfully executed");
}
catch (e)
{
console.log("Failed to delete category");
throw e;
}
});
});
Separate Json Functions for teamCategory.js File name ApiCategory.js
class ApiCategory {
constructor()
{
//super();
}
generateCreateCategoryJsonObject(categoryName,groupID) {
return{
"name": categoryName,
"groupId": groupID, //if you pass manually groupId here and run the code then code is executed successfully.
"parent": 0
}
}
renameCreateCategoryJsonObject(categoryName_rename) {
return{
"name": categoryName_rename
}
}
}
module.exports = ApiCategory;
A simple pub sub module might help you here
const topics = {};
const hOP = topics.hasOwnProperty;
export default class Events {
/**
*
* #param topic
* #param listener
* #returns {{remove: remove}}
*/
subscribe(topic, listener) {
if (!hOP.call(topics, topic)) topics[topic] = [];
const index = topics[topic].push(listener) - 1;
return {
remove: function() {
delete topics[topic][index];
}
};
}
/**
*
* #param topic
* #param info
*/
publish(topic, info) {
if (!hOP.call(topics, topic)) return;
topics[topic].forEach(function(item) {
item(info != undefined ? info : {});
});
}
}
Create this in a js file somewhere. then import it into each of your js files. When you want to pass the value from one script to another you can first publish in the teamgroupapi file and subscribe to the event in the teamCategoryApi file.
self.events.publish('/eventId', groupId);
events.subscribe('/eventId', (groupId) => {
console.log(groupId);
// do stuff
});
Issue is getting resolve after add this lines to teamgroupapi.js file
export let groupID;
exports.groupID = groupID;
After add above two lines in teamgroupapi.js file.
import { getGeneratedApi } from '#test/bender-executor-simple-api-generator';
import ApiGroup from '../_support/ApiGroup.js';
const request = require('supertest');
const fs = require('fs');
const assert = require('assert')
const chakram = require ('chakram');
const expect = chakram.expect;
const swaggerPath = process.env.BENDER_SWAGGER_PATH || 'https://api-slurmhourly.hourly.cc.altus.bblabs/documentation/api.yaml';
const token = process.env.BENDER_LOGIN_TOKEN || 'ju7WkQItxRMFdMtghlGEVz5CZdC1b4umwLId16591CbK00hWs1a1_lT63cBr8xkvBhPK_vWO-fJTUBdP99LFVw';
console.log(`login token is ${token}`);
const apiUrl = 'https://' + (process.env.CC_URL_API || 'api-slurmhourly.hourly.cc.altus.bblabs');
const readJsonTestFile = (testfilename) => {
return JSON.parse(fs.readFileSync(testfilename, 'utf8'));
};
export var groupID;
describe('Create Group all api generated', () => {
let api;
let apiGroup;
//let groupID;
const groupName = "Test_" + new Date().getTime();
const groupName_rename = "Rename_" + new Date().getTime();
//const groupJson = { "name": groupName };
//const grouprenameJson = { "name": groupName_rename };
beforeAll(async () => {
api = await getGeneratedApi(apiUrl, token, swaggerPath);
console.log(api);
apiGroup = new ApiGroup();
});
beforeEach(async () => {
// TODO setup.cleanupDb();
// await setup.gateway();
});
//Create Group API
test('Create Group', async() => {
try
{
jest.setTimeout(10000);
console.log("Create Group");
const groupJson = apiGroup.generateCreateGroupJsonObject(groupName);
const createGroup = await api.postTeamGroups(groupJson);
expect(createGroup).to.have.status(201);
console.log("Create group successfully executed");
} catch(e){
console.log("Failed to create group");
throw e;
}
});
//Get Group API
test('Get Group API', async() => {
try
{
jest.setTimeout(10000);
console.log("Get Created Group");
let foundIndex = -1;
console.log("Running get group and attempting to get ::: " + groupName);
const getGroup = await api.getTeamGroups(false,false);
expect(getGroup).to.have.status(200);
for(var i = 0; i < getGroup.body.length;i++){
if((getGroup.body[i].name == groupName) && (getGroup.body[i].id != '') ) {
foundIndex = i;
break;
}
}
groupID = getGroup.body[i].id;
console.log("Group ID ---->>>>" + getGroup.body[i].id);
console.log("Group Name ---->>>>" + getGroup.body[i].name);
expect(foundIndex).to.be.above(-1);
console.log("Get group successfully executed");
} catch(e){
console.log("Failed to get group");
throw e;
}
});
// Rename Group API
test.skip('Rename Group API with Group ID', async()=> {
try
{
jest.setTimeout(10000);
console.log("Rename already created group");
const groupJson = apiGroup.generateCreateGroupJsonObject(groupName_rename);
const apigroup = await api.postTeamGroupsWithGroupID(groupID,groupJson);
expect(apigroup).to.have.status(200);
console.log("Rename group successfully executed");
} catch(e){
console.log("Failed to rename group");
throw e;
}
});
//Delete Group API
test.skip('Delete Group API', async()=> {
try
{
jest.setTimeout(10000);
console.log("Delete Created Group");
console.log("Running delete group and attemptin to delete ::: " + groupID);
const apigroup = await api.deleteTeamGroupsWithGroupID(groupID);
expect(apigroup).to.have.status(200);
console.log("Delete group successfully executed");
} catch(e){
console.log("Failed to delete group");
throw e;
}
});
});
exports.groupID = groupID;
In teamCategoryApi.js file add this two lines.
var teamgroupapi = require('./teamgroupapi.js');
groupID = teamgroupapi.groupID;
After Add above two lines in teamCategoryApi.js file issue is getting resolved.
import { getGeneratedApi } from '#test/bender-executor-simple-api-generator';
import ApiCategory from '../_support/ApiCategory.js';
var teamgroupapi = require('./teamgroupapi.js');
const request = require('supertest');
const fs = require('fs');
const assert = require('assert')
const chakram = require ('chakram');
const expect = chakram.expect;
const swaggerPath = process.env.BENDER_SWAGGER_PATH || 'https://api-slurmhourly.hourly.cc.altus.bblabs/documentation/api.json';
const token = process.env.BENDER_LOGIN_TOKEN || 'ju7WkQItxRMFdMtghlGEVz5CZdC1b4umwLId16591CbK00hWs1a1_lT63cBr8xkvBhPK_vWO-fJTUBdP99LFVw';
console.log(`login token is ${token}`);
const apiUrl = 'https://' + (process.env.CC_URL_API || 'api-slurmhourly.hourly.cc.altus.bblabs');
const readJsonTestFile = (testfilename) => {
return JSON.parse(fs.readFileSync(testfilename, 'utf8'));
};
describe('Create category all api generated', () => {
let api;
let categoryID;
let apiCategory;
let groupID;
//let teamGroup;
const categoryName = "Test_" + new Date().getTime();
const categoryName_rename = "Rename_" + new Date().getTime();
//const categoryrenameJson = { "name": categoryName_rename };
beforeAll(async () => {
api = await getGeneratedApi(apiUrl, token, swaggerPath);
console.log(api);
apiCategory = new ApiCategory();
//teamGroup = new teamgroupapi();
//console.log(api);
});
beforeEach(async () => {
// TODO setup.cleanupDb();
// await setup.gateway();
});
//Create Category API
test('Create Category', async () => {
jest.setTimeout(20000);
try {
console.log("Create Category");
groupID = teamgroupapi.groupID;
const categoryJson = apiCategory.generateCreateCategoryJsonObject(categoryName,groupID);
//const categoryJson = { "name": categoryName, "groupId": groupID, "parent": 0 };
const createCategory = await api.postTeamCategories(categoryJson);
//const listofCategories = JSON.parse(JSON.stringify(createCategory));
//expect(result.response.statusCode).toBe(201);
expect(createCategory).to.have.status(201);
console.log("Create category successfully executed");
}
catch (e)
{
console.log("Failed to create category");
throw e;
}
});
//Get Category API
test('Get Category API', async() => {
jest.setTimeout(20000);
try {
console.log("Get Created Category");
let foundIndex = -1;
//const categoryName = "Test_" + new Date().getTime();
console.log("Running get category and attempting to get ::: " + categoryName);
//Check if previously created Group exists using the GET Group API
//Check the response payload and loop through the response to find the workspace that was created earlier
//let api = teamGroupApi.api;
const getCategory = await api.getTeamCategories();
//const listofCategories = JSON.parse(JSON.stringify(apicategory));
//console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
//console.log("list of category" + apicategory.body.length);
expect(getCategory).to.have.status(200);
for(var i = 0; i < getCategory.body.length;i++){
if((getCategory.body[i].name == categoryName) && (getCategory.body[i].id != '') ) {
foundIndex = i;
break;
}
}
categoryID = getCategory.body[i].id;
console.log("Category Name ---->>>>" + getCategory.body[i].id);
console.log("Category Name ---->>>>" + getCategory.body[i].name);
expect(foundIndex).to.be.above(-1);
console.log("Get Category successfully executed");
}
catch (e)
{
console.log("Failed to get category");
throw e;
}
});
//Rename Category API
test('Rename Category API with categoryID', async()=> {
jest.setTimeout(20000);
try {
console.log("Rename already created category");
const renameCategoryJson = apiCategory.renameCreateCategoryJsonObject(categoryName_rename);
//const groupJson = apiGroup.generateCreateGroupJsonObject(groupName_rename);
const apicategory = await api.postTeamCategoriesWithCategoryID(categoryID,renameCategoryJson);
//const apicategory = await api.postTeamCategoriesWithCategoryID(categoryID,categoryrenameJson);
expect(apicategory).to.have.status(200);
console.log("Rename category successfully executed");
}
catch (e)
{
console.log("Failed to Rename category");
throw e;
}
});
//Delete Category API
test('Delete Category API', async()=> {
jest.setTimeout(20000);
try {
console.log("Delete Created Cateory");
console.log("Running delete category and attemptin to delete ::: " + categoryID);
const apicategory = await api.deleteTeamCategoriesWithCategoryID(categoryID);
expect(apicategory).to.have.status(200);
console.log("Delete category successfully executed");
}
catch (e)
{
console.log("Failed to delete category");
throw e;
}
});
});

Categories