I am trying to create a chat application using pubnub api in javascript for first time
Below described is the logic i created for implementing a chat
User A is subscribed to channel "talktoA" and "ourPublicChannel"
User B is subscribed to channel "talktoB" and "ourPublicChannel"
When a User A want to talk to User B User A will a message to channel "talktoB"
as user B is subscribed to channel "talktoB" User B will receive the message and vice versa
When users want to send broadcast message the users need to send message to channel "ourPublicChannel"
Following are the code for each operations
1. **Establish a Connection**
var pubnub = PUBNUB.init({
publish_key: 'pub-mypublishkey',
subscribe_key: 'sub-mysubkey',
uuid : me
});
2. **Publish Message to a Channel**
//Sending a private message
pubnub.publish({
channel: ['privatechannelofB'],
message: {
text: “Test Message to userB ”,
username: me
}
});
//Sending a broadcast message
pubnub.publish({
channel: ['publicchannel'],
message: {
text: “A Broadcast Message to all user”,
username: me
}
});
3. **Subscribe /Receive to a channel**
pubnub.subscribe({
channel: ['myprivatechannel','mypublichannel']
message: function(data) {
alert(data)//Test Message
}
});
4. **History of message**
pubnub.history({
channel: channelname,
callback: function(m){console.log(m)},
});
I need to confirm the following
How to retrieve the offline messages ? if user A send message to user B and user B is offline i need to show the offline
messages?
History api will give the full list of message but how sort it whether it is offline messages
Is the approach right?
The Playback and Storage (history API) lets you to retrieve the message history of a channel up to 30 days retention.
When userA sends a message to userB, who is not connected to the internet, or the application is in the background, no problems, userB will be able to retrieve every message that was sent to his channel in the past 30 days.
Otherwise there is no difference between "offline" and "online" messages. If a message was successfully sent, you can retrieve it with the history API.
You can also use the Mobile Push Gateway for push notifications, in this case your user will receive the message when the app is in the background state.
For the best user experience I'm combining the two stuff and had zero problems with receiving messages.
Related
I'm trying to create a private messaging functionality using socket.io with React and Node.
I am able to send a message to a particular socket like so:
io.to(targetSocketID).emit('privateMessage' message)
it successfully sends it to that specific user but not the sender. is there a way to just emit a message to sender and the target user to make this simple? From what I can see there is two approaches here.
When a message is created push the sender messages into a messages array setMessages([...messages, senderMessages]) and also push the socket message into that array setMessages([...messages, receivedMessages]). this approach seems sloppy and like to avoid this route as it can become problematic.
generate a unique room for each user and send the room to the server and join it:
//server
socket.on('joinRoom', room => {
socket.join(room)
socket.on('privateMessage', message => {
socket.on(room).emit('messageResponse', message)
})
})
I would like to know if there is a better way to do this.
that allows me to emit a message to just sender AND targeted receiver.
I would send a message on telegram channel with telegraf. I'v einvited the bot and put him admin.
I've tested with this code:
bot.on('text', (ctx) => {
// Explicit usage
ctx.telegram.sendMessage(ctx.message.chat.id, `Hello ${ctx.state.role}`)
// Using context shortcut
// ctx.reply(`Hello ${ctx.state.role}`)
})
bot.launch();
But it replies only if i wrote on private.
So why it doesn't work on a channel?
Than how can i send a message in that channel without a command? (For example with and interval?
I i try this one:
bot.use((ctx) => {
console.log(ctx.message)
})
when i use the bot on private chat (with him) it returns all the message data. On the channel i receive undefined
In your case CTX have current chat info, if you want to send message to channel provide correct id as documented for Telegraf sendMessage:
telegram.sendMessage(process.env.TELEGRAM_CHANNEL, ctx.message.text);
I am using a bot for a public channel, so in my case it's:
TELEGRAM_CHANNEL=#MY_PUBLIC_CHANNEL_NAME
The channel name is available in channel info settings t.me/MY_PUBLIC_CHANNEL_NAME
I am new to Azure bot services. I have created a bot and hosted locally. I want to know when the connectivity between user and bot gets closed.
I actually need this to store chat history to DB that too before connection getting closed.
I am using Directline API.
Is bot connection will remains for a long time?
Is there any event triggers before connection close?
How actally connection between use and bot created and closed?
If you are using a directline channel within your own website the following method should work. Essentially you will just send a backchannel message to your bot when a user closes out of a chat with your bot.
Make sure to define your directline as follows so the connection can be used for backchannel messages
botConnection = new BotChat.DirectLine({
secret: "<secret>"
});
You will want to register an "onunload" method on your html body or div like so:
<body onunload="closeBotChat();">
and then within this method you simply send an event from your website to your bot that indicates that the conversation is over
function closeBotChat(){
botConnection
.postActivity({
from: { id: '<user>' },
value: "chat <conversationId> closed", //send whatever information you need about the conversation here
type: 'event',
name: "ConversationUpdate"
})
.subscribe(id=> console.log("closed" + id)) // this will likely not be shown unless the botchat is in a modal within the page somewhere
}
The following code when used in your bot will be able to hear and process this event:
bot.on("event", function(e){
console.log(util.inspect(e)); // do whatever with the conversation end event here
});
Note that you do not have to add anything for an "open connection" event with your bot webchat, as a ConversationUpdate event is sent automatically at the start of a new conversation.
I am implementing one to one and group chat in my application in NodeJs using socket.io and angular 4 on client side. I am new to socket.io and angular 4.I want to ask what is better approach for this e.g if user want to send a message to specific user or it want to send a message to group of users.
According to my Rnd should I keep the obj of all connected users and that obj contain the socket id of that user with his user name (email or what ever ) so that if some user want to send message to some one we should need his user name and we can access his id through his user name .
Or is there any solution except this ?
And where should i keep that obj of user and socket id global variable or database ?
One-to-one and group chat is very similar. If we use rooms in socket.io https://socket.io/docs/rooms-and-namespaces/#.
In one-to-one only 2 users are in the same room. where as in a group chat more than 2 people can be in the same room.
So when a person sends a mesage, they send it to the room they belong to and want to chat with instead of sending it to individual users. Then, everyone in that room, whether its one other person or multiple people will receive it.
- Node.js
Join a client to a room
io.on('connection', function(client){
client.join(conversation._id)
});
Emitting a message to a room
client.broadcast.to(conversation_id).emit('message:send:response', {
msg: res.msg,
conversation_id: res.data._id
});
- Angular
Listen to emitted messages
getMessages(conversation_id) {
let observable = new Observable(observer => {
this.socket.on('message:send:response', (chat) => {
if (chat.conversation_id === conversation_id) {
observer.next(chat.msg);
}
})
});
return observable;
}
im implementing a chat system where you can send personal messages to a particular person connected to a shocket.
first im putting the username as a key along with the shocket.id to a jason called "connectedUser".
socket.username=loggeduser;
connectedUser[socket.username]=socket.id;
Then im using this code send a personal message
socket.broadcast.to(connectedUser[usersnametobesent]).emit('chat', { message:result});
this works perfectly but whenever i use this it only shows the message on receiver's side but not the clients. i need it to be shown in both sender and receiver's side.
You will need to emit the same thing to the sender.
socket.emit('chat', {});
That function will only send to just that socket.
Why not just use some DOM manipulation to add the chat message to the clients side. This will also add a better user experience for if say there was bad lag for whatever reason, your sender would see the message he sent instantly and not rely on waiting to see his message return from the socket?
Here is a nice little cheat sheet for sockets:
// sending to sender-client only
socket.emit('message', "this is a test");
// sending to all clients, include sender
io.emit('message', "this is a test");
// sending to all clients except sender
socket.broadcast.emit('message', "this is a test");
// sending to all clients in 'game' room(channel) except sender
socket.broadcast.to('game').emit('message', 'nice game');
// sending to all clients in 'game' room(channel), include sender
io.in('game').emit('message', 'cool game');
// sending to sender client, only if they are in 'game' room(channel)
socket.to('game').emit('message', 'enjoy the game');
// sending to all clients in namespace 'myNamespace', include sender
io.of('myNamespace').emit('message', 'gg');
// sending to individual socketid
socket.broadcast.to(socketid).emit('message', 'for your eyes only');
Credit to https://stackoverflow.com/a/10099325
To answer your comment:
In the case of sockets, if you're sending a chat message say from a client so we got client1 and client2
Assuming you have a chat window you probably have some divs and maybe some lists like ul
Client1 sends to Client2 ---> "Hello"
Client1 should immediately see the message "Hello" by using simple Dom stuff like creating a new div / li and appending it to the chat window maybe with some sort of ID to keep track of messages.
Then if the message fails to send you can find that message by id that failed, remove it and maybe append an error message instead that says whatever, message failed to send.
Meanwhile client2 is none the wiser a message had ever been sent
If you use sockets to populate messages for both users then you might run into a case where
Client1 sends to Client2 ----> "Hello"
Now maybe your server has a hiccup or the client lost connection for a second for whatever reason, he doesn't see his message yet and goes oh maybe it didn't send so he goes
Client1 sends to Client2 ----> "Hello"
Client1 sends to Client2 ----> "Hello"
Client1 sends to Client2 ----> "Hello"
Still nothing, he does it 20 more times.
Suddenly the server or whatever unlocks and sends 300 hello messages both clients are spammed.
Sorry for formatting I'm on mobile.
Simply,
This is what you need :
io.to(socket.id).emit("event", data);
whenever a user joined to the server,socket details will be generated including ID.This is the ID really helps to send a message to particular people.
first we need to store all the socket.ids in array,
var people={};
people[name] = socket.id;
here name is the reciever name. Example:
people["ccccc"]=2387423cjhgfwerwer23;
So, now we can get that socket.id with the reciever name whenever we are sending message:
for this we need to know the recievername.You need to emit reciever name to the server.
final thing is:
socket.on('chat message', function(data){
io.to(people[data.reciever]).emit('chat message', data.msg);
});
Hope this works well for you.!!Good Luck