I'm trying to use Nodemailer for this, but I can't use an attachment in the input, or I don't know how
https://nodemailer.com/message/attachments/
please help, anything is helpful for me
postuler.js
let details = {
name: name.value,
prenom: prenom.value,
email: email.value,
telephone: telephone.value,
cv: cv.file,
profil: profil.value,
motivation: motivation.value
};
let response = await fetch("http://localhost:5000/postuler", {
method: "POST",
headers: {
"Content-Type": "application/json;charset=utf-8",
},
body: JSON.stringify(details),
});
server.js
router.post("/postuler", (req, res) => {
const name = req.body.name;
const prenom = req.body.prenom
const email = req.body.email;
const telephone = req.body.telephone;
const cv = req.files;
const profil = req.body.profil;
const motivation = req.body.motivation;
const mail = {
from: email,
to: "*************#gmail.com",
subject: `Contact Form ${name} ${prenom}`,
html: `<p>Name et Prenom: ${name} ${prenom}</p>
<p>Email: ${email}</p>
<p>Telephone: ${telephone}</p>
<p>Linkedin: ${profil}</p>
<p>Motivation: ${motivation}</p>
`,
attachments: [
{ // use URL as an attachment
filename: cv.originalname,
contentType: 'application/pdf',
path: cv.path
},
]
};
You tring to send req.file.path as an attachment.
Nodemailer get files as zip , csv,pdf and ect...
Req.file.path it's tricky because the nodemailer don't no where the path is .
Try to zip or save your files in to one file in some folder (you can use fs or js-zip modules) and than give the path of the file as an path in the attachment object.
Related
Thanks in advance for taking a look. I am working on being able to download a zip file from react through a django api request. I am able to click on my pop up that downloads the zip file, but when I double click on the zip file to open, I get this error: "Unable to expand file_name.zip. It is an unsupported format" My response with the zip file seems to be passing correctly to the front end, so I am thinking it may be something wrong with the react code when making the "blob"? Thanks again.
Django code:
class DownloadZip(APIView):
def post(self, request, format=None):
# information to find file to create zip
profile_name = request.data["profile"]
profile_year = request.data["year"]
# file path to create zips from
path = str(Path(__file__).parent.resolve())
zip_dir = shutil.make_archive(profile_name + profile_year, "zip", path + "/" + profile_name + profile_year)
s = io.StringIO(zip_dir)
response = HttpResponse(s, content_type = "application/zip")
zip_name = profile_name + profile_year + ".zip"
response["Content-Disposition"] = f"attachment; filename={zip_name}"
return response
React code:
downloadZip = async () => {
const params = {
profile: this.state.profileName,
year: this.state.year,
};
axios({
url: `${serverUrl}/download_zip`,
method: "post",
data: params
}).then(
(res) => {
const url = window.URL.createObjectURL(new Blob([res.data],{type:'application/zip'}));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.zip');
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
},
(error) => {
console.log(error);
});
}
I did do a fellow commentor's suggestion, and updated to get route with query params, but am having the same issue. I can double click on the zip link on the web browser but a pop up appears "Unable to expand filename.zip. It is an unsupported format"
Please try adding {responseType: 'arraybuffer'}. I also had the same problem but after adding this {responseType: 'arraybuffer'}. I am getting correct file.
downloadZip = async () => {
const params = {
profile: this.state.profileName,
year: this.state.year,
};
axios.post(
`${serverUrl}/download_zip`,
params,
{
responseType: 'arraybuffer'
}
).then(
(res) => {
const url = window.URL.createObjectURL(new Blob([res.data],{type:'application/zip'}));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.zip');
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
},
(error) => {
console.log(error);
});
}
I'm serving pdf file with nodejs/koa2
ctx.body = readableStream;
ctx.attachment('file.pdf');
The file successfully arrives and on the client side i receive it with ReactJS application:
const document = useSelector(selectors.getFile(documentFile.key));
if (document) {
window.open(window.URL.createObjectURL(new Blob([document], { type: "application/octet-stream" })), "_self");
}
...
const openFile = useCallback((key) => {
dispatch(actions.getFile.request(key))
}, [dispatch]);
It successfully downloads the file, but completely ignores response header Content-Disposition: attachment; filename="file.pdf" and downloads it under the name like d3aa7870-bd35-4645-a926-294392343cfc which is taken from the BLOB url: Request URL: blob:http://localhost:3000/d3aa7870-bd35-4645-a926-294392343cfc.
Could you please advise how to correctly save it under the name of file.pdf on the client side?
just create an element and set download attribute with file name
const document = useSelector(selectors.getFile(documentFile.key));
if (document) {
const url =window.URL.createObjectURL(new Blob([document], { type: "application/octet-stream" }))
const a = document.createElement("a");
a.style = "display: none";
document.body.appendChild(a);
a.href = url;
a.download = "fileName";
a.click();
window.URL.revokeObjectURL(url);
}
I am able to use sObject to put an Attachment onto one of my records. The problem is that SF is not recognizing the file as a PDF but as a generic file.
const base64data = await new Buffer.from(pdfBuffer).toString('base64');
try {
await conn.sobject('Attachment').create({
ParentId: filename,
Name: resumeFileName,
Body: base64data,
ContentType: fileType,
Description: 'Resume Attachment',
});
} catch (e) {
console.log('Attachment Error', e);
}
When I look at the attachments of my record, the file does not have all of the options that a PDF file has (only download and delete)
Thanks in advance!
Turns out in order for Salesforce to recognize the pdf correctly you need to have the content type set to application/pdf AND the name of the file must include the .pdf extension. This worked for me:
(async () => {
const jsforce = require('jsforce');
const fs = require('fs');
var conn = new jsforce.Connection({
instanceUrl : '...',
accessToken : '...'
});
const pdfData = fs.readFileSync('./test.pdf').toString('base64');
try {
await conn.sobject('Attachment').create({
ParentId: '0012300000RWedX',
Name: 'My Test PDF.pdf', // <= Turns out the name has to have .pdf
Body: pdfData,
ContentType: 'application/pdf',
Description: 'Testing PDF Attachment',
});
} catch(err) {
console.error(err);
}
})();
First, when the docs at https://aws-amplify.github.io/docs/js/api#complex-objects say:
input CreateTodoInput {
id: ID
name: String!
description: String
file: S3ObjectInput # This input type will be generated for you
}
I get an error Type "S3ObjectInput" not found in document. and I have to add S3ObjectInput manually.
This is my schema (the docs are not very clear on it so I put it together from similar questions)
type Picture #model {
id: ID!
file: S3Object!
url: String!
rating: Int
appearedForRanking: Int
}
type S3Object {
bucket: String!
key: String!
region: String!
}
input CreatePictureInput {
id: ID
file: S3ObjectInput!
url: String!
rating: Int
appearedForRanking: Int
}
input S3ObjectInput {
bucket: String!
region: String!
localUri: String
visibility: Visibility
key: String
mimeType: String
}
enum Visibility {
public
protected
private
}
And this is the client code (with React)
class PictureUpload extends Component {
state = { fileUrl: '', file: '', filename: '' }
handleChange = e => {
let file = e.target.files[0]
let filext = file.name.split('.').pop()
let filename = uuid() + '.' + filext
this.setState({
fileUrl: URL.createObjectURL(file),
filename: filename
})
}
saveFile = async () => {
let visibility = 'public'
let fileObj = {
bucket: awsConfig.aws_user_files_s3_bucket,
region: awsConfig.aws_user_files_s3_bucket_region,
key: visibility + '/' + this.state.filename,
mimeType:'image/jpeg',
localUri: this.state.fileUrl,
visibility: visibility
}
try {
const picture = await API.graphql(
graphqlOperation(mutations.createPicture, {
input: {
url: this.state.filename,
file: fileObj
}
})
)
The problem is that the mutation runs without errors, setting the DB records, but the file does not appear in S3. The docs say the SDK uploads the file to Amazon S3 for you. so I don't think I forgot to add something.
Any idea why the upload doesn't happen?
Automatic upload of file to S3 happens only if using the aws-appsync package, with aws-amplify you need to upload the file yourself using Storage.put(...).
This GitHub issue explain the differences in more detail
For ReactNative I've found that you can't simply provide a uri, but rather a blob. Try this code instead:
const response = await fetch(uri);
const blob = await response.blob();
let file = {
bucket,
key,
region,
localUri: blob,
mimeType,
};
This should get the image data to S3 as long as your authentication is properly configured.
My task is pretty simple, all i have to do is to create records in the lead section of the salesforce. I have created a free account and i am not able to figure it out that, what is https://yourinstance.saleforce.com in the below rest api:
https://yourinstance.salesforce.com/services/data/v39.0/sobjects/Lead
Body JSON:
{
"body": {
"Salutation": "Mr.",
"FirstName": "H",
"LastName": "Sam",
"Company": "Samosto"
}
}
Header:
Authorization: Bearer 00D0o0000015jPn!ARgAQPiIGhuYGUG_c0HDKNR0hxTX9zS82Fv1lIuqn4rapFJHPR422gLyi10rF8Auukb._hj9pj532DP7IajQV36lyKpUNEXdxvL
Content-Type: application/json
Sforce-Auto-Assign: TRUE
Any help will be highly appreciated!
This is the URL you have for the organization you want to login to. Since most of the orgs are using their own Domain names in guides or examples you will see this "https://yourinstance.saleforce.com" being used.
You can simply take it from the URL while logged in Salesforce or go to Setup -> quick search "My Domain" and you will see the domain name.
It is a good thing to check it from here as the generic URL can also be blocked as a login option.
fwiw i think the API has changed to Account. This is working for me
// to run:
// node create_new_account.js --config ./config_na150_scan_email_app.json
//
// links:
// https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_create.htm
const axios = require("axios");
const qs = require("qs");
const yargs = require("yargs");
const argv = yargs
.command('create_account', 'test creating salesforce leads', {
config: {
description: 'config',
alias: 'c',
type: 'string',
}
})
.help()
.alias('help', 'h')
.argv;
let { salesforce, scanResultsURL } = require(argv.config);
const auth_data = qs.stringify({"username": salesforce.username,
"password": salesforce.password + salesforce.security_token,
"grant_type": "password",
"client_id": salesforce.consumer_key,
"client_secret": salesforce.customer_secret,
"redirect_uri": salesforce.redirect_uri});
console.log("auth data", auth_data)
const auth_config = {
method: "post",
url: salesforce.oauth2_uri,
data: auth_data,
headers: {"Content-Type": "application/x-www-form-urlencoded"}
}
const action_url = "https://na<TBD>.salesforce.com/services/data/v51.0/sobjects/Account"
console.log('action url', action_url)
data = {
"Name" : "test Salesforce account API"
}
async function createAccout() {
// "get" token
axios(auth_config).then(function (response) {
auth_header = {"Authorization": "Bearer " + response["data"]["access_token"]}
action_config = {
method: "post",
url: action_url,
headers: auth_header,
data: data
}
// use valid token to send email
axios(action_config).then(function (response) {
console.log("action response", response["data"]); // TODO rm
}).catch(function (error) {
console.log("authenticated passed, action failed")
console.log("action error", error); // TODO something
})
}).catch(function (error) {
console.log("action token error", error); // TODO something
})
}