如何使用node.js中的mailgun服务从firebase存储发送附加文件并将其发送到电子邮件
是否可以从firebase存储中附加文件?? 我尝试了下面的代码,但不起作用如何使用node.js中的mailgun服务从firebase存储发送附加文件并将其发送到电子邮件,node.js,firebase,google-cloud-storage,firebase-storage,mailgun,Node.js,Firebase,Google Cloud Storage,Firebase Storage,Mailgun,是否可以从firebase存储中附加文件?? 我尝试了下面的代码,但不起作用 var mailgun = require("mailgun-js"); var api_key = 'key-acf9f881e32c85b3c0dad34358507a95'; var DOMAIN = 'sandbox76c6f74ddab14862816390c16f37a272.mailgun.org'; var mailgun = require('mailgun-js')({apiKey: api_key
var mailgun = require("mailgun-js");
var api_key = 'key-acf9f881e32c85b3c0dad34358507a95';
var DOMAIN = 'sandbox76c6f74ddab14862816390c16f37a272.mailgun.org';
var mailgun = require('mailgun-js')({apiKey: api_key, domain: DOMAIN});
var path = require("path");
var filepath = path.join(`gs://i-m-here-c01f6.appspot.com/Groups/${leaderId}`, 'group_image.jpg');
var data = {
from: 'Excited User <postmaster@sandbox76c6f74ddab14862816390c16f37a272.mailgun.org>',
to: 'rayteamstudio@gmail.com',
subject: 'Complex',
text: 'Group Creation Request',
html: `<p>A user named: ${fromName} wants to create a group.<br />
User ID: ${leaderId}<br />
Group Name: ${groupName}<br />
Group Description: ${groupDescription}<br /><br />
To Accept the request click here:<br />
https://us-central1-i-m-here-c01f6.cloudfunctions.net/acceptOrDenyGroupCreation?leaderID=${leaderId}&requestStatus=approved <br /><br />
To Deny the request click here:<br />
https://us-central1-i-m-here-c01f6.cloudfunctions.net/acceptOrDenyGroupCreation?leaderID=${leaderId}&requestStatus=denied /></p>`,
attachment: filepath
};
mailgun.messages().send(data, function (error, body) {
if(error)
console.log('email err: ',error);
});
var mailgun=require(“mailgun js”);
变量api_key='key-ACF9F881E32C85B3C0DAD3358507A95';
变量域='sandbox76c6f74ddab14862816390c16f37a272.mailgun.org';
var mailgun=require('mailgun-js')({apiKey:api_-key,domain:domain});
var路径=要求(“路径”);
var filepath=path.join(`gs://i-m-here-c01f6.appspot.com/Groups/${leaderId}`,'group_image.jpg');
风险值数据={
发件人:'兴奋用户',
致:'rayteamstudio@gmail.com',
主题:"复杂",,
文本:“组创建请求”,
html:`名为:${fromName}的用户想要创建一个组。
用户ID:${leaderId}
组名:${groupName}
组描述:${groupDescription}
要接受请求,请单击此处:
https://us-central1-i-m-here-c01f6.cloudfunctions.net/acceptOrDenyGroupCreation?leaderID=${leaderId}&requestStatus=已批准
要拒绝请求,请单击此处:
https://us-central1-i-m-here-c01f6.cloudfunctions.net/acceptOrDenyGroupCreation?leaderID=${leaderId}&requestStatus=denied/>`,
附件:文件路径
};
mailgun.messages().send(数据、函数(错误、正文){
如果(错误)
console.log('电子邮件错误:',错误);
});
请帮助您不能像使用HTTP URL一样使用
gs://bucket name/path to file
URL从云存储下载文件。相反,您必须执行以下操作之一:
您可以将其作为缓冲区,并按如下方式发送:
var request = require('request');
var file = request("https://www.google.ca/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
var data = {
from: 'Excited User <me@samples.mailgun.org>',
to: 'serobnic@mail.ru',
subject: 'Hello',
text: 'Testing some Mailgun awesomeness!',
attachment: file
};
mailgun.messages().send(data, function (error, body) {
console.log(body);
});
var request=require('request');
var file=请求(“https://www.google.ca/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
风险值数据={
发件人:'兴奋用户',
致:'serobnic@mail.ru',
主题:“你好”,
文字:“测试一些邮枪的威力!”,
附件:档案
};
mailgun.messages().send(数据、函数(错误、正文){
控制台日志(主体);
});
从在您给出的示例中,您正在使用
gs:://bucket name/path
从云存储下载文件并将其作为附件发送。为此,您需要按照以下文档使用依赖项:
在这种情况下,您需要做的就是:
// var path = require("path");
const request = require('request');
var filepath = request(`gs://i-m-here-c01f6.appspot.com/Groups/${leaderId}`);
如果您想更具体地为文件指定属性,可以使用新的mailgun.Attachments(options)
传入一个options
参数,该参数如下所示:
options: {
data: filepath,
filename: 'name,jpg',
contentType: 'image/jpeg',
knownLength: 2019121,
};
在哪里
- 数据-可以是以下数据之一:
- 表示附件的文件路径的字符串
- 文件数据的缓冲区
- 流的实例,表示它是可读流
- filename—用于附件的文件名。默认值为“文件”
- contentType—内容类型。流数据的情况下需要。例如图像/jpeg
- knownLength—以字节为单位的内容长度。流数据的情况下需要
Angular
/TypeScript
中
它从component.html文件的某个地方开始
<form
#formDirective="ngForm"
[formGroup]="contactForm"
(ngSubmit)="onSubmit(contactForm.value, formDirective)"
>
<mat-form-field>
<ngx-mat-file-input
(change)="uploadFile($event)"
formControlName="fileUploader"
multiple
type="file"
>
</ngx-mat-file-input>
</mat-form-field>
</form>
从前端到后端,开发人员要动态地将文件附加到一封电子邮件中,需要使用正确的contentType
、downloadURL
、和fileName
,这或多或少都是一件让人头疼的事情。我在WWW上找不到一个完整的解决方案,这就是为什么从前到后的答案
注意:
前端在Firebase端的UI/云存储上处理多个文件上传,所有文件都上传到Firebase。但是,只有一个动态添加的附件工作正常。我仍然不知道如何处理多个动态文件上传
import { AngularFirestore } from '@angular/fire/firestore';
import {
AngularFireStorage,
AngularFireStorageReference,
AngularFireUploadTask,
} from '@angular/fire/storage';
import {
FormBuilder,
FormGroup,
FormGroupDirective,
Validators,
} from '@angular/forms';
import { throwError } from 'rxjs';
...
constructor(
private angularFirestore: AngularFirestore,
private angularFireStorage: AngularFireStorage,
private formBuilder: FormBuilder
) {}
public contentType: string[] = [];
public downloadURL: string[] = [];
public fileName: string = '';
public maxFileSize = 20971520;
public contactForm: FormGroup = this.formBuilder.group({
fileUploader: [
'',
Validators.compose([
// Your validators rules...
]),
],
...
});
...
public onSubmit(form: any, formDirective: FormGroupDirective): void {
form.contentType = this.contentType;
form.fileUploader = this.downloadURL;
form.fileName = this.fileName;
this.angularFirestore
.collection(String(process.env.FIRESTORE_COLLECTION_MESSAGES)) // Make sure the environmental variable is a string.
.add(form)
.then(() => {
// Your logic, such as alert...
.catch(() => {
// Your error handling logic...
});
}
public uploadFile(event: any): void {
// Iterate through all uploaded files.
for (let i = 0; i < event.target.files.length; i++) {
const file = event.target.files[i]; // Get each uploaded file.
const fileName = file.name + '_' + Date.now(); // It makes sure files with the same name will be uploaded more than once and each of them will have unique ID, showing date (in milliseconds) of the upload.
this.contentType = file.type;
this.fileName = fileName;
// Get file reference.
const fileRef: AngularFireStorageReference = this.angularFireStorage.ref(
fileName
);
// Create upload task.
const task: AngularFireUploadTask = this.angularFireStorage.upload(
fileName,
file,
file.type
);
// Upload file to Cloud Firestore.
task
.snapshotChanges()
.pipe(
finalize(() => {
fileRef.getDownloadURL().subscribe((downloadURL: string) => {
this.angularFirestore
.collection(String(process.env.FIRESTORE_COLLECTION_FILES)) // Make sure the environmental variable is a string.
.add({ downloadURL: downloadURL });
this.downloadURL.push(downloadURL);
});
}),
catchError((error: any) => {
return throwError(error);
})
)
.subscribe();
}
}
import { DocumentSnapshot } from 'firebase-functions/lib/providers/firestore';
import { EventContext } from 'firebase-functions';
async function onCreateSendEmail(
snap: DocumentSnapshot,
_context: EventContext
) {
try {
const contactFormData = snap.data();
// You can use those to debug your code...
console.log('Submitted contact form: ', contactFormData);
console.log('context: ', _context); // This log will be shown in Firebase Functions logs.
const mailTransport: Mail = nodemailer.createTransport({
// Make sure the environmental variables have proper typings.
host: String(process.env.MAIL_HOST),
port: Number(process.env.MAIL_PORT),
auth: {
user: String(process.env.MAIL_ACCOUNT),
pass: String(process.env.MAIL_PASSWORD),
},
tls: {
rejectUnauthorized: false, //! Fix ERROR "Hostname/IP doesn't match certificate's altnames".
},
});
const mailOptions = {
attachments: [
{
contentType: `${contactFormData!.contentType}`,
filename: `${contactFormData!.fileName}`,
path: `${contactFormData!.fileUploader}`,
},
],
... // Your other mails options such as bcc, from, to, subject, html...
};
await mailTransport.sendMail(mailOptions);
} catch (err) {
console.error(err);
}
}