ERR_STREAM_PUSH_AFTER_EOF error in ffmpeg - javascript

I got this error ( ERR_STREAM_PUSH_AFTER_EDF ) a lot when i stay in voice channel for a long time, this error only happen when i stay in the voice channel for like minute or more, when i stay in voice channel for couple of seconds the code return no errors, and this my ffmpeg part of code :
try {
let proc = new ffmpeg(`./abdlmutiiRecords/r-${myID}.pcm`);
proc.then(function(audio) {
audio.fnExtractSoundToMP3('./abdlmutiiRecords/mp3-' + myID + ".mp3", function(error, file) {
if (!error) {
ab.guild.channels.cache.get("983142179734175814").send({
embeds: [abdlmutiiEmbedLog],
files: [new dis.MessageAttachment('./abdlmutiiRecords/mp3-' + myID + ".mp3", "record.mp3")]
});
}
});
}, function(err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e);
}
Also this my full code :
bot.on("interactionCreate", async ab => {
if (ab.isButton()) {
let myID = abdlmutiiID("10");
if (ab.customId === "recordButton") {
await ab.deferReply();
let startEmbed = new dis.MessageEmbed().setDescription("**جاري تسجيل المكالمة، ان انتهيت الرجاء الضغط على زر الإيقاف بالاسفل، يرجى معرفة ان التسجيل سيكون مدته ٣٠ دقيقة ان لم يتم الضغط على زر الإيقاف**").setColor("GREEN");
let startRow = new dis.MessageActionRow().addComponents(new dis.MessageButton().setLabel("الأيقاف").setStyle("DANGER").setCustomId(`stopButton${myID}`), ) let voiceChannel = ab.member.voice.channel;
if (!voiceChannel) return ab.reply("Please join a voice channel first!");
await ab.editReply({
embeds: [startEmbed],
components: [startRow],
ephemeral: true
});
const connection = await bot.voiceManager.join(voiceChannel, {
selfMute: true
});
const receiver = connection.receiver.createStream(ab.member, {
mode: "pcm",
end: "silence"
});
const writer = await receiver.pipe(fs.createWriteStream(`./abdlmutiiRecords/r-${myID}.pcm`));
const collector = ab.channel.createMessageComponentCollector({
componentType: 'BUTTON'
});
collector.on('collect', i => {
if (i.user.id === ab.user.id && i.customId === `stopButton${myID}`) {
connection.destroy();
let abdlmutiiEmbedLog = new dis.MessageEmbed().setAuthor(ab.user.tag, ab.user.avatarURL({
dynamic: true
})).setDescription(`**أيدي التسجيل**: ${myID}\n**القناة الصوتية**: ${ab.member.voice.channel.name}\n**منذ**: `);
const ffmpeg = require('ffmpeg');
try {
let proc = new ffmpeg(`./abdlmutiiRecords/r-${myID}.pcm`);
proc.then(function(audio) {
audio.fnExtractSoundToMP3('./abdlmutiiRecords/mp3-' + myID + ".mp3", function(error, file) {
if (!error) {
ab.guild.channels.cache.get("983142179734175814").send({
embeds: [abdlmutiiEmbedLog],
files: [new dis.MessageAttachment('./abdlmutiiRecords/mp3-' + myID + ".mp3", "record.mp3")]
});
}
});
}, function(err) {
console.log('Error: ' + err);
});
} catch (e) {
console.log(e);
}
}
});
}
}
})

Related

SQS messages are coming back to DLQ?

I have written the following script to move messages from DLQ to MainQ.
'use strict'
import { readFileSync } from "fs";
import {
DeleteMessageCommand,
SQSClient,
GetQueueUrlCommand,
SendMessageCommand,
ReceiveMessageCommand,
GetQueueAttributesCommand
} from '#aws-sdk/client-sqs';
const REGION = 'us-east-1';
const sqs = new SQSClient({ region: REGION });
async function getMessageCount(queueUrl) {
const params = { AttributeNames: ['ApproximateNumberOfMessages'], QueueUrl: queueUrl };
try {
const data = await sqs.send(new GetQueueAttributesCommand(params));
// console.log(data);
return data.Attributes.ApproximateNumberOfMessages;
} catch (err) {
console.error(err);
}
}
async function reprocessMessages(dlqQueue, mainQueue) {
try {
const response1 = await sqs.send(new GetQueueUrlCommand({ QueueName: dlqQueue }));
const response2 = await sqs.send(new GetQueueUrlCommand({ QueueName: mainQueue }));
const dlqQueueUrl = response1.QueueUrl;
const mainQueueUrl = response2.QueueUrl;
const messageCount = await getMessageCount(dlqQueueUrl);
console.log(`Message count ${messageCount}`);
const visibiltyTimeout = Math.ceil(messageCount / 100) * 2;
let count = 0;
while (count <= 50) {
count += await moveMessage(mainQueueUrl, dlqQueueUrl, 5);
}
console.log(`Moved ${count} messages`);
return "Completed";
} catch (err) {
console.error(err);
}
}
async function moveMessage(mainQueueUrl, dlqQueueUrl, visibiltyTimeout) {
try {
const receiveMessageParams = {
MaxNumberOfMessages: 9,
MessageAttributeNames: ['All'],
QueueUrl: dlqQueueUrl,
VisibilityTimeout: visibiltyTimeout,
WaitTimeSeconds: 1
};
const receiveData = await sqs.send(new ReceiveMessageCommand(receiveMessageParams));
// console.log(receiveData);
if (!receiveData.Messages) {
// console.log("finished");
return 0;
}
const messages = [];
receiveData.Messages.forEach(msg => {
messages.push({ id: msg.MessageId, msgAttributes: msg.MessageAttributes, body: msg.Body, receiptHandle: msg.ReceiptHandle });
});
const sendMsg = async ({ id, msgAttributes, body, _ }) => {
const sendMessageParams = {
MessageId: id,
MessageAttributes: msgAttributes,
MessageBody: body,
QueueUrl: mainQueueUrl
};
const sentData = await sqs.send(new SendMessageCommand(sendMessageParams));
// console.log("Success, message sent. MessageID: ", sentData.MessageId);
return 'Success';
};
const deleteMsg = async ({ id, receiptHandle }) => {
const deleteMessageParams = {
MessageId: id,
QueueUrl: dlqQueueUrl,
ReceiptHandle: receiptHandle
};
const deleteData = await sqs.send(new DeleteMessageCommand(deleteMessageParams));
// console.log("Message deleted", deleteData);
return 'Deleted';
};
const sent = await Promise.all(messages.map(sendMsg));
console.log(sent);
const deleted = await Promise.all(messages.map(deleteMsg));
console.log(deleted);
console.log(sent.length);
return sent.length;
// return 1;
} catch (err) {
console.log(err);
}
}
function main() {
const queues = readFileSync('queues.txt', 'utf8').split('\n');
queues.map(async elem => {
const [dlqQueue, mainQueue] = elem.split(' ');
console.log(`Moving messages from ${dlqQueue} to ${mainQueue}`);
const response = await reprocessMessages(dlqQueue, mainQueue);
console.log(response);
});
}
main()
This script moves the message from DLQ to MainQ and shows the new count of the DLQ decreased by the number of messages. However, when those messages in MainQ fail they again come back to DLQ thus keeping the count same as before reprocessing. But, after a while I see that the messages in DLQ increase by the same amount as the number of messages processed.
For instance for the below case I moved 54 messages and the screenshots for the queue counts are attached after each stage.

Discord.js YouTube Search and Play

I am trying to make discord bot that will play some music but I can't manage to make search command correctly ( Now I need to type command .f press enter and then put that what I want to search and I want it to just .f [what i want to search]) but doesn't know how to. I tried many guides but still nothing, also I would like to have that after searching and choosin what to I meant to play bot automatically join and play it (I made it buut in weird way and I know there is easier way but I am dumb for it.
TL;DR: Search command that will search and play with ".f [what to search]".
Whole code if it wil help:
const { Client } = require("discord.js");
const config = require('./config.json')
const Discord = require("discord.js");
const ytdl = require('ytdl-core');
const search = require("youtube-search")
const opts = {
maxResults: 25,
key: config.YOUTUBE_API,
type: 'video'
}
const queue = new Map();
const client = new Client({
disableEveryone: true
});
client.on("ready", () => {
console.log(`ŻYJE I JAM JEST ${client.user.username} `);
});
client.on("message", async message => {
console.log(`${message.author.username} mówi: ${message.content}`)
});
client.on("message", async message => {
if (!message.content.startsWith('.')) return;
const serverQueue = queue.get(message.guild.id);
if (message.content.startsWith(`.p`, '.play', '.pla', '.pl')) {
execute(message, serverQueue);
return;
} else if (message.content.startsWith(`.s`, '.skip', '.sk', '.ski')) {
skip(message, serverQueue);
return;
} else if (message.content.startsWith(`.l`, '.leave', '.le', '.lea', '.leav')) {
stop(message, serverQueue);
return;
};
if (message.content.toLowerCase() === '.f') {
let embed = new Discord.MessageEmbed()
.setColor("#00FE0C")
.setDescription("Czego szukasz? Opowiedz mi dokładniej.")
.setTitle("Wyszukiwarka")
.setThumbnail('https://i.imgur.com/vs6ulWc.gif')
let embedMsg = await message.channel.send(embed);
let filter = m => m.author.id === message.author.id;
let query = await message.channel.awaitMessages(filter, { max: 1});
let results = await search(query.first().content, opts).catch(err => console.log(err))
if(results) {
let youtubeResults = results.results;
let i =0;
let titles = youtubeResults.map(result => {
i++;
return i + ") " + result.title;
});
console.log(titles);
message.channel.send({
embed : {
title: "Wybieraj mordo",
description: titles.join("\n")
}
}).catch(err => console.log(err));
filter = m => (m.author.id === message.author.id) && m.content >= 1 && m.content <= youtubeResults.length;
let collected = await message.channel.awaitMessages(filter, { max: 1 });
let selected = youtubeResults[collected.first().content - 1];
embed = new Discord.MessageEmbed()
.setColor("#00FE0C")
.setTitle(`${selected.title}`)
.setURL(`${selected.link}`)
.setDescription(`${selected.description}`)
.setThumbnail(`${selected.thumbnails.default.url}`);
message.channel.send(embed)
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
await message.channel.send(`.p ${selected.link}`).then(d_msg => { d_msg.delete({ timeout: 1500 })})
}
};
};
});
async function execute(message, serverQueue) {
const args = message.content.split(" ");
const voiceChannel = message.member.voice.channel;
if (!voiceChannel)
return message.channel.send(
"No wbij Mordunio na kanał najpierw!"
);
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has("CONNECT") || !permissions.has("SPEAK")) {
return message.channel.send(
"Dawaj klucze do kantorka to wbije!"
);
}
const songInfo = await ytdl.getInfo(args[1]);
const song = {
title: songInfo.title,
url: songInfo.video_url
};
if (!serverQueue) {
const queueContruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 5,
playing: true
};
queue.set(message.guild.id, queueContruct);
queueContruct.songs.push(song);
try {
var connection = await voiceChannel.join();
queueContruct.connection = connection;
play(message.guild, queueContruct.songs[0]);
} catch (err) {
console.log(err);
queue.delete(message.guild.id);
return message.channel.send(err);
}
} else {
serverQueue.songs.push(song);
return message.channel.send(`**${song.title}** został do kolejeczki dodany Byku!`);
}
}
function skip(message, serverQueue) {
if (!message.member.voice.channel)
return message.channel.send(
"Nie zatrzymasz mnie! Ciebie tu nie ma!"
);
if (!serverQueue)
return message.channel.send("A co miałabym pominąć");
serverQueue.connection.dispatcher.end();
}
function stop(message, serverQueue) {
if (!message.member.voice.channel)
return message.channel.send(
"Musisz tu byyyyć byyyyyku!!"
);
serverQueue.songs = [];
serverQueue.connection.dispatcher.end();
}
function play(guild, song, message) {
const serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.voiceChannel.leave();
queue.delete(guild.id)
return;
}
const dispatcher = serverQueue.connection
.play(ytdl(song.url))
.on("finish", () => {
serverQueue.songs.shift();
play(guild, serverQueue.songs[0]);
})
.on("error", error => console.error(error));
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
serverQueue.textChannel.send(`Gram: **${song.title}**`);
};
client.login(config.TOKEN);

ROBLOX Discord bot

I'm trying to create a discord bot that connects to a Roblox account that I made.
I'm trying to create a command that will shout a message in a group, but there's a problem at the login and I can't figure out how to fix the problem.
let roblox = require('noblox.js');
const { Client } = require("discord.js");
const { config } = require("dotenv");
const client = new Client({
disableEveryone: true
});
config({
path: __dirname + "/.env"
});
let prefix = process.env.PREFIX
let groupId = groupid;
client.on("ready", () => {
console.log("I'm Ready!");
function login() {
roblox.cookieLogin(process.env.COOKIE)
}
login()
.then(function () {
console.log(`Logged in to ${username}`);
})
.catch(function (error) {
console.log(`Login error: ${error}`);
});
client.on("message", async message => {
console.log(`${message.author.username} said: ${message.content}`);
if (message.author.bot) return;
if (message.content.indexOf(prefix) !== 0) return;
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "shout") {
if (!args) {
return;
message.reply("You didn't specify a message to shout.")
}
const shoutMSG = args.join(" ");
roblox.shout(groupId, shoutMSG)
.then(function() {
console.log(`Shouted ${shoutMSG}`);
})
.catch(function(error) {
console.log(`Shout error: ${error}`)
});
}
})
client.login(process.env.TOKEN);
It gives me the error:
Shout error: Error: Shout failed, verify login, permissions, and message
At the first you don`t close you client.on('ready') state.
if (!args) {
return;
message.reply("You didn't specify a message to shout.")
}
This funcyion will never reply, because you use return, before reply.
Your groupId looks like undefined, because you declarate it let groupId = groupid;, so this is the one way, why got you got this error.
let roblox = require('noblox.js');
const { Client } = require("discord.js");
const { config } = require("dotenv");
const client = new Client({
disableEveryone: true
});
config({
path: __dirname + "/.env"
});
let prefix = process.env.PREFIX
let groupId = groupid;
client.on("ready", () => {
console.log("I'm Ready!");
})
function login() {
roblox.cookieLogin(process.env.COOKIE)
}
login()
.then(function () {
console.log(`Logged in to ${username}`);
})
.catch(function (error) {
console.log(`Login error: ${error}`);
});
client.on("message", async message => {
console.log(`${message.author.username} said: ${message.content}`);
if (message.author.bot) return;
if (message.content.indexOf(prefix) !== 0) return;
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "shout") {
if (!args) return message.reply("You didn't specify a message to shout.")
const shoutMSG = args.join(" ");
roblox.shout(groupId, shoutMSG)
.then(function() {
console.log(`Shouted ${shoutMSG}`);
})
.catch(function(error) {
console.log(`Shout error: ${error}`)
});
}
})
client.login(process.env.TOKEN);

Camera Plugin not opening camera in Ionic 4

I am working on a project in Ionic 4.
I would like user to upload picture by capturing from camera or uploading from library. For now I am running in development mode. The problem is that I am not being able to open camera or photo library on device in debugging mode. However the camera is opening when I run on "DEVAPP". I have tried taking permission but nothing is working out. Here is my code, tried many ways therefore code is a bit scattered:
async selectImage() {
try {
const actionSheet = await this.actionSheetController.create({
header: 'Select Image source',
buttons: [{
text: 'Load from Library',
handler: () => {
this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
}
},
{
text: 'Use Camera',
handler: () => {
this.takePicture(this.camera.PictureSourceType.CAMERA);
}
},
{
text: 'Cancel',
role: 'cancel'
}
]
});
await actionSheet.present();
} catch (error) {
alert(error);
}
}
takePicture(sourceType: PictureSourceType) {
const options: CameraOptions = {
quality: 100,
sourceType,
saveToPhotoAlbum: false,
correctOrientation: true
};
alert('i m n takepicture');
this.androidPermissions.requestPermissions([this.androidPermissions.PERMISSION.CAMERA]).then(
result => console.log('i am asking for permision: ' + result),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.CAMERA)
);
if (this.camera.PictureSourceType.CAMERA) {
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.CAMERA).then(
result =>
this.camera.getPicture(options).then(imagePath => {
if (this.plt.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
this.filePath.resolveNativePath(imagePath)
.then(filePath => {
const correctPath = filePath.substr(0, filePath.lastIndexOf('/') + 1);
const currentName = imagePath.substring(imagePath.lastIndexOf('/') + 1, imagePath.lastIndexOf('?'));
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
}). catch((error) => {
console.warn('error: ' + error);
});
} else {
const currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
const correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
}
}),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.CAMERA));
} else {
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.PHOTOLIBRARY).then(
result =>
this.camera.getPicture(options).then(imagePath => {
if (this.plt.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
this.filePath.resolveNativePath(imagePath)
.then(filePath => {
const correctPath = filePath.substr(0, filePath.lastIndexOf('/') + 1);
const currentName = imagePath.substring(imagePath.lastIndexOf('/') + 1, imagePath.lastIndexOf('?'));
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
});
} else {
const currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
const correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
}
}),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.PHOTOLIBRARY));
}
}
Try this
takePicture(sourceType: PictureSourceType) {
const options: CameraOptions = {
quality: 100,
sourceType:sourceType,
saveToPhotoAlbum: false,
correctOrientation: true
};
this.camera.getPicture(options).then(
imageData => {
///DO YOUR LOGIC
},
err => {
// Handle error
}
);
}

Close Event Triggers Before Data Events on File Stream

I've got a script that adds JSON data from a file to a DynamoDB table. The script uses the "fs" module to open a read stream to the json file and retrieve the data line by line. As the data is returned, it's inserted into a DynamoDB table. When the operation ends, an execution summary is given with number of records processed, successfully inserted, and unsuccessfully inserted. The problem is the summary executes before the file has completely processed. As result the numbers are wrong.
The script...
ddb_table_has_records(table_name, (err, dat) => {
if (dat.Count === 0 || force) {
const transformStream = JSONStream.parse("*");
const inputStream = fs.createReadStream(import_file);
let record_position = 0;
let count_imported_successful = 0;
let count_imported_fail = 0;
inputStream.pipe(transformStream).on("data", (Item) => {
const params = {
TableName: table_name,
Item
}
ddb_client.put(params, (err, data) => {
++record_position;
if (err) {
console.error("Unable to add mapping for record " + record_position + ", error = " + err);
++count_imported_fail;
} else {
console.log("PutItem succeeded " + record_position);
++count_imported_successful;
}
});
}).on("close", () => {
console.log("=".repeat(70));
console.log(`'Completed: ${import_file}' has been loaded into '${table_name}'.`);
console.log(` Record Count: ${record_position}`);
console.log(` Imported Record Count: ${count_imported_successful}`);
console.log(` Rejected Record Count: ${count_imported_fail}`);
});
} else {
console.log("=".repeat(70));
console.log(`Completed: Skipping import of '${import_file}' into '${table_name}'.`);
};
});
When this runs, it looks like the following
PS C:\> node --max-old-space-size=8192 .\try.js 'foo' 'us-west-2' 'development' '.\data.json' true
Target Profile: development
Target Region: us-west-2
Target Table: foo
Source File: .\data.json
Force Import: true
Confirming Table's State...
======================================================================
'Completed: .\data.json' has been loaded into 'foo'.
Record Count: 0
Imported Record Count: 0
Rejected Record Count: 0
PutItem succeeded 1
PutItem succeeded 2
PutItem succeeded 3
PutItem succeeded 4
...
The portion of the code that gets the record counts runs before the inserts completes so the records imported and rejected numbers are always wrong. It looks like the file stream closes while inserts are occurring. I've tried changing from the "close" to "end" event, same result.
Test this script with the following call...
node --max-old-space-size=8192 .\data.load.js 'foo' 'us-west-1' 'dev' '.\foo.default.json' true
Here is the content for the script I ultimately used...
'use strict'
if (process.argv.length < 6) {
throw new Error ('Please pass the table-name, aws-Region, aws-Profile, and file-path to the script.');
}
let [, , TableName, Region, Profile, ImportFile, Force] = process.argv;
process.env.AWS_SDK_LOAD_CONFIG = true;
process.env.AWS_PROFILE = Profile;
Force = typeof(Force) !== 'undefined' ? Force : false;
const AWS = require('aws-sdk');
const fs = require('fs');
const JSONStream = require('JSONStream');
AWS.config.update({ region: Region });
const ddbc = new AWS.DynamoDB.DocumentClient();
console.log('Target Profile: ', Profile);
console.log('Target Region: ', Region);
console.log('Target Table: ', TableName);
console.log('Source File: ', ImportFile);
console.log('Force Import: ', Force);
// Returns the number of records in a specified table
const ddb_table_has_items = (TableName) => {
return new Promise((resolve, reject) => {
const ddb_query_parameters = { TableName, Select: 'COUNT' }
ddbc.scan(ddb_query_parameters, (error, data) => {
(error) ? reject(error) : resolve(data);
});
});
}
const ddb_table_upsert_items = (TableName, Item) => {
return new Promise((reject, resolve) => {
const ddb_insert_payload = { TableName, Item };
ddbc.put(ddb_insert_payload, (error, data) => {
(error) ? reject(error) : resolve(data);
});
});
}
const ddb_bulk_load = (TableName, ImportFile) => {
return new Promise ( (resolve, reject) => {
let count_succeeded = 0;
let count_failed = 0;
let count_attempted = 0;
let inserts = [];
const json_stream = JSONStream.parse( "*" );
const source_data_stream = fs.createReadStream(ImportFile);
const ddb_source_item = source_data_stream.pipe(json_stream);
ddb_source_item.on("data", (source_data_item) => {
count_attempted++;
let ddb_insert = ddb_table_upsert_items(TableName, source_data_item)
.then( (data) => count_succeeded++ )
.catch( (error) => count_failed++ );
inserts.push(ddb_insert);
});
ddb_source_item.on("end", () => {
Promise.all(inserts)
.then(() => {
resolve({count_succeeded, count_failed, count_attempted});
})
.catch((error) => {
console.log(error);
reject(error);
});
});
ddb_source_item.on("error", (error) => {
reject(error);
});
});
}
(async () => {
try {
let proceed_with_import = false;
if ( Force.toString().toLowerCase() === 'true' ) {
proceed_with_import = true;
} else {
const table_scan = await ddb_table_has_items(TableName);
proceed_with_import = ( table_scan.Count === 0 );
}
if (proceed_with_import) {
let ddb_inserts = await ddb_bulk_load(TableName, ImportFile);
console.log("=".repeat(75));
console.log("Completed: '%s' has been loaded into '%s'.", ImportFile, TableName);
console.log(" Insert Attempted: %s", ddb_inserts.count_attempted);
console.log(" Insert Succeeded: %s", ddb_inserts.count_succeeded);
console.log(" Insert Failed : %s", ddb_inserts.count_failed);
}
} catch (error) {
console.log(error);
}
})();
Wrapping each insert in a promise, pushing the insert-promises into an array, and using promise all on that array did the trick. I execute the promise all once we're finished reading from the file; once the "end" event is emitted on the ddb_source_item stream.

Categories