I have a messaging app that works the following way: one of the user sends a list of messages through socket.emit to the server, which then sends the messages to the intended receiver.
First time i tried using multiple emits for multiple messages sent all at once, but only the first as received, so i switched to using a list of messages.
Now, if the user sends a text message it will send a list with one object containing the information. If the user selects and sends one image as an attachment, the list of messages will have a list with an object with the data for an image; but if the user sends multiple images all at once, a list of objects, each containing the data for each image, will be sent, and the client on which the socket.emit(sender, receiver, message_list) is ran is forcefully reconnected.
This is what the code looks like:
const divs = some_node.children; // these are the elements that contain the information
let message_list = [];
let message_object;
for (let i=0; i<divs.length; i++) {
message_object = {};
const input = div.input_field.value;
const source = divs[i].firstElementChild.firstElementChild.src;
const time = `${(new Date()).getHours()}:${(new Date()).getMinutes()}`;
if (input != null && input.trim() != "") {
// display the message on the sender's screen
// ...
message_object = {
message: input,
image: source,
time: time
};
} else {
// display the message on the sender's screen
// ...
message_object = {
message: null,
image: source,
time: time
};
}
// put the images on the sender's screen
// ...
message_list.push(message_object);
}
socket.emit("message-send", sender, receiver, message_list);
Github repository.
Any help would be appreciated, i have no idea why this is happening.
Related
I have data returning from server and based on that data I am showing notifications to users,
What I'm trying to do is to send notification to everyone except sender and for that I need to loop my data users but don't know how to.
Code
Every part is commented for better understanding
// group notif
this.socket.fromEvent('message').subscribe(async (message: any) => {
console.log('group message: ', message); // screenshot below
// loop group users and except sender user, send notification to everyone else.
// (access to group users - tested) `message.msg.message.group.users`
// need to loop here, but how?
// condition to avoid send notification to sender user
// (sender user - tested) `message.msg.message.user.username`
// if (message.msg.message.user.username ............??? ) {
const notifs = LocalNotifications.schedule({
notifications: [
{
title: message.msg.message.user.username,
body: message.msg.message.note,
id: Math.floor(Math.random() * 10),
schedule: { at: new Date(Date.now() + 1000 * 2) },
sound: 'beep.wav',
attachments: null,
actionTypeId: 'OPEN_CHAT',
extra: null
}
]
});
console.log('scheduled notifications', notifs);
// }
});
// group notif
Screenshot
Can anyone help to make this happen please?
Update
To make it clear:
LOGIC
Each user has unique username
user object is sender of notification
Group users are members of the group that notification has been sent to (including sender himself)
The reason to loop group users is to exclude sender (user object) in other to not receive the notification Therefore everyone in group will get notification except sender
Hope it clears it a bit.
You can loop over elements of an array using for-of syntax:
for(const user of users) {
if(user != sender) { ... }
}
So, I'm creating the bot for my Discord channel. I created a special system based on requests. For example, the user sends a request to be added to the chat he wants. Each request is paired with a unique ID. The request is formed and sent to the service channel where the moderator can see those requests. Then, once the request is solved, moderator types something like .resolveRequest <ID> and this request is copied and posted to 'resolved requests' channel.
There is some code I wrote.
Generating request:
if (command === "join-chat") {
const data = fs.readFileSync('./requestID.txt');
let requestID = parseInt(data, 10);
const emb = new Discord.RichEmbed()
.setTitle('New request')
.setDescription('Request to add to chat')
.addField('Who?', `**User ${msg.author.tag}**`)
.addField('Which chat?', `**Chat: ${args[0]}**`)
.setFooter('Request\'s ID: ' + requestID)
.setColor('#fffb3a');
let chan = client.channels.get('567959560900313108');
chan.send(emb);
requestID++;
fs.writeFileSync('./requestID.txt', requestID.toString(10));
}
Now the .resolveRequest <ID>:
if (command === '.resolveRequest') {
msg.channel.fetchMessages({limit : 100}) //getting last 100 messages
.then((messages) => messages.forEach(element => { //for each message get an embed
element.embeds.forEach(element => {
msg.channel.send(element.fields.find('value', args[0].toString(10))); //send a message containing the ID mentioned in 'args[0]' that was taken form the message
})
}));
}
.join-chat <chat_name> works flawlessly, but .resolveRequest <ID> does't work at all, even no errors.
Any way to fix it?
Using .find('value', 'key') is deprecated, use .find(thing => thing.value == 'key') instead.
Also you should use a DataBase to store things, but your Code actually is not broken, its just that you check for: command === '.resolveRequest', wich means you need to run ..resolveRequest, as in the command variable the prefix gets cut away so change that to: command === 'resolveRequest'
Building a Twitter bot to:
search for tweets with keywords like "Net Neutrality"
Return the tweet IDs and usernames for those tweets
Publish a tweet in response to that user (via in_reply_to_status_id, as described in Twitter Docs)
Here is my current code:
const Twitter = new twit(config);
let tweet = function() {
let params = {
q: '#netneutrality, #savethenet, Net Neutrality',
result_type: 'mixed',
lang: 'en'
}
// search through all tweets using our params and execute a function:
Twitter.get('search/tweets', params, function(err, data) {
// if there is no error
if (!err) {
// loop through the first 4 returned tweets
for (let i = 0; i < 4; i++) {
// iterate through those first four defining a rtId that is equal to the value of each of those tweets' ids
let rtId = data.statuses[i].id_str;
let username = data.statuses[i].username;
// the post action
Twitter.post('statuses/update', {
// setting the id equal to the rtId variable
in_reply_to_status_id: rtId
, status: `#${username} Send single-click #SaveTheNet tweets to key politicians at fliplist.app. Take 60 seconds to protect our Internet, once and for all.`
// log response and log error
}, function(err, response) {
if (response) {
console.log('Successfully tweeted');
}
if (err) {
console.log(err);
}
});
}
}
else {
// catch all log if the search could not be executed
console.log('Could not search tweets.');
}
});
}
tweet();
setInterval(tweet, 600000);
When I ran it, there was a successful output ("Succesfully tweeted" 4 times in terminal), and there were indeed 4 new tweets published from my account.
However, the username in all of those tweets was #undefined.
So I imagine I'm either failing to collect those usernames from the relevant tweets or failing to add them to the status string appropriately.
Any suggestions for how I can fix this?
For reference, here is a link to one of the #undefined tweets: https://twitter.com/ProoveTweets/status/1075855455958765569
And a screenshot is attached here
Two things to note. Firstly, Twitter's usernames are called "Screen Names". So you code should probably read:
let username = data.statuses[i].user.screen_name;
Take a look at the search documentation for an example of the JSON being returned. https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets.html
Secondly - please don't do this! Automatically replying to keywords is against the developer terms of service and is really annoying to users.
https://help.twitter.com/en/rules-and-policies/twitter-automation
I've implemented a call center in Salesforce with Twilio client JavaScript SDK. I'm trying to save the call record information in Salesforce and I'm using the connection.parameters.CallSid to identify the correct record when the recording call back fires. However my CallSid in client side is getting changed automatically sometimes to a different format and hence the recording call back function can't find the Salesforce end record to update it with the RecordingUrl. Have anyone experienced this before or appreciate any guidance.
Below is my JavaScript code. To be more specific, in the startCall function console.log print the CallSid correctly but when goes to saveLog function it's having a different value with a different format and hence the saved record having an incorrect value.
<script type="text/javascript">
Twilio.Device.setup("{! token }");
var callerSid; // hold the Twilio generated CallSid unique to this call
var parentId; // hold the parent record being called in order to associate as the parent of task being logged for the call
var newTaskId; // hold the id of newly created task
// function to fire when click 2 dial executes
var startCall = function (payload) {
sforce.opencti.setSoftphonePanelVisibility({visible: true}); //pop up CTI softphone
parentId = payload.recordId; // the record that the phone number being called belongs to
var cleanednumber = cleanFormatting(payload.number);
params = {"PhoneNumber": cleanednumber};
var connection = Twilio.Device.connect(params);
callerSid = connection.parameters; // track the unique Twilio CallSid
console.log('clk2dial : ', callerSid.CallSid); **// here it logs correcly as CAc57d05994cd69498e0353a5f4b07f2dc**
setTimeout(function(){
saveLog(); // save the call information in a Task record
}, 2000
);
};
//OpenCTI!!
sforce.opencti.enableClickToDial();
sforce.opencti.onClickToDial({listener : startCall}); // click 2 dial
function cleanFormatting(number) {
//changes a SFDC formatted US number, which would be 415-555-1212 into a twilio understanble number 4155551212
return number.replace(' ','').replace('-','').replace('(','').replace(')','').replace('+','');
}
// save the call information in a Task record
function saveLog() {
var keyPrefix;
var taskToSave;
console.log('callerSid.CallSid : ', callerSid.CallSid); **// surprisingly here it logs as TJSce253eb4-c2a0-47f3-957f-8178e95162aa**
if(parentId != null) {
keyPrefix = parentId.slice(0,3);
}
if(keyPrefix != null && keyPrefix == '003') {
taskToSave = {WhoId:parentId, Type: "Call", CallObject: callerSid.CallSid, entityApiName: "Task", Subject: "Call log"};
} else {
taskToSave = {WhatId:parentId, Type: "Call", CallObject: callerSid.CallSid, entityApiName: "Task", Subject: "Call log"};
}
sforce.opencti.saveLog({value:taskToSave, callback: saveLogCallBack});
}
// call back function for saving the call information in a Task record
var saveLogCallBack = function(response) {
if(response.success) {
newTaskId = response.returnValue.recordId;
console.log('save success! : ', newTaskId);
} else {
console.error('Error saving : ', response.errors);
}
}
</script>
Answering my own question as I got through this. I registered a function for Twilio.Device.connect and in the call back function retrieved the CallSid. Along with that I've updated my click 2 dial function as well accordigly as below. However I was unable to find this approach in Twilio documentation and any comments are welcome.
// function to fire when click 2 dial executes
var startCall = function (payload) {
sforce.opencti.setSoftphonePanelVisibility({visible: true}); //pop up CTI softphone
parentId = payload.recordId; // the record that the phone number being called belongs to
var cleanednumber = cleanFormatting(payload.number);
params = {"PhoneNumber": cleanednumber};
Twilio.Device.connect(params);
};
//OpenCTI!!
sforce.opencti.enableClickToDial();
sforce.opencti.onClickToDial({listener : startCall}); // click 2 dial
// registered a function for Twilio Device connect
Twilio.Device.connect(function(response) {
callSid = response.parameters; // track the unique Twilio CallSid
// nothing change in save function so not posting again
saveLog(); // save the call information in a Task record
});
Here is my code:
Titanium.Network.registerForPushNotifications({
types: [
Titanium.Network.NOTIFICATION_TYPE_BADGE,
Titanium.Network.NOTIFICATION_TYPE_ALERT
],
success:function(e)
{
var deviceToken = e.deviceToken;
Ti.API.info("Push notification device token is: "+deviceToken);
alert('device token is' +e.deviceToken);
Ti.API.info("Push notification types: "+Titanium.Network.remoteNotificationTypes);
Ti.API.info("Push notification enabled: "+Titanium.Network.remoteNotificationsEnabled);
},
error:function(e)
{
Ti.API.info("Error during registration: "+e.error);
},
callback:function(e)
{
// called when a push notification is received.
//Titanium.Media.vibrate();
var data = JSON.parse(e.data);
var badge = data.badge;
if(badge > 0){
Titanium.UI.iPhone.appBadge = badge;
}
var message = data.message;
if(message != ''){
var my_alert = Ti.UI.createAlertDialog({title:'', message:message});
my_alert.show();
}
}
});
}
The callback function:
callback:function(e)
{
// called when a push notification is received.
//Titanium.Media.vibrate();
var data = JSON.parse(e.data);
var badge = data.badge;
if(badge > 0){
Titanium.UI.iPhone.appBadge = badge;
}
var message = data.message;
if(message != ''){
var my_alert = Ti.UI.createAlertDialog({title:'', message:message});
my_alert.show();
}
}
});
is fired when the push notification is recieved when the app is running in the foreground.
Question , if I have 2 files:
app.js -> newwindow.js
and say that I am in newwindow.js , will I still receive push notifications? (if the code above is all pasted in app.js?)
2) When I recieve a push notification when the app is running in the background, how can I write a callback method for it, so I can tell the app what to do with that notification
3) What is the best way of handling different notifications, i.e. say I need to open different windows, when its in background mode?
notification 1 - > win1.js
notification 2 - > win2.js
notification 3 - > win3.js
First of all you should Implement it in your app(It seems you just copied from docs) and see how actually push notification appear it will make every thing a lot clear.
The callback you have written above will fetch the message that you have send using the Push notification.
As for part 2 of your question : Once the user clicks on the push received your app will come into foreground and the callback will be automatically called.
And to handle different notifications, there are never different push notifications, there is always a single push notification.you have to parse the data and have act according to the condition. you can modify your push message and open window according to it.