sharing messages between telegram bots - node.js

I'm using node-telegram-bot-api package
and I have two telegram bots like this:
const TelegramBot = require('node-telegram-bot-api');
let bot1 = new TelegramBot(token1, { polling: true });
let bot2 = new TelegramBot(token2, { polling: true });
I'm kind of making a connection between these two bots, In a way that messages that are recieved from bot1 should be sent to user by bot2 and vice versa
something like:
bot1.on('message', (msg) => {
if (msg.video) { // video in this case
bot2.sendVideo(user2_chatid, msg.video.file_id);
}
});
In the above code I am trying to send the video to user2 using bot2, once bot1 receives a video
using file_id to reference sticker is all right, but for photos, videos, voices etc I get this error
wrong file identifier/HTTP URL specified
Looks like telegram is kind of private about the bots and the data they can share, means that file_id is something private and only accessible by the bot it self
How can I share these data between telegram bots?
and I strongly prefer a way other than saving photos and videos somewhere on the server then sending them

https://core.telegram.org/bots/api#sending-files
file_id is unique for each individual bot and can't be transferred from one bot to another.
so I guess the answer Is no, unless I would save the file somewhere, upload it again using bot2 and then send it
for me a better solution was to use the same bot (bot1) for both users, so I can easily send the received file to any user who has started a chat with the bot

Related

How To Send A Discord.JS Startup Message To All Servers

I wanted to inquire on something I’ve been trying to do recently. I have a Discord.JS bot, and it’s pretty public (130+ servers), and I want it to send a message to any channel in every single server it’s in, when the bot starts up, the purpose is to create a “New Update” notification in one of the channels.
Please do not plan on doing this, as this will get you rate limited really quickly.
This is kind of possible. There is a problem, there is no default guild channel, so you cannot get their "main" channel just by their guild object. If you would want to do that you, would need them to select their channel and store that ID somewhere.
This is a simple solution, where you loop through every guild of your Discord client, and send some channel a message. You don't know what channel with this solution specifically, but you will send some channel a message if it is not a voice channel.
const Discord = require("discord.js");
require("dotenv").config();
// Creating our Client
const client = new Discord.Client();
// Event listener: when the bot is ready
client.on("ready", () => {
// Looping through every guild the bot is in
client.guilds.cache.forEach((guild) => {
// Getting one of their channels
let channel = guild.channels.cache.array()[2];
// Sending the channel a message
channel.send("Hey");
});
});
client.login(process.env.DISCORD_BOT_TOKEN);

How to get all non bot users in discord js using a discord bot in nodejs

I have created a discord bot by taking reference from this digital ocean link.
Now I can send message to any channel using the bot but my requirement is to send dm to user of that server.
For that I have tried many SO answers and followed other links, but all the solutions end up to be same.
I have tried this two way to get the users of a guild and send dm to any one selected user.
1st way - Get all users of guild (server)
const client_notification = new Discord.Client();
client_notification.on('ready', () => {
console.log("Notification manager ready");
let guild = client_notification.guilds.cache.get("Server ID");
guild.members.cache.forEach(member => console.log("===>>>", member.user.username));
});
client_notification.login("login");
Output
Notification manager ready
===>>> discord notification
By this way it only returns me the bot name itself. Although the membersCount is 6.
2nd way - send dm to user directly (server)
client.users.cache.get('<id>').send('<message>');
It gives me undefined in output.
My configs,
Node version: 10.16.3
discord.js version: 12.5.1
My question is how to get all the guild members in discord.js?
Discord added privileged gateway intents recently. So to fetch all member data you need to enable that in the developer portal. After that you need to fetch all the members available, for that we can use the fetchAllMembers client option, and then we need to filter out bot users, so that we don't message them.
const client_notification = new Discord.Client({fetchAllMembers:true}); //Fetches all members available on startup.
client_notification.on('ready', () => {
console.log("Notification manager ready");
let guild = client_notification.guilds.cache.get("Server ID");
guild.members.cache.filter(member => !member.user.bot).forEach(member => console.log("===>>>", member.user.username));
});
client_notification.login("login");
The .filter() method filters out all the bots and gives only the real users.
You should avoid using fetchAllMembers when your bot gets larger though, as it could slow down your bot and use lots of memory.
I think the problem is related to updating the bot policy for discord. Do you have this checkbox checked in the bot settings?
https://discord.com/developers/applications
Some info about client.users.cache:
Its a cache collection, so if you restart bot, or bot never handle user message or actions before, this collection will be empty. Better use guild.members.cache.get('')

discord.js playing audio on multiple servers

I made a test test bot for discord.js using Node.js / ffmpeg, to play a radio station in a channel on discord and there are no problems there, however i was thinking about how it would stream the same station to multiple servers/channels efficiently.
For example, if I am playing it on "Discord server one":
var voiceChannel = message.member.voiceChannel;
voiceChannel.join().then(connection => {
console.log("joined channel");
const dispatcher = connection.playArbitraryInput('http://philae.shoutca.st:8950/live', { volume: 0.5 });
dispatcher.on("end", end => {
console.log("left channel");
voiceChannel.leave();
});
}).catch(err => console.log(err));
However if i want to play it on another server that my bot is a member of, do i need to create the audio stream again?
If so that kinda sux. My bot would have to encode the stream seperatly for each instance?
I would like to know if there is any way i can reuse the audio stream and restream it so that if I had my bot in 100 channels its only one download instance of the stream and 100 uploads
I haope i am making sense but let me make some fake code to try help explain:
lets say instead i could do something like this:
let cachedAudioStream = cacheArbitraryInput('http://philae.shoutca.st:8950/live', {});
then for every outgoing instance:
connection1.playArbitraryInput(cachedAudioStream, { volume: 0.5 });
connection2.playArbitraryInput(cachedAudioStream, { volume: 0.8 });
connection3.playArbitraryInput(cachedAudioStream, { volume: 1 });
and so on
Thanks
Since the stream is managed by Discord.js (you only give a link, and Discord.js uses FFMPEG to handle it), you can't do it without modifying the Discord.js code.
Your question is relevant but I don't think it's feasible, at least if you uses Discord.js. You can still open an issue on their Github repository to ask them.
discord.js has a 'Voice Broadcast' for stuff like radio bots. Yes, you do have to connect the call to the broadcast but that's all.

How can I get my bot to post a message to a Microsoft Teams channel?

I have a bot that is identical to the one demonstrated in the docs quickstart. It repeats back whatever the user says (for now).
It is currently running locally and exposed with ngrok. I've registered the bot with the Microsoft Bot Framework.
I have configured the Microsoft Teams channel in the Microsoft Bot Framework, and I've sideloaded my bot into Teams. My bot can receive messages from Teams users.
At present, the bot just repeats whatever it receives back to the user, but what I want it to do is post to a Microsoft Teams channel. I want it to post to a Teams channel - not a user - without being prompted first by a user. So for example given a certain condition (eg. triggered by some event such as time of day, a pull request, etc.) it posts a message in a channel.
I've read the documentation about sending proactive messages, and I gather that in order to send a message to a teams channel, the bot needs to know the "address" of the user. This information is stored in the session.message.address object, and it gets this from the current conversation. However, in my case I don't have a 'current conservation', because I don't want to just respond to a user, I want to post in a channel proactively.
So, how do I permanently set the necessary credentials/address/session-data for the Teams channel?
Things I've looked into:
Webhooks. I've configured a webhook in my Teams channel, and I can send it a message easily enough (using the webhook url) using curl. So I can send the Teams channel a simple message with just a url (no authentication required), but I'm not sure how I'd get this url into my bot.
How do we maintain different session for different users in Microsoft Bot Framework? I'm not sure that the answer here answers my question. My problem is that the bot is initiating the 'conversation', not a Teams user, so I need to be able to set the session data myself so the bot knows where to go.
App.js:
require('dotenv').config();
var restify = require('restify');
var builder = require('botbuilder');
// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
// Create chat connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
// Listen for messages from users
server.post('/api/messages', connector.listen());
// Receive messages from the user and respond by echoing each message back (prefixed with 'You said:')
var bot = new builder.UniversalBot(connector, function (session) {
session.send("You said: %s", session.message.text);
});
For anyone who is wondering about the same for c#, here is the solution that worked for me:
var channelData = context.Activity.GetChannelData<TeamsChannelData>();
var message = Activity.CreateMessageActivity();
message.Text = "Hello World";
var conversationParameters = new ConversationParameters
{
IsGroup = true,
ChannelData = new TeamsChannelData
{
Channel = new ChannelInfo(channelData.Channel.Id),
},
Activity = (Activity) message
};
var connectorClient = new ConnectorClient(new Uri(activity.ServiceUrl));
var response = await
connectorClient.Conversations.CreateConversationAsync(conversationParameters);
Note: If you are calling this outside Bot's controller code then you need to call TrustServiceUrl on serviceUrl as shown here:
MicrosoftAppCredentials.TrustServiceUrl(serviceUrl, DateTime.MaxValue);
var connectorClient = new ConnectorClient(new Uri(serviceUrl));
Source of answer: https://github.com/OfficeDev/BotBuilder-MicrosoftTeams/issues/162
It is definitely possible. We call these proactive messages and it’s possible to proactively message both users and channels.
For the latter, see the sample at https://github.com/OfficeDev/microsoft-teams-sample-complete-node, specifically this file, ProactiveMsgToChannelDialog.ts.
To send proactive messages to channels, you need to use the Microsoft Teams SDK (as these samples do).
Last but not least, you need to add the bot to a team in order to send a message to one of the channels in the team, which requires a manifest.
Hope this works for you.. below code proactively sends the message to session before initiating the chat.
bot.on('conversationUpdate', function (message) {
if (message.membersAdded[0].id === message.address.bot.id) {
var reply = new builder.Message()
.address(message.address)
.text("Hello"");
bot.send(reply);
}
});

How to send a message to all subscribed users with kik bot

I'm just a beginner trying to learn how to write a bot for kik.
I'm trying to write it with the node js framework that kik has provided.
I want to send a message to all subscribed users of the bot; I found this in their docs:
bot.send(Bot.Message.text('Hey, nice to meet you!'), 'a.username');
but I'm confused as to how they get the username of the subscribed user. I tried using bot.getUserProfile.username, but it seems to be undefined.
Thanks for any help! Also, any tips on how this bot works would be appreciated! I have no web development experience; why does this bot have to be on a server?
First of all, if you want to send a blast to all of your users, I'd recommend using the broadcast API, which allows you to send messages by batches of 100 (instead of 25 for the regular send() API).
You can use the broadcast API like this:
bot.broadcast(Bot.Message.text('some message'), ['username1', 'username2']);
Documentation for this method can be found here.
As for sending messages to all of your users, you will need to have a list of usernames somewhere (in a database, for example). At the moment, Kik does not provide a way to get your list of subscribers.
Something like this would work:
bot.use((msg, next) => {
let username = msg.from; // Find the username from the incoming message
registerInDatabase(username); // Save it somewhere
next(); // Keep processing the message
});
You will need to make sure that this is placed before you declare any other handler (such as bot.onTextMessage(), for instance).

Resources