Twilio & NodeJS: can't find and delete Media instances/resources - arrays

I'm using Twilio's NodeJS module & API to send out MMS messages with images attached (from a remote URL), and I want to delete the Media instances that get created on Twilio servers as soon as I send out the messages.
My messages send out correctly, and in the callback, I'm trying to 1) list media instances for the current message, then 2) loop through those instances and delete. The problem is that the mediaList array that comes back from the API for a current message is always empty.
Here's my code:
twilio_client.messages.create({
body: "Thanks for taking a photo. Here it is!",
to: req.query.From,
from: TWILIO_SHORTCODE,
mediaUrl: photo_URL,
statusCallback: STATUS_CALLBACK_URL
}, function(error, message) {
if (!error) {
twilio_client.messages(message.sid).media.list(function(err, data) {
console.log(data);
// The correct object comes back as 'data' here per the API
// but the mediaList array is empty
}
console.log('Message sent via Twilio.');
res.status(200).send('');
} else {
console.log('Could not send message via Twilio: ');
console.log(error);
res.status(500).send('');
}
});

So, it turns out that trying to get the media list at the point I was trying to doesn't work because the media instances didn't exist yet.
I have a separate little app running at the statusCallback (I supply a URL via a constant in the code above, STATUS_CALLBACK_URL), that until now, just checked to see if a message I tried to MMS to a user wasn't handled properly by Twilio, and alerted the user to a problem via SMS. So, I added a check in that same app to see if the message was actually 'sent' to the user, and then checked for and deleted the media instance(s) associated with the message at that point, and it works fine. Here's my code:
// issue message to user if there's a problem with Twilio getting the photo
if (req.body.SmsStatus === 'undelivered' || req.body.SmsStatus === 'failed') {
twilio_client.messages.create({
body: "We're sorry, but we couldn't process your photo. Please try again.",
to: req.body.To,
from: TWILIO_SHORTCODE
}, function(error, message) {
if (!error) {
console.log('Processing error message sent via Twilio.');
res.send(200,'');
} else {
console.log('Could not send processing error message via Twilio: ' + error);
res.send(500);
}
});
}
// delete media instance from Twilio servers
if (req.body.SmsStatus === 'sent') {
twilio_client.messages(req.body.MessageSid).media.list(function(err, data) {
if (data.media_list.length > 0) {
data.media_list.forEach(function(mediaElement) {
twilio_client.media(mediaElement.sid).delete;
console.log("Twilio media instance deleted");
});
}
});
}

Related

salesforce Change Data Capture not sending change event

I am using firebase functions to subscribe to change events for opportunity using specified cometD. my handshake all is working but the change is not received at all. i have made sure that in setup Opportunity object is selected. Any advice on what else to check or debug as why nothing is happening?
export const helloWorld = functions.https.onRequest(async(request, response) => {
functions.logger.info("Hello logs!", {structuredData: true});
const data = {
"url": "https://XX.salesforce.com",
"accessToken": "XXX"
}
await cometd_setup(data)
functions.logger.log("cometd_setup_done")
await cometd.handshake(function (handshake:any) {
if (handshake.successful) {
functions.logger.log("successful opty sending data")
cometd.subscribe('/data/OpportunityChangeEvents', cometd_processdata)
} else {
logger.info('Handshake failed', handshake);
}
})
response.send("Hello from Firebase!");
});
the method that process data is currently simply doing a console log as below
var cometd_processdata = function (server_data:any) {
// Do something more useful with the data
functions.logger.info("got new data:", server_data);
};
The name of the subscription channel for Change Data Capture (CDC) events on standard objects is /data/<Standard_Object_Name>ChangeEvent. For an Opportunity standard object, the CDC channel is /data/OpportunityChangeEvent (no s on the end)

Fetch status 200 but pending endllessly, except first call

I've been searching to solve this problem for a while but couldn't find a working solution.
I'm making a simple social network website and this API returns a article data such as text, image and video url, etc, all saved in server's local MySQL Database. My front-end is React and server is Nginx reverse proxy with Node.js using Express. When I load the page, I create 5 React components that each make fetch request for given article number.
The following code snippet is the fetch API that asks the server to fetch data from database:
//server-side script
app.get('/api/getArticle/:id', (req, res) => {
const con = mysql.createConnection({
host: 'myhost_name',
user: 'myUser',
password: 'myPassword',
database: 'myDB',
});
con.connect(function (err) {
if (err) {
throw err;
}
console.log("Connected!");
})
const idInterest = req.params.id.toString();
console.log(idInterest)
let sql = 'some_sql';
con.query(sql, function (err, result) {
if (err) {
res.status(500).send("Error while getting article data");
return;
}
else {
res.set('Connection', 'close')
res.status(200).send(result);
console.log("ended")
con.end();
return;
}
})
}
//React script
//index.js
fetch('http://mywebsite.com/api/getMaxArticleId/')//Retrieve top 5 article ID
.then((response) => {
for (let i = 0; i < data.length; i++) {
nodesList.push(<Container articleId={data[i]['id']}/>)
}
ReactDOM.render(<React.StrictMode><NavBar />{nodesList}<Writer writer="tempWriter" /></React.StrictMode>, document.getElementById('root'));
})
//Container.jsx; componentDidMount
const url = "http://mywebsite.com/api/getArticle/" + this.props.articleId.toString();
fetch(url, {
method: 'GET',
credentials: "include",
}).then((response) => {
response.json().then((json) => {
console.log(json);
//processing json data
This used to work very fine, but suddenly the getArticle/:id calls started to show 200 status but 'pending' in 'time' column in Chrome network tab, endlessly, all except the first*getArticle/:idcall. This prevents my subsequent .then() in each Container from being called and thus my entire tab is frozen.
Link to image of network tab
As you see from the image, all pending fetches are missing 'Content Download' and stuck in 'Waiting(TTFB)', except the first call, which was '39'
I checked the API is working fine, both on Postman and Chrome, the server sends result from DB query as expected, and first call's Json response is intact. I also see that console.log(response.json()) in React front-end shows Promise{<pending>} with *[[PromiseStatus]]: "Resolved"* and *[[PromiseValue]]* of Array(1) which has expected json data inside.
See Image
This became problematic after I added YouTube upload functionality with Google Cloud Platform API into my server-side script, so that looks little suspicious, but I have no certain clue. I'm also guessing maybe this could be problem of my React code, probably index.js, but I have no idea which specific part got me so wrong.
I've been working on this for a few days, and maybe I need common intelligence to solve this (or I made a silly mistake XD). So, any advices are welcomed :)

How to hide console status error message while fetching in React js?

In my React app, I'm using fetch() to get data from my API, _callAPI() function gets domain parameter and call API if a website of the domain exists in my DB. If it exists, it returns the website's object, otherwise it returns 500. So, I can't figure out if the website exists until I use fetch(). The problem is that every time fetch() doesn't find anything, it throws the following:
container.jsx:25 GET
http://localhost:3000/boutiques/detail/?q=testdomain.com
500 (Internal Server Error)
When it doesn't doesn't find a lot of websites, the console log is packed with that error message. Is there a way to ignore that sort of message while fetching?
fetch()
_callApi = () => {
const { domain } = this.props;
return fetch(`/boutiques/detail/?q=${domain}`)
.then(response => {
if (response.status === 500) {
return 500;
}
return response.json();
})
.then(json => json)
.catch(err => console.log(err));
};
If you want to mute the browser error:
Unfortunately, this cannot be done, as this type of message in the
console is printed by chrome itself. Repressing this type of message
has been debated for years, but the consensus seems to be that this
message is desirable
Credits.
If you want to mute the Unhandled error in the console:
You can always mute the error on front-end, as follows:
.catch(err => { const mute = err })
But it would be better to notify somehow the user about the error and not doing such workarounds.
Also it would better your server to return an error message in the response and on the front-end side you will proceed it.
Looking into your case, it may be better the server to response with status code 400. Here are the HTTP error codes and their purpose:
4xx (Client Error): The request contains bad syntax or cannot be
fulfilled
5xx (Server Error): The server failed to fulfill an
apparently valid request

Make nodejs request image to external site and send back to front end

I am using nodejs with a server.
I need to do a backend request in an url to get an jpg, png... image and send the response to my angular frontend.
I have tried the next but it doesn´t work.
When I do test using Postman. Only text is showing in the screen. No image.
What am I doing wrong?
//node
var request=require('request');
app.get('/foto', function(req, res, next) {
request.get('https://firebasestorage.googleapis.com/v0/b/ortototem.appspot.com/o/Photos%2F51%2FFoto?alt=media&token=XXXXX',
function(err,resp,body){
if(err) {
next(err)
}else{
if(resp.statusCode !== 200 ) {
console.log(resp)
} else res.send(resp)
}
})
Because your endpoint does not have an extension, you will have to set the Content-Type header on your response to match the mime type of the image you are getting. Probably by programmatically detecting it from your google storage response or something. You will also need to be sure you are passing in and rendering binary data with a Buffer type.
For example:
request.get('https://firebasestorage.googleapis.com/v0/b/ortototem.appspot.com/o/Photos%2F51%2FFoto?alt=media&token=YOUR_TOKEN', { encoding: null }, function(err,resp) {
if(err) {
next(err)
} else {
if(resp.statusCode !== 200 ) {
console.log(resp)
} else {
res.contentType(resp.headers['content-type']);
res.end(resp.body, 'binary');
}
}
});
Without this Postman or any Browser won’t know that it’s an image or what type of image it is so it will assume it’s plain text.
The three important items here are:
Specify the encoding: null option on request so body is loaded as a Buffer
Set res.contentType equal to the content-type from Firebase response
Specify binary data in the express response with res.end(resp.body, 'binary')

i have getting "do_not_collapse" as payload in FCM WEB notification

i am doing fcm web notification for the first time andgeting an message as
{ from: "205864560478", collapse_key: "do_not_collapse" }
my code is
messaging.onMessage(function(payload) {
console.log("Message received. ", payload);
// ...
});
and my firebase-messaging-sw.js
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
const notificationTitle = 'Background Message Title';
const notificationOptions = {
body: 'Background Message body.',
icon: '/firebase-logo.png'
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
please help . i dont know why i get this error
i have perfectly working for ios and Android.
my web project is in localhost and do not have https
{ from: "205864560478", collapse_key: "do_not_collapse" } is the expected payload and it is not an error.
Also, for development, localhost is exempted from the https condition.
In FCM, if the user is currently viewing your web page and receives a push notification then it will not be shown as push notification (default behavior).
The behavior of messages differs depending on whether the page is in
the foreground (has focus), or in the background, hidden behind other
tabs, or completely closed.
When your app is in the foreground (the user is currently viewing your
web page), you can receive data and notification payloads directly in
the page.
https://firebase.google.com/docs/cloud-messaging/js/receive
If you still want to show a notification when user is currently viewing your web page then you can add push code logic at messaging.onMessage
Example
messaging.onMessage(function (payload) {
console.log('Message received. ', payload);
var options = {
body: 'Background Message body.', // payload.body
icon: '/firebase-logo.png' . // payload.icon
};
var n = new Notification('Notification says',options);
setTimeout(n.close.bind(n), 5000);
});

Resources