NodeJS 禁止使用401型机枪

eagi6jfj  于 2023-03-17  发布在  Node.js
关注(0)|答案(7)|浏览(159)

我试着用mailgun发送电子邮件。我用的是node.js(nest.js),这是我的邮件服务。我应该改变什么?当我试着发送第一封电子邮件时(在mailgun官方网站中有描述),我收到了同样的错误信息。

import { Injectable } from '@nestjs/common';
import * as Mailgun from 'mailgun-js';
import { IMailGunData } from './interfaces/mail.interface';
import { ConfigService } from '../config/config.service';

@Injectable()
export class MailService {
  private mg: Mailgun.Mailgun;

  constructor(private readonly configService: ConfigService) {
    this.mg = Mailgun({
      apiKey: this.configService.get('MAILGUN_API_KEY'),
      domain: this.configService.get('MAILGUN_API_DOMAIN'),
    });
  }

  send(data: IMailGunData): Promise<Mailgun.messages.SendResponse> {
    console.log(data);
    console.log(this.mg);
    return new Promise((res, rej) => {
      this.mg.messages().send(data, function (error, body) {
        if (error) {
          console.log(error);
          rej(error);
        }
        res(body);
      });
    });
  }
}

当我尝试发送消息时,我收到401错误,带有禁止的描述。
我的mg(控制台.日志(此. mg))

Mailgun {
  username: 'api',
  apiKey: '920d6161ca860e7b84d9de75e14exxx-xxx-xxx',
  publicApiKey: undefined,
  domain: 'lokalne-dobrodziejstwa.pl',
  auth: 'api:920d6161ca860e7b84d9de75e14exxx-xxx-xxx',
  mute: false,
  timeout: undefined,
  host: 'api.mailgun.net',
  endpoint: '/v3',
  protocol: 'https:',
  port: 443,
  retry: 1,
  testMode: undefined,
  testModeLogger: undefined,
  options: {
    host: 'api.mailgun.net',
    endpoint: '/v3',
    protocol: 'https:',
    port: 443,
    auth: 'api:920d6161ca860e7b84d9de75e14exxx-xxx-xxx',
    proxy: undefined,
    timeout: undefined,
    retry: 1,
    testMode: undefined,
    testModeLogger: undefined
  },
  mailgunTokens: {}
}

我的电子邮件正文

{
  from: 'rejestracja@lokalne-dobrodziejstwa.pl',
  to: 'me@gmail.com',
  subject: 'Verify User',
  html: '\n' +
    '                <h3>Hello me@gmail.com!</h3>\n' +
    '            '
}
ljsrvy3e

ljsrvy3e1#

当我的域名在欧盟区域时,我遇到了这个问题。当你使用欧盟区域时,你必须在配置中指定它--Mailgun没有清楚地解释这一点。
所以应该是这样的:

var mailgun = require("mailgun-js")({
  apiKey: API_KEY,
  domain: DOMAIN,
  host: "api.eu.mailgun.net",
});
2fjabf4q

2fjabf4q2#

欧盟用户:对于mailgun v3,您必须在mailgun.client()的url选项中指定eu端点,如下所示:

const API_KEY = "xxxxxxxxXxxxxxxxxxxxxxxxxxxx-xxxxxxx-xxxxxx";
const DOMAIN = "mydomaim.com";

const formData = require('form-data');
const Mailgun = require('mailgun.js');

const mailgun = new Mailgun(formData);
const client = mailgun.client({username: 'api', key: API_KEY, url:"https://api.eu.mailgun.net"});
// console.log(client)

const messageData = {
from: 'Yoopster <joep@mydomain.com>',
to: 'mybestbuddy@gmail.com',
subject: 'Hello',
text: 'Testing some Mailgun awesomeness!'
};

client.messages.create(DOMAIN, messageData)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.error(err);
});
vc6uscn9

vc6uscn93#

尝试通过控制台中的此命令向自己发送电子邮件(帐户电子邮件):

curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <mailgun@YOUR_DOMAIN_NAME>' \
    -F to=YOU@YOUR_DOMAIN_NAME \
    -F to=bar@example.com \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomeness!'

有效果吗?
如果它不是..我假设你已经写了API和域正确,所以以后如果你有免费的帐户,你应该检查授权recipant概述部分(你不能发送电子邮件到任何地方,你想在试用帐户,你必须先键入它)
x1c 0d1x如果你没有找到解决方案,这是我如何做我的mailService(工作),所以你可以尝试一下,我用nodemailer这样做:

import { Injectable, InternalServerErrorException, OnModuleInit } from '@nestjs/common';
import { readFileSync } from 'fs';
import { compile } from 'handlebars';
import { join } from 'path';
import * as nodemailer from 'nodemailer';
import { Options } from 'nodemailer/lib/mailer';
import * as mg from 'nodemailer-mailgun-transport';

import { IReplacement } from './replacements/replacement';
import { ResetPasswordReplacement } from './replacements/reset-password.replacement';

@Injectable()
export class MailService implements OnModuleInit {
  private transporter: nodemailer.Transporter;

  onModuleInit(): void {
    this.transporter = this.getMailConfig(); 
  }

  sendResetPasswordMail(email: string, firstName: string = '', lastName: string = ''): void { // this is just example method with template but you can use sendmail directly from sendMail method
    const resetPasswordReplacement = new ResetPasswordReplacement({
      firstName,
      lastName,
      email,
    });

    this.sendMail(
      proccess.env.MailBoxAddress),
      email,
      'Change password',
      this.createTemplate('reset-password', resetPasswordReplacement),
    );
  }

  sendMail(from: string, to: string, subject: string, body: string): void {
    const mailOptions: Options = { from, to, subject, html: body };

    return this.transporter.sendMail(mailOptions, (error) => {
      if (error) {
        throw new InternalServerErrorException('Error');
      }
    });
  }

  private getMailConfig(): any {
    return nodemailer.createTransport(mg({
      auth: {
        api_key: proccess.env.MailApiKey,
        domain: proccess.env.MailDomain
      },
    }));
  }

  private createTemplate(fileName: string, replacements: IReplacement): string {
    const templateFile = readFileSync(join(__dirname, 'templates', `${fileName}.html`), { encoding: 'utf-8' });
    const template = compile(templateFile);
    return template(replacements);
  }
}

const templateFile = readFileSync(join(__dirname, 'templates', `${fileName}.html`), { encoding: 'utf-8' });

定义包含内容的html文件的位置及其外观(本例中为reset-password.html):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Password reset</title>
</head>
<body>
  <div>Welcome {{firstName}} {{lastName}}</div>
</body>
</html>

{{}}中的值将自动被库替换
在本示例中,ResetPasswordReplacement是其唯一基本对象,包含3个属性,并由空接口IReplacement继承-使其仅用于模板文件中定义的值
资料来源:

  1. https://www.npmjs.com/package/nodemailer-mailgun-transport
  2. https://documentation.mailgun.com/en/latest/quickstart-sending.html#send-with-smtp-or-api
nbewdwxp

nbewdwxp4#

从mailgun API v3起,您必须:

var formData = require('form-data');
            const Mailgun = require('mailgun.js');
            const mailgun = new Mailgun(formData);
            const mg      = mailgun.client({
                username: 'api', 
                key: process.env.EMAIL_MAILGUN_API_KEY
            }); 
            
            mg.messages.create(process.env.EMAIL_MAILGUN_HOST, {
                from: "sender na,e <"+process.env.EMAIL_FROM+">",
                to: ["dan@dominic.com"],
                subject: "Verify Your Email",
                text: "Testing some Mailgun awesomness!",
                html: "<h1>"+req+"</h1>"
              })
              .then(msg => {
                console.log(msg);
                res.send(msg);
              }) // logs response data
              .catch(err => { 
                console.log(err);
                res.send(err);
              }); // logs any error
kd3sttzy

kd3sttzy5#

要使用mailgun API,白名单您的服务器IP,从那里你要使用mailgun网络控制台发送电子邮件。

设置〉安全和用户〉API安全〉IP白名单

yacmzcpb

yacmzcpb6#

如果您仍在使用golang脚本寻找答案,请添加以下行

mg := mailgun.NewMailgun()

//当您有EU域时,必须指定终结点

mg.SetAPIBase("https://api.eu.mailgun.net/v3")
ecbunoof

ecbunoof7#

另一个可能发生在我身上的案例是:
我最初用npm安装了mailgun-js,并开始使用yarn代替,然后它在每个请求中都返回401 Forbidden,所以yarn add mailgun-js解决了这个问题。

相关问题