Problem : I have got list of 1000 recipients, but I want to sent mail in batch of 200 each. I am using node js module emailjs for sending mail.
Below is my snippet of code.
// Code goes here
var sizeLimit = 200;
var totalData = 350;
var cycles = Math.ceil(totalData / sizeLimit);
var start;
var end;
var recepients = "a#gmail.com,b#gmail.com...long list"
for (var i = 0; i < cycles; i++) {
start = end ? end + 1 : 0
end = (sizeLimit) * (i + 1) > totalData ? (totalData - start) + start :
(sizeLimit) * (i + 1)
var bcc = recepients.substr(start,end);
(function(i) {
setTimeout(function() {
console.log(i)
//Sending mail using emailjs
//bcc
}, i * 5000)
})(i)
}
What is the best way of sending mail in batches, I don't want to use Redis.
From what I can gather, you are attempting to send email batches by putting 200 recipients into the BCC field at once. This is extremely bad practice and shows a lack of understanding of the fundamentals of what you're trying to do.
What you should be doing instead is sending one email to one recipient at a time. This is what mailing list software does anyway and is what you should use for this purpose anyway instead of trying to roll your own.
You can use SaaS offerings like MailChimp, open source solutions like Mailtrain or my personal favorite Sendy, which features API access, so you can automate certain aspects.
Related
I am trying to generate encoded docket number from storeId and transactionId. Encoded docket number has to be unique, length should be <=9 and easy to read/copy for users as well.
The maximum length of storeId is 3 and maximum length of transactionId is 5.
How can I improve my code so that my docket number will be unbreakable?
Here is my code:
let myTransKey = 19651;
let myStoreKey = 186;
function generateShortCode(storeId, transactionId) {
//reverse the ids and then add the respective key
var SID = storeId.toString().split("").reverse().join("");
SID = parseInt(SID) + myStoreKey;
var TID = transactionId.toString().split("").reverse().join("");
TID = parseInt(TID) + myTransKey;
var docketNum = `${SID}-${TID}`;
return docketNum;
}
function decodeShortCode(shortCode) {
shortCode = shortCode.split("-");
var storeID = shortCode[0];
var transactionID = shortCode[1];
//subtract the same key and then reverse the ids again
storeID = parseInt(storeID.toString()) - myStoreKey;
storeID = storeID.toString().split("").reverse().join("");
transactionID = parseInt(transactionID.toString()) - myTransKey;
transactionID = transactionID.toString().split("").reverse().join("");
return {
storeId: parseInt(storeID), // store id goes here,
shopDate: new Date(), // the date the customer shopped,
transactionId: parseInt(transactionID) // transaction id goes here
};
}
Is there any better way to do this? I need to encode docket number in a way which will be really hard to decode by any third person.
Every encrypted message can be broken if an attacker tries every possible decryption key (this is called a brute-force attack). With modern computers, this is really easy to do. The way that you are encoding data is very easy to break (within seconds). However, there are encryption methods that take very long to break (like millions of years long).
One of the more popular encryption algorithms is AES. Because it is so popular, there are also many easy-to-use libraries for JavaScript. Here's an example with CryptoJS:
const KEY = "a super secret password";
let myTransKey = 19651;
let myStoreKey = 186;
function generateShortCode(storeId, transactionId) {
const docketNum = `${storeId}-${transactionId}`;
return CryptoJS.AES.encrypt(docketNum, KEY).toString().replace("=", "");
}
function decodeShortCode(shortCode) {
const docketNum = CryptoJS.AES.decrypt(shortCode, KEY).toString(CryptoJS.enc.Utf8);
const parts = docketNum.split("-");
return {
storeId: parseInt(parts[0]), // store id goes here,
shopDate: new Date(), // the date the customer shopped,
transactionId: parseInt(parts[1]) // transaction id goes here
};
}
const s1 = generateShortCode(myStoreKey, myTransKey);
console.log("Short Code: " + s1);
console.log("Decrypted Short Code:", decodeShortCode(s1));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js" integrity="sha256-/H4YS+7aYb9kJ5OKhFYPUjSJdrtV6AeyJOtTkw6X72o=" crossorigin="anonymous"></script>
This shortcode is longer than 9 characters, but it very secure and nearly unbreakable. This is really just the tradeoff. If you reduce the length of the shortcode, then you won't be able to have a secure shortcode. Users can still easily copy and paste the code though. If you absolutely need a shorter cipher, then try looking at Skip32.
Be sure to change KEY to a secret key that isn't shared with anyone. Also, be sure not to run this code client-side. If the encryption key is sent to the client, then they could look at the JavaScript code and then be able to decrypt any message.
well this work for me with visual compser in Wordpress
/[[^[]vc[^]]]/ig
I have a shinyApp running on cloud that runs for long (lots of computation taking about 25 minutes) leading to timeout. However, If I keep interacting with the page as the app runs (e.g. navigating the navbar or moving a slider..), timeout does not happen. A possible solution is to keep the web-socket active by updating a value on the current page every 5 seconds or so. I borrowed the idea here https://community.rstudio.com/t/keep-shiny-app-running-in-shiny-server-no-greying-out/27784/4.
ui <- fluidPage(
"Am I losing connection?",
tags$div(style = "position: absolute; top: -100px;",
textOutput("clock")
)
)
server <- function(input, output) {
output$clock <- renderText({
invalidateLater(5000)
Sys.time()
})
}
shinyApp(ui = ui, server = server)
However, this also fails because it appears that UI values do not update or refresh as the app runs in the background, until it completes the current task. So it appears doing this in the server.R block is not the solution.
I later tried to do it differently by including JS code that can update or refresh the UI as the app runs in the background. What I came up with is this ...
function time_function(){
var today1 = new Date();
var hr = today1.getHours();
var mn = today1.getMinutes();
var ss = today1.getSeconds();
if (hr.toString().length <2 ){hr = '0' + hr;}
if (mn.toString().length <2 ){mn = '0' + mn;}
if (ss.toString().length <2 ){ss = '0' + ss;}
console.log(hr + ':' + mn + ':' + ss);
}
setInterval(time_function,5000)
... with the view that I could update textOutput("time_display") on shiny UI every 5 seconds to keep the page active and prevent loss of connection to websocket.This is exactly where I got stuck as I cannot get textOutput("time_display") to update with refreshing values of the JS function time_function().
I appreciate all help offered. Thank you!
I managed to find a workaround that keeps the R/Shiny web page active even as intensive workloads run in server.R. I would like to share my working solution.
The first step is to create a div tag or object inside shiny's UI, fluidPage() section. I have a assigned "time_stamp" id to it.
ui<-fluidPage(
titlePanel(" Testing 5 sec display of clock"),
HTML('<div id="time_stamp"></div>'), // comment: new object created. We write to it using js code.
br(),
tags$script(src = "time_print.js")
)
//server.R
server = function(input,output,session){
// do some complex tasks..
}
The tags$script bit is where the .js file is read from. For this to happen, I saved the time_print.js file in a directory named www in the same directory as our shinyApp.R file. The code in the .js file is shown next:
function js_print_time(){
var today1 = new Date();
var hr = today1.getHours();
var mn = today1.getMinutes();
var ss = today1.getSeconds();
if (hr.toString().length <2 ){hr = '0' + hr;}
if (mn.toString().length <2 ){mn = '0' + mn;}
if (ss.toString().length <2 ){ss = '0' + ss;}
var pstamp = hr + ':' + mn + ':' + ss;
document.getElementById("time_stamp").textContent = ""; //clear current div object contents.
document.getElementById("time_stamp").textContent += pstamp; // Append pstamp to current value of div object, "". I thank Jesus!
}
setInterval(one_time_print,5000);
What this does is print the output of the javascript js_print_time() function to shiny's web page (on the "time_stamp" div) every 5000 milliseconds (5 seconds), regardless of whether heavy tasks are running in the shinyApp's server.R.
I'm trying to use Google Script to extract email address and name from forwarded emails that I've filed under a specific label.
The emails look like this:
From: Person A
Sent: Sunday, September 22, 2019 8:00 PM
To: Other, Email
Subject: Forwarded Email
BODY
They have all have been forwarded to this specific inbox. Therefore the headers actually include my other email address I forwarded from.
I've sorted over 2000 emails and now for each of the labels I want to extract the name of the sender (Person A) and their email address (person#gmail.com) in a spreadsheet. Preferably, I can have the first and last name in separate cells (e.g. Person | A | email address)
The code I have thus far is below:
function processInboxToSheet() {
// Have to get data separate to avoid google app script limit!
var start = 0;
var label = GmailApp.getUserLabelByName("LABEL");
var threads = label.getThreads();
var sheet = SpreadsheetApp.getActiveSheet();
var result = [];
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
var content = messages[0].getPlainBody();
// implement your own parsing rule inside
if (content) {
var tmp;
tmp = content.match(/From:\n([A-Za-z0-9\s]+)(\r?\n)/);
var name = (tmp && tmp[1]) ? tmp[1].trim() : 'No name';
tmp = content.match(/<\n([A-Za-z0-9#.]+)/);
var email = (tmp && tmp[1]) ? tmp[1].trim() : 'No email';
sheet.appendRow([name, email]);
Utilities.sleep(500);
}
}
};
I only get No name and No email as output so something is not quite working in the code. I would appreciate your help.
You are parsing the plain body, it doesn’t contain to and from. It only contains the message body. The API has methods getTo() and getFrom() that contains what you want to parse. See the API for GmailMessage for more details.
I'm trying to calculate the EMA with this script.
But it does not give me the correct EMA.
This could be of many reasons, but i'm not sure what it is.
I've tried different formulas for the EMA without any better results, I'm really not a professional coder nor mathematician and thus i can't see what I'm doing wrong.
How Is the EMA value calculated over time? For the first value I calculate the first EMA using the SMA, i guess that should work - right?
My EMA value = 0.033144798412698406
Real EMA value = 0.033084
Close = last closing price
Period = 20;
Multiplier = (2 / (period + 1));
function calculateEMA() {
if (EMA == 0) {
EMA = (Close - SMA) * multiplier + SMA;
calculateEMA();
} else {
for (a = 0; a < period; a++) {
EMA = (Close - previous_ema) * multiplier + previous_ema;
console.log(EMA + " ema");
previous_ema = EMA;
}
}
}
// UPDATE Added my whole script (which can be runned)- https://pastebin.com/91GEuATM
You need Nodejs and the binance node api installed (npm install node-binance-api --save) ; Keep in mind that this is just my "test script" hence all the weird variable names etc.
//UPDATE 2 Ticks sample data https://pastebin.com/AFzf7GwQ
I have a js which is integrated into other websites. When the user enters the site, a function is called from the script and an element pops up.
Is it possible for me, in the js function that pops-up the element, to make it open only for a certain percentage (let's say 60%) of the users?
I thought about using the Math.random() function, but i'm not sure how to make it.
EDIT:
After thinking about it, it might be that this is not achievable by javascript alone and it will require the use of some kind of tracking of users (via database or such). If someone knows of a different way, I'll be happy to hear it.
It is easily achievable by Javascript, and it's very simple!
var pctg = 60; // Set percentage here
var rndm = Math.ceil(Math.Random() * 100);
if (rndm <= pctg) {
// Execute popup statement(s)
}
On a first glance, this code snippet gives a 60% chance that the popup will occur: that is, one page view is completely independent from another page view. It can easily happen that 20 or more subsequent visitors get the popup, but the opposite is also possible. But the more visitors, the closer the 60% will be approached.
If you want to be mercillesly accurate, you can say 'set the percentage that a given visitor will receive the popup'.
This method will not attempt any kind of balance, it relies purely on sheer number of page views. Also, do not forget, that this is per page view.
If you want to remember whether or not a certain user should receive popups between visits, you can use cookies:
document.cookie="bShowPopup=0"; or document.cookie="bShowPopup=1";
This also opens up the possibility to create a more powerful code, one that creates a given chance of displaying the popup per page view, up until the point that the popup has already been displayed once:
First a function to read and write the specified cookie string:
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1);
if (c.indexOf(name) != -1) return c.substring(name.length,c.length);
}
return "";
}
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + "; " + expires;
}
Please check out http://www.w3schools.com/js/js_cookies.asp for more information regarding the use of cookies.
Next we could do this:
// See if the user already received the popup
// The if statement will only evaluate to true if the popup is *not* explicitly disabled (that is, it is set to 1, or not set)
if (getCookie('bShowPopup') !== '0')
{
var pctg = 60; // Set percentage here
var rndm = Math.ceil(Math.Random() * 100);
if (rndm <= pctg) {
// Execute popup statement(s)
//stmt123....
// Set cookie bShowPopup to 0 (so the user won't receive popups ever again)
// NOTE: The cookie will expire after 30 days.
setCookie('bShowPopup', '0', 30);
}
}
Another approach, that will create the closest result without any server-side programming or user-tracking is to check whether a certain user should be shown popups only once, and then store the decision result in a cookie. The only thing to modify in the previous code is to set the bShowPopup cookie to 0 even if the popup wasn't shown.
if (getCookie('bShowPopup') !== '0')
{
var pctg = 60; // Set percentage here
var rndm = Math.ceil(Math.Random() * 100);
if (rndm <= pctg) {
// Execute popup statement(s)
//stmt123....
}
setCookie('bShowPopup', '0', 30);
}
Please, also refer to http://www.w3schools.com/jsref/jsref_random.asp regarding the use and return valies of Math.random().
Using Math.Random() is a good choice for this. Math.Random() generates a number between 0 and 1, so if you want a random number between 0 and 10, multiply the result by 10, then take the ceiling of that number to remove the decimal places and convert it to a round number. For 0 to 100, multiply it by 100. At the beginning of your pop-up function, add the following:
var rand = Math.Random() * 100;
next wrap the code that displays the popup in an if statement that checks to see if the random number you generated is less than or equal to 60:
if(Math.ceil(rand) <= 60) {
...
}
Heres an example of what I did when I needed this functionality
The following code would be a bit easier to maintain if you change the number of options or the chance percentage.
var contentId, random = Math.random();
if (random < 0.5) {
// option 1: chance 0.0–0.499...
contentId = 0;
} else (random < 0.75) {
// option 2: chance 0.50—0.7499...
contentId = 1;
} else {
// option 3: chance 0.75–0.99...
contentId = 2;
}
loadContent(contentId);
EDIT Based on comment feedback.
Glad to help. If this is a php page then you don't need ajax. Simply update/return the count at the top of the page via php/sql and then echo that figure into your JS function. You only need to check whether the figure is divisible by 3. If it is then run your popup function. This way you can also report on the amount of times the popup would have been activated.