I am currently developing a Discord Bot focused on sharing Twitter Tweets to Discord Channels, coded in Node JS and using npm module Twit for Twitter API.
Twit, basically creates a stream event, that occurs everytime one of the users from the IDs Array Tweets Something and then a .on with the tweet information defined as tweet.
stream = twitterClient.stream('statuses/filter', { follow: followArray })
stream.on('tweet', tweet => {
})
The followArray is the Array containing the Users IDs, defined like: followArray = ['3083945176', '34507480']
However, if I want to add or remove an ID from the Array, I would have to restart the Bot, instead of being able to just followArray.push(userID). How could I update the Array without having to restart the Bot?
Related
I want to send newsletters to multiple users, but when I try my code, the emails can be seen by everyone. And if I send it using looping, I'm afraid it will take a long time because there are many users. Is there a good solution to send multiple emails?
This is my code (I use SMTP):
await Mail.send('newsletter', data, (message) => {
message
.from('newsletter#web.com', 'Admin')
.subject('New Events Notification')
.to(emails) // array consist of multiple emails
})
You can use the sendLater method to send multiple emails. The Adonis js uses the memory queue inside this method. So it will not block your HTTP request.
After replacing the method your code will look like this .
await Mail.sendLater('newsletter', data, (message) => {
message
.from('newsletter#web.com', 'Admin')
.subject('New Events Notification')
.to(emails) // array consist of multiple emails
})
Now you can add your loop and Adonis js will send email in background.
Twitter API Client for node called Twit. I am using twit for my nodejs application to scrape twitter data.
var stream = T.stream('statuses/filter', { follow: twitter_config.handles , track: twitter_config.topics , language: twitter_config.languages });
I am using above approach but it doesn't seem to work.
twitter_config.handles are the user-ids and topics are the keywords.
is user-ids correct way of referencing for this architecture???
Should I be using screen_name or user-id???
What to do if i have to use few thousand user-ids and a few keywords??
What about using the same-ip address for entire twitter-scraping application???
Purpose: I'm trying to make my bot check for reactions from a specific message.
I've read this post: Get Message By ID: Discord.js
But it didn't help at all.
I've searched the internet to see how can I use .fetchMessage properly. But unfortunately didn't find any results.
This is my code:
client.channels.get('CHANNEL ID').fetchMessage('MESSAGE ID').then(async msg => { *CODE HERE* });
This is the error i get:
TypeError: client.channels.get is not a function
I do realise that client.channels.get is not a function and I should use this in a function but I don't know how to.
Discord.js version: 12.0.2
Node.js verison: 12.13
That answer was for v11, in v12 it has changed to:
client.channels.cache.get(chid).messages.cache.fetch(mesid)
However, it's important to note that client.channels.cache may contain non-text channels, if you are retrieving an ID that you know to be a TextChannel type, you will be fine but if the ID is being retrieved programmatically you need to check to ensure it is an instanceof TextChannel.
In v12 it has changed and uses managers and added this command to my bot and fixed it.
let channelMessage = client.channels.cache.get(channel_id) // Grab the channel
channelMessage.messages.fetch(message_id).then(messageFeteched => messageFeteched.delete({timeout: 5000})); // Delete the message after 5 seconds
I'm currently attempting to accept voice input from the user, feed it into the Bing Speech API to get text, and pass that text as a user response. I've gotten as far as receiving the text back from Bing, but I'm not sure how to send that text as a user response. I've been scouring GitHub, so any feedback is appreciated. Relevant code is below:
function(session){
var bing = new client.BingSpeechClient('mykey');
var results = '';
var wave = fs.readFileSync('./new.wav');
const text = bing.recognize(wave).then(result => {
console.log('Speech To Text completed');
console.log(result.header.lexical)
console.log('\n');
results.response = result.header.lexical;
});
}]
You should use session.send.
I recommend you to take a look to the intelligence-SpeechToText sample, where a similar scenario is being shown.
Update: Figured it out (sorta). In order to take advantage of sending this user input back, I had to use another card. Within the context of the card, I'm able to use the imBack function
I just started the Meteor js, and I'm struggling in its publish method. Below is one publish method.
//Server side
Meteor.publish('topPostsWithTopComments', function() {
var topPostsCursor = Posts.find({}, {sort: {score: -1}, limit: 30});
var userIds = topPostsCursor.map(function(p) { return p.userId });
return [
topPostsCursor,
Meteor.users.find({'_id': {$in: userIds}})
];
});
// Client side
Meteor.subscribe('topPostsWithTopComments');
Now I'm not getting how I can use publish data on client. I meant I want to use data which will be given by topPostsWithTopComments
Problem is detailed below
When a new post enters the top 30 list, two things need to happen:
The server needs to send the new post to the client.
The server needs to send that post’s author to the client.
Meteor is observing the Posts cursor returned on line 6, and so will send the new post down as soon as it’s added, ensuring the client will receive the new post straight away.
However, consider the Meteor.users cursor returned on line 7. Even if the cursor itself is reactive, it’s now using an outdated value for the userIds array (which is a plain old non-reactive variable), which means its result set will be out of date as well.
This is why as far as that cursor is concerned, there is no need to re-run the query and Meteor will happily continue to publish the same 30 authors for the original 30 top posts ad infinitum.
So unless the whole code of the publication runs again (to construct a new list of userIds), the cursor is no longer going to return the correct information.
Basically what I need is:
if any changes happens in Post, then it should have the updated users list. without calling user collection again. I found some user full mrt modules.
link1 |
link2 |
link3
Please share your views!
-Neelesh
When you publish data on the server you're just publishing what the client is allowed to query. This is for security. After you subscribe to your publication you still need to query what the publication returned.
if(Meteor.isClient) {
Meteor.subscribe('topPostsWithTopComments');
// This returns all the records published with topPostsWithComments from the Posts Collection
var posts = Posts.find({});
}
If you wanted to only publish posts that the current user owns you would want to filter them out in the publish method on the server and not on the client.
I think #Will Brock already answered your question but maybe it becomes more clear with an abstract example.
Let's construct two collections named collectiona and collectionb.
// server and client
CollectionA = new Meteor.Collection('collectiona');
CollectionB = new Meteor.Collection('collectionb');
On the server you could now call Meteor.publish with 'collectiona' and 'collectionb' separately to publish both record sets to the client. This way the client could then also separately subscribe to them.
But instead you can also publish multiple record sets in a single call to Meteor.publish by returning multiple cursors in an array. Just like in the standard publishing procedure you can of course define what is being sent down to the client. Like so:
if (Meteor.isServer) {
Meteor.publish('collectionAandB', function() {
// constrain records from 'collectiona': limit number of documents to one
var onlyOneFromCollectionA = CollectionA.find({}, {limit: 1});
// all cursors in the array are published
return [
onlyOneFromCollectionA,
CollectionB.find()
];
});
}
Now on the client there is no need to subscribe to 'collectiona' and 'collectionb' separately. Instead you can simply subscribe to 'collectionAandB':
if (Meteor.isClient) {
Meteor.subscribe('collectionAandB', function () {
// callback to use collection A and B on the client once
// they are ready
// only one document of collection A will be available here
console.log(CollectionA.find().fetch());
// all documents from collection B will be available here
console.log(CollectionB.find().fetch());
});
}
So I think what you need to understand is that there is no array sent to the client that contains the two cursors published in the Meteor.publish call. This is because returning an array of cursors in the function passed as an argument to your call to Meteor.publish merely tells Meteor to publish all cursors contained in the array. You still need to query the individual records using your collection handles on the client (see #Will Brock's answer).