Quickblox Message Attachments - quickblox

In reference to this question: quickblox web how to upload profile picture
I would like to attach the uploaded file to a new message.
QB.content.createAndUpload({file: profile_picture, public: true}, function(error, response) {
if (error) {
console.log("upload didn't work");
} else {
var blob_id = response.id;
// Example HERE //
var attachment = {
id: response.id.toString(),
name: response.name,
type: "photo",
url: response.path,
name: response.name,
'content-type': response.content_type
};
QB.chat.message.create({
attachments: [attachment]
},...)
}
});
The message is created (see photo below) but the name and content-type values are not saved into quickblox. The photo below shows a file attached using Q-municate app, the second content is from the code referenced above. Can you let me know the correct was to add an attachment to a chat message. Thanks
http://imgur.com/9QKNtXh

The right way is to log response and check response.name and response.content_type - they can be null by some reason
In that case you can manually set them or so:
var attachment = {
id: response.id.toString(),
name: response.name,
type: "photo",
url: response.path,
name: "my image",
'content-type': "image/jpeg",
};

Related

How to upload multiple files using RNFetchBlob.fetch and react-native-document-picker

I am using react-native-document-picker and rn-fetch-blob to upload the file. It's working as expected for a single file. But I couldn't able to upload multiple files to the server.
Upload function
const uploadPic=()=>{
// alert('ddf');
RNFetchBlob.fetch('POST', 'http://localhost/test.upload.php', {
Authorization : "Bearer access-token",
otherHeader : "foo",
'Content-Type' : 'multipart/form-data',
}, [
// element with property `filename` will be transformed into `file` in form data
{name : 'image', filename : singleFile.name, type: singleFile.type, data: RNFetchBlob.wrap(singleFile.uri)}
]).then((resp) => {
console.log(resp);
alert('your image uploaded successfully');
})
}
It's working fine to upload the single file but I need to upload multiple docs.
Select Function
let selectFile = async () => {
//Opening Document Picker to select one file
try {
const res = await DocumentPicker.pick({
//Provide which type of file you want user to pick
type: [DocumentPicker.types.allFiles],
//There can me more options as well
// DocumentPicker.types.allFiles
// DocumentPicker.types.images
// DocumentPicker.types.plainText
// DocumentPicker.types.audio
// DocumentPicker.types.pdf
});
//Printing the log related to the file
console.log('res : ' + JSON.stringify(res));
//Setting the state to show single file attributes
setSingleFile(res);
} catch (err) {
setSingleFile(null);
//Handling any exception (If any)
if (DocumentPicker.isCancel(err)) {
//If user canceled the document selection
alert('Canceled from single doc picker');
} else {
//For Unknown Error
alert('Unknown Error: ' + JSON.stringify(err));
throw err;
}
}
};
I changed this line from const res = await DocumentPicker.pick({ to const res = await DocumentPicker.pickMultiple({
In the console, the array of all the files are posted.
Now I need to upload all the files to the server, Looking for a solution to loop all the data in RNFetchBlob.fetch.
I have added the loop in the function as below
const uploadPic=()=>{
// alert('ddf');
RNFetchBlob.fetch('POST', 'http://localhost/test.upload.php', {
Authorization : "Bearer access-token",
otherHeader : "foo",
'Content-Type' : 'multipart/form-data',
}, [ singleFile.map((item, key) => (
{name : 'image[]', filename : item.name, type: item.type, data: RNFetchBlob.wrap(item.uri)}
))
// element with property `filename` will be transformed into `file` in form data
]).then((resp) => {
console.log(resp);
alert('Document uploaded successfully');
})
}
In the console the error which i am getting now
RNFetchBlob failed to create request multipart body :com.facebook.react.bridge.ReadableNativeArray cannot be cast to com.facebook.react.bridge.ReadableNativeMap
[Tue Jun 23 2020 05:36:26.918] WARN Attempt to invoke virtual method 'int java.io.InputStream.read(byte[], int, int)' on a null object reference
[Tue Jun 23 2020 05:36:27.363] LOG {"array": [Function anonymous], "base64": [Function anonymous], "blob": [Function anonymous], "data": "{\"Message\":\"sorry\",\"Status\":\"Error\"}",
Came ages after, but maybe helps someone else. Faced the same issue, and I could make it work wrapping the array of files in a for loop before sending it to RNFetchBlob.fetch. I was using react-native-document-picker to get the files.
const [multipleFiles, setMultipleFiles] = useState([]);
let data = []
for(let i = 0; i < multipleFiles.length; i++){
data.push(
{ name : 'submit', data: 'ok' },
{ name : 'files', filename : multipleFiles[i].name, data: RNFetchBlob.wrap(multipleFiles[i].uri) },
)
}
Then on the request ...
RNFetchBlob.fetch('post', 'http://myendpoint.com/api/example' , {
Authorization : "Bearer access-token",
'Content-Type' : 'multipart/form-data',
}, data).then((res) => {
console.log(res)
})
Hope it helps, it did for me! ;D

React Native upload image to server failed in android

i am using the following code to but i keep getting in android, which was showing "Network request failed", but it was no problem if i not append photo file data in the FormData. Why I am getting this problem?
const data = new FormData();
data.append("name", "testName"); // you can append anyone.
data.append("photo", {
uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==',
type: 'image/png', // or photo.type
name: 'testPhotoName.png'
});
fetch('https://ptsv2.com/t/1gfl7-1544694996/post', {
method: "post",
body: data
}).then(res => {
console.log(res);
});

Sending Templated emails with node.js, node mailer and nodemailer-mailgun-transport

I have the following basic nodejs app:
var nodemailer = require('nodemailer');
var hbs = require('nodemailer-express-handlebars');
var options = {
viewEngine: {
extname: '.hbs',
layoutsDir: 'views/email/',
defaultLayout : 'template',
partialsDir : 'views/partials/'
},
viewPath: 'views/email/',
extName: '.hbs'
};
var mg = require('nodemailer-mailgun-transport');
var auth = {
auth: {
api_key: ' mailgun api key ',
domain: ' mailgun email domain '
}
}
var mailer = nodemailer.createTransport(mg(auth));
mailer.use('compile', hbs(options));
mailer.sendMail({
from: 'test#inventori.io',
to: 'test#test.com',
subject: 'Any Subject',
template: 'email.body',
context: {
variable1 : 'value1',
variable2 : 'value2'
}
}, function (error, response) {
// console.error(error);
if (error) {
throw error;
};
console.log('mail sent to ',response);
mailer.close();
});
views/email/template.hbs
{{>email/head}}
<body>
{{>email/header}}
{{{body}}}
{{>email/footer}}
</body>
</html>
views/email/email.body.hbs
<h4>Main Body Here</h4>
{{variable1}} <br/>
{{variable2}}
views/partials/email/header.hbs
<h4>Header Content</h4>
views/partials/email/footer.hbs
<h4>Footer Content</h4>
The handlebars template engine gives zero errors but the mailgun transport throws the following error:
Error: Sorry: template parameter is not supported yet. Check back soon!
at IncomingMessage.<anonymous> (~/test/node_modules/nodemailer-mailgun-transport/node_modules/mailgun-js/lib/request.js:228:15)
at IncomingMessage.emit (events.js:129:20)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)
This example uses the gmail node mailer transport:
http://excellencenodejsblog.com/express-nodemailer-sending-mails/
I would like to be able to send templated emails using mailgun.
Any help would be greatly appreciated.
Thank you.
Change your template parameter to html.
If you look at the source code here, the error correct- there is no such thing as a template parameter.
For me, templates weren't rendering properly because I was following an example using extName when the key was actually extname (all lowercase). Perhaps it was renamed overtime and the guide I was looking at is now somewhat out of date.
Full working example below as of 30 May 2020.
Directory Structure:
root/
src/
email-templates/
layouts/
blank.hbs
partials/
hello.hbs
services/
email.service.ts
email.service.ts (Haven't updated this to use proper types yet. Just a poc.)
export async function sendTestEmail() {
try {
// Generate test SMTP service account from ethereal.email
// Only needed if you don't have a real mail account for testing
const testAccount = await nodemailer.createTestAccount()
// create reusable transporter object using the default SMTP transport
const transporter = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: testAccount.user, // generated ethereal user
pass: testAccount.pass, // generated ethereal password
},
})
transporter.use('compile', hbs({
viewEngine: {
extname: '.hbs', // handlebars extension
partialsDir: 'src/email-templates',
layoutsDir: 'src/email-templates/layouts',
defaultLayout: 'blank',
},
viewPath: 'src/email-templates',
extName: '.hbs'
}))
// send mail with defined transport object
const mailOptions = {
from: 'test#gmail.com', // sender address
to: 'test#gmail.com', // list of receivers
subject: 'Hello ✔', // Subject line
text: 'Hello world?', // plain text body
template: 'hello',
context: {
firstName: 'Clem'
}
}
const info = await transporter.sendMail(mailOptions)
console.log('Message sent: %s', info.messageId)
// Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321#example.com>
// Preview only available when sending through an Ethereal account
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info))
// Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
} catch (error) {
console.log(error)
}
}

How to Upload images from FileReader to Amazon s3, using meteor

Im trying to build an image uploader with meteor to Amazon S3. Thanks to Hubert OG, Ive found AWS-SDK which makes things easy.
My problem is that the data uploaded seems to be corrupt. When I download the file it says, the file may be corrupt. Probably it is.
Inserting the data into an image src, does work, and the preview of the image shows up as it supposed to, so the original file, and probably the data is correct.
I'm loading the file with FileReader, and than pass the result data to AWS-SDK putObject method.
var file=template.find('[type=file]').files[0];
var key="uploads/"+file.name;
var reader=new FileReader();
reader.onload=function(event){
var data=event.target.result;
template.find('img').src=data;
Meteor.call("upload_to_s3",file,"uploads",reader.result);
};
reader.readAsDataURL(file);
and this is the method on the server:
"upload_to_s3":function(file,folder,data){
s3 = new AWS.S3({endpoint:ep});
s3.putObject(
{
Bucket: "myportfoliositebucket",
ACL:'public-read',
Key: folder+"/"+file.name,
ContentType: file.type,
Body:data
},
function(err, data) {
if(err){
console.log('upload error:',err);
}else{
console.log('upload was succesfull',data);
}
}
);
}
I wrapped an npm module as a smart package found here: https://atmosphere.meteor.com/package/s3policies
With it you can make a Meteor Method that returns a write policy, and with that policy you can upload to S3 using an ajax call.
Example:
Meteor.call('s3Upload', name, function (error, policy) {
if(error)
onFinished({error: error});
var formData = new FormData();
formData.append("AWSAccessKeyId", policy.s3Key);
formData.append("policy", policy.s3PolicyBase64);
formData.append("signature", policy.s3Signature);
formData.append("key", policy.key);
formData.append("Content-Type", policy.mimeType);
formData.append("acl", "private");
formData.append("file", file);
$.ajax({
url: 'https://s3.amazonaws.com/' + policy.bucket + '/',
type: 'POST',
xhr: function() { // custom xhr
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // check if upload property exists
myXhr.upload.addEventListener('progress',
function (e){
if(e.lengthComputable)
onProgressUpdate(e.loaded / e.total * 100);
}, false); // for handling the progress of the upload
}
return myXhr;
},
success: function () {
// file finished uploading
},
error: function () { onFinished({error: arguments[1]}); },
processData: false,
contentType: false,
// Form data
data: formData,
cache: false,
xhrFields: { withCredentials: true },
dataType: 'xml'
});
});
EDIT:
The "file" variable in the line: formData.append("file", file); is from a line similar to this: var file = document.getElementById('fileUpload').files[0];
The server side code looks like this:
Meteor.methods({
s3Upload: function (name) {
var myS3 = new s3Policies('my key', 'my secret key');
var location = Meteor.userId() + '/' + moment().format('MMM DD YYYY').replace(/\s+/g, '_') + '/' + name;
if(Meteor.userId()) {
var bucket = 'my bucket';
var policy = myS3.writePolicy(location, bucket, 10, 4096);
policy.key = location;
policy.bucket = bucket;
policy.mimeType = mime.lookup(name);
return policy;
}
}
});
The body should be converted to buffer – see the documentation.
So instead of Body: data you should have Body: new Buffer(data, 'binary').

How to use api attribute on proxy

I would like to know how to use the api attribute of a proxy in ST2
For now, I have this in my proxy configuration:
api: {
create : App.urls.create_object,
read : App.urls.load_object,
update : App.urls.update_object,
destroy : App.urls.destroy_object
}
But then, I don't know how to use it.
For instance, when I wanted to create a new object, I created an Ext.Ajax.request with these parameters :
url: App.urls.create_object,
params: {
'object': object
},
But now, how could I do the same with the api attribute ?
Could you help ?
Assuming you have a model like this:
Ext.define('User', {
fields: ['name', 'email'],
proxy: {
type: 'ajax',
api: {
create: 'my_create_url',
read: 'my_read_url',
update: 'my_update_url',
destroy: 'my_destroy_url'
}
}
});
create
var user = Ext.create('User', {name: 'Ed Spencer', email: 'ed#sencha.com'});
user.save(); // will POST to the create url
update
var user = Ext.create('User', {name: 'Ed Spencer', email: 'ed#sencha.com'});
user.save({
success: function(user) {
user.set('name', 'Robert Dougan');
user.save(); // will PUT update URL
}
});
read
Using a store:
var store = Ext.create('Ext.data.Store', {
model: 'User'
});
store.load(); // will GET to read URL
Using the model:
// will GET the read URL with the specified ID.
User.load(12, {
success: function(user) {
console.log(user);
}
});
destroy
var user = Ext.create('User', {name: 'Ed Spencer', email: 'ed#sencha.com'});
user.save({
success: function(user) {
user.destroy(); // will DELETE destroy URL
}
});
There is more information about this on the Rest proxy in the Sencha Docs: http://docs.sencha.com/touch/2-0/#!/api/Ext.data.proxy.Rest
sync
You can also use the store sync method to batch create/update/destroy all the records in your store.
var store = Ext.create('Ext.data.Store', {
model: 'User'
});
store.add({ name: 'Robert Dougan', email: 'rob#sencha.com' });
store.sync(); // will batch update all the needed records