Convert Discord.js v11 module to v12? - networking

I mostly have this discord bot working. I am just having some trouble with this one module. The root of the problem is that this code was written for discord.js v11. I need to rewrite it for v12.
The original v11 module can be found here:
https://github.com/Meschdog18/disnet/blob/master/commands/broadcast.js
Here is what I have thus far:
exports.run = (client, message, args) => {
var serverlist = client.guilds.cache.size;
console.log(client.Networks)
var server = message.guild.channels.cache;
var Sender = client.Networks.get(message.guild.name);
const input = args.join(" "); //rejoins arg array into string
for (var i = 0; i < serverlist.length; i++) {
//get network id of message sender
var Recipient = client.Networks.get(serverlist[i].name);
Recipient = parseInt(Recipient);
if (Sender == Recipient) {
try {
var serv = serverlist[i].channels.cache.find(
serv => serv.name === "broadcast"
);
serv.send({
embed: {
/* author: { works but is disabled, because not sure if i like the look
name: "Disnet",
icon_url: client.user.defaultAvatarURL
},*/
color: 0x3850eb,
title: "**__BROADCAST__**",
thumbnail: {
url: message.guild.iconURL
},
fields: [{
name: "Broadcasted From ",
value: message.guild.name
}, {
name: "Message",
value: input
}
],
timestamp: new Date(),
footer: {
icon_url: message.author.avatarURL,
text: "Executed By " + message.author.username
}
}
})
} catch (error) {
console.log(error);
message.reply(
"You must create a #broadcast channel to recieve messages!"
);
break;
}
}
}
};
exports.help = {
name: "broadcast",
description: "Broadcasts message to all servers on your network",
usage: "N$broadcast <Message>"
};
exports.config = {
permLevel: "admin"
}
This module is meant to have the bot transmit a message to every server in my network of discord servers. (it does use enmap and MySQL, but this module doesn't appear to use the SQL component(s))
It is not transmitting messages to the other servers in my network, but I am not getting any errors thrown in my terminal. The bot just gives me this:
Enmap(2) [Map] {
'Discord Sports & Athletics Associations' => 'DSAAnet',
'NFL Discussion 2.0' => 'DSAAnet'
}
Which appears to be correct. (DSAAnet is the name of the network, and the other two names are names of servers in the network.)
Is this correct? What else do I need to change to make this v12 compatible?

you can see every change on this website: Updating from v11 to v12

I think you were reading this part.
Collection#filterArray
collection.filterArray() was removed entirely, as it was just a helper method for collection.filter().array() and most of the time converting a collection to an array is an unnecessary step.
No, .array() was never ever removed.
And for your question, it says .avatarURL, .iconURL, .defaultAvatarURL is now .avatarURL(), .iconURL(), .defaultAvatarURL()
That should fix the issue :)

Related

Error while making request: socket hang up. Error code: ECONNRESET

I'm using node.js as a backend server for sending push notification from the Firebase Cloud Messaging service. The notifications are working fine with local server but on live server, I get this error:
Error while making request: socket hang up. Error code: ECONNRESET
Things to consider are that...
Number of users are in the thousands on live server
Firebase version is firebase-admin#6.5.1
Previously unregistered tokens are still there. But now registered tokens are being stored.
This is my code for sending notifications:
for (let c = 0; c < tokens.length; c++)
{
let notifyTo = tokens[c];
const platform = platforms[c];
let payload;
if (platform === "ios") {
payload = {
notification: {
title: "title",
subtitle :"messgae",
sound: "default",
badge: "1"
},
data: {
sendFrom: "",
notificationType: "",
flag: "true"
}
};
} else if (platform === "android") {
payload = {
data: {
title: "",
message : "",
flag: "true"
}
};
}
const registrationtoken = notifyTo;
await admin.messaging().sendToDevice(registrationtoken, payload)
.then(function (response) {
console.log("Successfully sent message:");
})
.catch(function (error) {
console.log("Error sending message: ");
});
}
Your issue is caused by your function taking too long to respond to the client (more than 60 seconds) and is caused by the following line:
await admin.messaging().sendToDevice(registrationtoken, payload)
Because you are waiting for each call of sendToDevice() individually, you are running your for-loop in synchronous sequential order, rather than asynchronously in parallel.
To avoid this, you want to make use of array mapping and Promise.all() which will allow you to build a queue of sendToDevice() requests. As in your current code, any failed messages will be silently ignored, but we will also count them.
Your current code makes use of two arrays, tokens and platforms, so in the code below I use a callback for Array.prototype.map() that takes two arguments - the current mapped value (from tokens) and it's index (your for-loop's c value). The index is then used to get the correct platform entry.
let fcmPromisesArray = tokens.map((token, idx) => {
let platform = platforms[idx];
if (platform === "ios") {
payload = {
notification: {
title: "title",
subtitle :"messgae",
sound: "default",
badge: "1"
},
data: {
sendFrom: "",
notificationType: "",
flag: "true"
}
};
} else if (platform === "android") {
payload = {
data: {
title: "",
message : "",
flag: "true"
}
};
}
return admin.messaging().sendToDevice(token, payload) // note: 'await' was changed to 'return' here
.then(function (response) {
return true; // success
})
.catch(function (error) {
console.log("Error sending message to ", token);
return false; // failed
});
});
let results = await Promise.all(fcmPromisesArray); // wait here for all sendToDevice() requests to finish or fail
let successCount = results.reduce((acc, v) => v ? acc + 1 : acc, 0); // this minified line just counts the number of successful results
console.log(`Successfully sent messages to ${successCount}/${results.length} devices.`);
After this snippet has run, don't forget to send a result back to the client using res.send(...) or similar.

Why am I getting a 404 'App [my-project-id] was not found. The app preview may have expired.' trying push notifications on my Actions on Google?

I'm following the official instructions on how to send push notifications to users that gives their permission.
I'm able to follow all the instructions until this code
appMap.set('finish.push.setup', function(app)) {
if (app.isPermissionGranted()) {
const intent = app.getArgument('UPDATE_INTENT');
const userID = app.getArgument('UPDATES_USER_ID');
// code to save intent and userID in your db
app.tell("Ok, I'll start alerting you");
} else {
app.tell("Ok, I won't alert you");
}
}
the app.getArgument('UPDATE_INTENT') return undefined and checking the JSON it looks like it doesn't contain the intent at all but I have only one intent configured for updates so I hardcoded it's name in the code.
I got a userID and I hardcoded it too in the code.
Then I followed the instructions to get a service account key and I saved the JSON key locally.
Then the nasty problems begins.
I installed the required packages with npm install googleapis request --save and copied the code
const google = require('googleapis');
const key = require(PATH_TO_KEY);
let jwtClient = new google.auth.JWT(
key.client_email, null, key.private_key,
['https://www.googleapis.com/auth/actions.fulfillment.conversation'],
null
);
jwtClient.authorize(function (err, tokens) {
// code to retrieve target userId and intent
let notif = {
userNotification: {
title: '',
},
target: {
userId: '',
intent: ''
}
}
request.post('https://actions.googleapis.com/v2/conversations:send', {
'auth': {
'bearer': tokens.access_token
},
'json': true,
'body': { 'customPushMessage': notif }
}, function(err,httpResponse,body) {
console.log(httpResponse.statusCode + ': ' + httpResponse.statusMessage)
});
});
I edited it setting the right path to my key and edited the notification property with fixed values (the same title configured in the action, the userID returned by dialogflow and the name of my intent).
Then I noticed that the code is missing a const request = require('request'); and the line
let jwtClient = new google.auth.JWT(
gives an error so I changed to
let jwtClient = new google.google.auth.JWT(
I added a console.log('body', body); just to get more data and I got
body { error:
{ code: 404,
message: 'App [my-project-id] was not found. The app preview may have expired.',
status: 'NOT_FOUND' } }
Am I doing something wrong or the documentation has other errors I still have to catch?
try to add locale at target object:
let notif = {
userNotification: {
title: '',
},
target: {
userId: '',
intent: '',
locale: ''
}
}
For locale follow IETF BCP-47 language code as described here.
By default Google Actions use en-US language, and I figure out you are using a differente language code, so the system reply that cannot found us version of your application.

How can I delete a post from a supergroup in telegram with telegram-cli?

we have a group in telegram and we have a rule says no one must leave a message in group between 23 to 7 am , I wanna delete messages comes to group between these times automatically . could anyone tell me how I can do that with telegram cli or any other telegram client?
Use new version of telegram-cli. It's not fully open source, but you can download a binary from its site. Also you can find some examples there.
I hope the following snippet in JavaScript will help you to achieve your goal.
var spawn = require('child_process').spawn;
var readline = require('readline');
// delay between restarts of the client in case of failure
const RESTARTING_DELAY = 1000;
// the main object for a process of telegram-cli
var tg;
function launchTelegram() {
tg = spawn('./telegram-cli', ['--json', '-DCR'],
{ stdio: ['ipc', 'pipe', process.stderr] });
readline.createInterface({ input: tg.stdout }).on('line', function(data) {
try {
var obj = JSON.parse(data);
} catch (err) {
if (err.name == 'SyntaxError') {
// sometimes client sends not only json, plain text process is not
// necessary, just output for easy debugging
console.log(data.toString());
} else {
throw err;
}
}
if (obj) {
processUpdate(obj);
}
});
tg.on('close', function(code) {
// sometimes telegram-cli fails due to bugs, then try to restart it
// skipping problematic messages
setTimeout(function(tg) {
tg.kill(); // the program terminates by sending double SIGINT
tg.kill();
tg.on('close', launchTelegram); // start again for updates
// as soon as it is finished
}, RESTARTING_DELAY, spawn('./telegram-cli', { stdio: 'inherit' }));
});
}
function processUpdate(upd) {
var currentHour = Date.now().getHours();
if (23 <= currentHour && currentHour < 7 &&
upd.ID='UpdateNewMessage' && upd.message_.can_be_deleted_) {
// if the message meets certain criteria, send a command to telegram-cli to
// delete it
tg.send({
'ID': 'DeleteMessages',
'chat_id_': upd.message_.chat_id_,
'message_ids_': [ upd.message_.id_ ]
});
}
}
launchTelegram(); // just launch these gizmos
We activate JSON mode passing --json key. telegram-cli appends underscore to all fields in objects. See all available methods in full schema.

Data passed via Segment API does not show up on Google Analytics

I am using Segment.com .NET APIs to pass data to Google Analytics. But even after 3 to 4 days The data has not appeared on Google. Nor I can see data in the Debugger section of Segment's Account Dashboard.
I wonder what is happening? Is there any special configuration to be done at Google side for the data to appear ? or is there anything else I am missing.
Following is the code used.
Analytics.Initialize("pOAM4 Some-KEY PrAC",new Config().SetAsync(false));
Analytics.Client.Identify("BillGates", new Segment.Model.Traits() {
{ "name", uname },
{ "email", uemail },
{ "friends", counter }
});
Analytics.Client.Track("BillGates", "Purchased Item", new Segment.Model.Properties() {
{ "Item", itemcounter},
{ "revenue", 39.95 },
{ "shipping", "2-day" }
});
Analytics.Client.Track("BillGates", "Logged Out", new Segment.Model.Properties() {} );
I am executing them several times.... and I expect something to appear on Google Analytics Dashboard, but its bank.
Any help from anyone who have used Segment.com APIs ?
If your data isn't getting to the Segment debugger, that means that something is probably wrong in your implementation, either API keys or improperly formatted code and I'd recommend using the logging that's built into this lib, you can use it like so.
using Segment;
Segment.Logger.Handlers += Logging_Handler;
void Logging_Handler(Level level, string message, Dict args)
{
if (args != null)
{
foreach (string key in args.Keys) {
message += String.Format(" {0}: {1},", "" + key, "" + args[key]);
}
}
Console.WriteLine(String.Format("[Analytics] [{0}] {1}", level, message));
}
The one thing that jumps out to me is that you're calling new Segment.Model.Properties() in your .Track() and new Segment.Model.Traits() in your .Identify().
I've always used new Properties() in .Track() and new Traits() in .Identify() like so
Analytics.Client.Identify("<<userId>>", new Traits() {
{ "name", "#{ user.name }" },
{ "email", "#{ user.email }" },
{ "friends", 29 }
});
Analytics.Client.Track("<<userId>>", "Purchased Item", new Properties() {
{ "revenue", 39.95 },
{ "shipping", "2-day" }
});
The code for this lib is all open-source and available on github here and the Segment docs are pretty thorough as well.
Good luck!

MailChimp API 3.0 Subscribe

I am having trouble sorting out the new MailChimp API (V3.0). It does not seem like there is a way to call a subscribe method. It seems like I have to use their Sign Up Form. Am I correct?
If by "subscribe" you mean that your application will add someone to a mailing list, you may want to take a look at the List Members Collection portion of their documentation.
http://kb.mailchimp.com/api/resources/lists/members/lists-members-collection
Adding/editing a subscriber via MailChimp v3.0 REST API.
// node/javascript specific, but pretty basic PUT request to MailChimp API endpoint
// dependencies (npm)
var request = require('request'),
url = require('url'),
crypto = require('crypto');
// variables
var datacenter = "yourMailChimpDatacenter", // something like 'us11' (after '-' in api key)
listId = "yourMailChimpListId",
email = "subscriberEmailAddress",
apiKey = "yourMailChimpApiKey";
// mailchimp options
var options = {
url: url.parse('https://'+datacenter+'.api.mailchimp.com/3.0/lists/'+listId+'/members/'+crypto.createHash('md5').update(email).digest('hex')),
headers: {
'Authorization': 'authId '+apiKey // any string works for auth id
},
json: true,
body: {
email_address: email,
status_if_new: 'pending', // pending if new subscriber -> sends 'confirm your subscription' email
status: 'subscribed',
merge_fields: {
FNAME: "subscriberFirstName",
LNAME: "subscriberLastName"
},
interests: {
MailChimpListGroupId: true // if you're using groups within your list
}
}
};
// perform update
request.put(options, function(err, response, body) {
if (err) {
// handle error
} else {
console.log('subscriber added to mailchimp list');
}
});

Resources