Anti-Raid event DiscordJS - discord

I am creating a security discord bot and I would like to know how to include createdAt in an event, and create a command like that .setwelcomeban 5d command (for example) which will cause all joining accounts to be automatically kicked.

You can get when a member joined a server using the joinedAt or joinedTimestamp property of a GuildMember object.
You can then loop through each member in a guild, compare the current date with the date they joined, and kick the member if they joined within the amount of days you specified.
Remember to change the /* number of days */ part to take the number of days you specify.
message.guild.members.cache.each(member => {
const date1 = new Date(member.joinedAt).getTime();
const date2 = new Date().getTime() - /* number of days */ * 24 * 60 * 60 * 1000;
if (date2 < date1) {
member.kick();
}
});

Related

Checking if JoinDate is within x amount of days

Using moment, I'm trying to create an if statement to see if their joinDate is within 14 days.
let joinDate = ${moment(member.joinedAt).format("YYYY, MMMM Do dddd, HH:mm:ss")}
That's my current code to format when the user joined.
Basically what I'm saying (if you're not following) is how would I check if joinDate is within the last 14 days?
You may wanna use momentjs diff function to get the days difference between the current date and the input .
A Snippet for your reference
const selectedDate = "2021-08-07";
const date_temp = moment().diff(selectedDate, "days", true);
console.log('Is within 14 days? ',date_temp >= 0 && date_temp <= 14);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

Display rows with current date as top result using react-table

I'm trying to create a table using react-table that would display data that matches today's date as the top result. For instance, today is 18 August 2021, so I would like any data entry that matches 08/18/2021 (mm/dd/yyyy format) to be displayed as the topmost entry in my table.
My current table looks like this
To give an example, I have already sorted my table in chronological order (from earliest to latest in mm/dd/yyyy format). However, I want any entry/entries in the table above with today's date (eg. Date of Operation: 08/18/2021) to be displayed at the top of the table. Thereafter, entries that do not match today's date will continue to be sorted in chronological order.
Can someone please let me know how this can be done? Thank you.
Without getting into the code details, you should be able to do this by supplying a custom sort function in the column definition API docs. We don't do this specific sort but we do have multiple custom sort functions, and I got the most help in writing them by reading the sortTypes.js file from the library source.
Here's a simple date sort function. You basically get two rows and a columnId and return -1, 0, or 1.
const prevDate = new Date(prev.original[columnId])
const prevIsDate = ...
const currDate = new Date(curr.original[columnId])
const currIsDate = ...
if (prevIsDate && currIsDate) {
return prevDate > currDate ? 1 : -1
} else {
if (!prevIsDate) {
return !currIsDate ? 0 : 1
} else {
return 1
}
}
}

How to replace nested for loop to Map and any way to reduce the time calculation part?

How to replace the nested for loop with map?
HOW TO REPLACE THE NESTED FOR LOOP BY MAP
public class Casecal {
public void calculatetime(List caseids,Map casemap){
map<string,List<CaseMilestone>> milestonemap = new map<string,List<CaseMilestone>>();
if(casemap!=null && caseids.size()>0){
BusinessHours bh = [SELECT Id FROM BusinessHours WHERE IsDefault=true];
List<Case> caselist = [Select id, (select caseId,id,isCompleted,MilestoneTypeId,BusinessHoursId,MilestoneType.name,CompletionDate from
CaseMilestones where(MilestoneType.name='First Response' or MilestoneType.name='Technical Resolution')
AND caseid IN:casemap.keySet()) from case];
for(Case cs: caselist ){
milestonemap.put(cs.id,cs.Casemilestones);
}
for(Case c: caseids){
if(c.Request_for_Closure_Date__c!=null && milestonemap.containskey(c.id) ){
for(CaseMilestone ml:milestonemap.get(c.id)){
if(ml.MilestoneType.name=='First Response'){
Integer ms = Integer.valueOf((BusinessHours.diff(bh.id, ml.CompletionDate, c.Request_for_Closure_Date__c))/1000);
system.debug('Time#calculation'+ms);
Integer sec = ms;
Integer mns = sec/60;
integer days = mns / 60 / 24 ;
integer hours = (mns - days * 60 * 24) / 60 ;
integer mins = mns - days * 60 * 24 - hours * 60 ;
String timeSpentOnCase = days+'Days '+hours+'Hours '+mins+'Minutes'+sec+'Secs';
System.debug('Time'+timeSpentOnCase);
c.Test_Ignore__c = ml.CompletionDate;
}
else if(ml.MilestoneType.name=='Technical Resolution'){
c.Test_Ignore_2__c = ml.CompletionDate;
}
}
}
}
}
}
}
These loops have already been optimized, but the Map-based data access is not actually necessary because the child objects are queried with the parents.
for(Case cs: caselist ){
milestonemap.put(cs.id,cs.Casemilestones);
}
This is not needed at all and can be removed. Instead, change the inner for loop to refer to the child CaseMilestones list directly.
for(Case c: caseids){
if(c.Request_for_Closure_Date__c!=null){
for(CaseMilestone ml : c.CaseMilestones){
The loop simply won't execute if c.CaseMilestones is empty.
There is no further Map-based optimization for this code.
What David said in above comment, the access is pretty optimised as is.
If you seek further optimisation I'd:
Move if(c.Request_for_Closure_Date__c!=null and improve the WHERE clause (why you want to retrieve some Cases if you skip them in processing?). So something like
SELECT Id,
(SELECT CaseId, Id, isCompleted...
FROM CaseMilestones
WHERE ...)
FROM Case
WHEREId IN :caseids AND Request_for_Closure_Date__c!=null
throw this code away. If it's just for system.debug - you're just wasting the calculation time.
Integer ms = Integer.valueOf((BusinessHours.diff(bh.id, ml.CompletionDate, c.Request_for_Closure_Date__c))/1000);
system.debug('Time#calculation'+ms);
Integer sec = ms;
Integer mns = sec/60;
integer days = mns / 60 / 24 ;
integer hours = (mns - days * 60 * 24) / 60 ;
integer mins = mns - days * 60 * 24 - hours * 60 ;
String timeSpentOnCase = days+'Days '+hours+'Hours '+mins+'Minutes'+sec+'Secs';
System.debug('Time'+timeSpentOnCase);
If after these 2 optimisations you still have performance problems then you might have to rethink your business logic and query. Is it guaranteed that there will be at most 1 milestone of each type on case?
Maybe you need a subquery with just one type that would give you latest milestone? Something like SELECT Id, (SELECT CompletionDate FROM CaseMilestones WHERE Type = 'x' ORDER BY CompletionDate DESC LIMIT 1) FROM Case? Then you run this query for second type and process. Ok, wastes 2 queries but guaranteed to return only few rows.
Or maybe you can simplify this code completely by doing something like
SELECT CaseId, MAX(CompletionDate) d, MilestoneType.Name t
FROM CaseMilestone
WHERE CaseId IN :... AND MilestoneType.Name IN :...
GROUP BY CaseId, MilestoneType.Name

How to check if a string date has passed a certain date

I have these strings:
yy = "19";
mm = "05";
dd = "31";
These represent the creation date of a certain object in my project. This object expires after one month. How do I check if the object has expired already?
(I came across this solution but thought there might be another way to do it.)
UPDATE: the string date apparently represent the actual expiry date
I ended up using the date format "yymmdd" so I can convert it to type long and do a simple number comparison.
sprintf(buffer, "%s%s%s", yy, mm, dd);
expiryDate = atol(buffer);
// get current date of format "yymmdd" as well
// getCurrentDate() is my function that gets the date from my SDK
currentDate = getCurrentDate();
if(expiryDate >= currentDate)
{
// expired object!
}

Trying to avoid Governor limits in no of SOQL queries

i have 2 custom objects appointment_c and TimeDrive_c.
Appointment has fields
startdate__c
contact__c
TimeDrive__c has
Target_date__c
contact__c
CreatedDate
Here is what i need to do
I need to get all get all records with in a specific date range
select id, Target_date__c, Contact__c, Name, CreatedDate
from TimeDrive__c where Target_date__c >=:startdate and
Target_date__c <=:enddate
i need to loop through each record in this list and check if there are appointments for this contact which has startdate fall between targetdate and createddate
Here is the bit i have done till now
timeDriverLst = [select id, Target_date__c, Contact__c, Name, CreatedDate
from TimeDrive__c where Target_date__c >=:startdate and
Target_date__c <=:enddate ];
if(timeDriverLst.size() >0){
for(integer i =0; i < timeDriverLst.size(); i++)
{
mapTime.put(timeDriverLst[i].id, timeDriverLst[i]);
/* appLst = [Select Name, Contact__c from Appointment__c where (StartDate__c > = :timeDriverLst[i].CreatedDate
and StartDateTime__c <=:timeDriverLst[i].Target_date__c) and Contact__c = :timeDriverLst[i].Contact__c ];
*/
}
I know i shouldnt have a SOQL query within a for loop. How can i avoid this and achieve the requirement.
An ugly, but possibly usable solution: You could get all the contact ids from the time driver list and also find the earliest created date. Then you could pull out all the appointments whose contact id is in the contact id list and whose date is between the earliest created date and the target date. Then you would need to do a double loop, checking each appointment against each time driver. (Ordering the appts by contact or by date as you retrieve them might help here).

Resources