【问题标题】:Mailgun - 401 forbiddenMailgun - 401 被禁止
【发布时间】:2020-12-08 20:58:58
【问题描述】:

我尝试使用 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 错误。

我的毫克(console.log(this.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' +
    '            '
}

【问题讨论】:

    标签: node.js nestjs mailgun httpforbiddenhandler


    【解决方案1】:

    当我的域位于欧盟区域时,我遇到了这个问题。当您使用欧盟区域时,您必须在配置中指定它 - Mailgun 没有明确解释。

    所以应该是这样的:

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

    【讨论】:

    【解决方案2】:

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

    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 和域,所以稍后如果你有免费帐户,你应该在概述部分检查授权收件人(你不能在试用帐户上随处发送电子邮件,你必须先输入它)

    如果您没有找到解决方案,这就是我完成邮件服务(工作)的方式,因此您可以尝试一下,我使用 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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        从 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
        

        【讨论】:

          【解决方案5】:

          要使用 mailgun API,请将您要使用 mailgun Web 控制台发送电子邮件的服务器 IP 列入白名单。

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

          【讨论】:

            猜你喜欢
            • 2015-08-30
            • 2018-10-14
            • 1970-01-01
            • 1970-01-01
            • 2014-08-27
            • 2018-10-26
            • 2016-09-13
            • 2014-07-04
            相关资源
            最近更新 更多