Использование SendGrid с моделью программирования Azure node.js v4

Моя цель — отправить электронное письмо со страницы контактов статического веб-приложения Azure с помощью функции Azure. Мне удалось заставить это работать, как описано ниже, поэтому мой вопрос: «Как это можно сделать лучше в функциях Azure?»

  • Очевидно, нельзя использовать службы связи Azure из функции Azure для отправки электронной почты. Мне удалось заставить это работать в эмуляции локального статического веб-приложения (SWA), но при запуске из Azure это происходит автоматически.

  • Я забил и создал учетную запись SendGrid. Он предлагает 100 бесплатных сообщений в день бесплатно, так что это хорошая альтернатива.

  • Все справочные материалы, которые я могу найти, ссылаются на интеграцию с использованием модели программирования Azure node.js v3, которая включает файлы конфигурации function.json. По этому поводу даже есть проблема с репозиторием Microsoft Docs на GitHub: https://github.com/MicrosoftDocs/azure-docs/issues/119439

  • Поскольку модель программирования Azure node.js v4 (далее просто «v4») является моделью по умолчанию и стандартом, я решил, что не хочу использовать v3.

  • Пример кода SendGrid работает практически сразу после установки, но когда вы оборачиваете его в асинхронную функцию для версии 4, вам нужно дождаться операции «.send». Если вы этого не сделаете, функция фактически завершит работу, и вы получите значение ответа «неожиданное состояние» (используя мой код; сообщение по-прежнему отправляется в локальной среде, но на это нельзя рассчитывать). Здесь проявляется моя слабость к JS async, потому что я думал, что then/catch — это другой способ работы с промисами.

Вот мой рабочий код:

const { app } = require("@azure/functions");
const mta = require("@sendgrid/mail");

app.http("sendGrid", {
  methods: ["GET", "POST"],
  authLevel: "anonymous",
  handler: async (request, context) => {
    const key = process.env.SENDGRID_API_KEY;
    var response = 'unexpected state'
    var code = 200;

    // Authenticate
    mta.setApiKey(key);

    // Timestamp for this invocation
    const timestamp = new Date(Date.now());

    // Build a message
    const content = {
      to: "user@domain", /* <== replace with your target email address */
      from: "user@domain", /* <== replace with authenticated sender address */
      subject: `SendGrid message ${timestamp}`,
      text: `SendGrid message body text ${timestamp}`,
      html: `SendGrid message body html <strong>${timestamp}</strong>`
    };

    await mta.send(content)
            .then(() => { 
                response = `message ${timestamp} sent`;
                code = 200;
            })
            .catch((thrown) => { 
                response = `message not sent ${thrown}`;
                code = 500;
            });
    
    context.log(response);

    return { status: code, body: response };
  }
});

🤔 А знаете ли вы, что...
Node.js поддерживает работу с файлами и директориями на сервере.


60
1

Ответ:

Решено

Чтобы отправлять электронную почту из статического веб-приложения Azure с помощью функции Azure версии 4, вам необходимо добавить приложение внешнего интерфейса для вызова конечной точки API. Я использовал файл _src/index.html_, чтобы получить текст из функции API и отобразить его на экране, который действует как никакой фреймворк.

Я использовал этот MSDOC, чтобы добавить API к статическим веб-приложениям Azure с функциями Azure.

Ниже приведен простой HTML-код, который используется для запуска/отображения результатов. Функция Azure для отправки электронного письма с помощью SendGrid.


<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <meta name = "viewport" content = "width=device-width, initial-scale=1.0">
    <title>API Response Display</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        .response {
            margin-top: 20px;
            padding: 20px;
            border: 1px solid #ccc;
            border-radius: 5px;
        }
        .success {
            background-color: #e6ffed;
            border-color: #a3d9a5;
        }
        .failure {
            background-color: #ffe6e6;
            border-color: #d9a5a5;
        }
    </style>
</head>
<body>
    <h1>API Response Display</h1>
    <button id = "fetchButton">Fetch API Response</button>
    <div id = "responseContainer" class = "response"></div>

    <script>
        document.getElementById('fetchButton').addEventListener('click', async () => {
            const responseContainer = document.getElementById('responseContainer');
            responseContainer.innerHTML = 'Fetching...';

            try {
                const response = await fetch('/api/httpTrigger');
                const data = await response.json();

                if (response.ok) {
                    responseContainer.innerHTML = `
                        <div class = "success">
                            <h2>Success</h2>
                            <pre>${JSON.stringify(data, null, 2)}</pre>
                        </div>
                    `;
                } else {
                    responseContainer.innerHTML = `
                        <div class = "failure">
                            <h2>Failure</h2>
                            <pre>${JSON.stringify(data, null, 2)}</pre>
                        </div>
                    `;
                }
            } catch (error) {
                responseContainer.innerHTML = `
                    <div class = "failure">
                        <h2>Error</h2>
                        <pre>${error}</pre>
                    </div>
                `;
            }
        });
    </script>
</body>
</html>

Структура папки Git:

  • Теперь измените git yml в соответствии со структурой вашей папки.
 app_location to  "./src" 
  api_location to  "./api1"
 output_location to  "." 

Обратитесь к этому SO для файла конфигурации рабочего процесса yml в Static Web App. Статус развертывания

Конечная точка приложения функции должна иметь префикс /api, поскольку Static Web Apps сопоставляет запросы, отправленные к /api. Существующее приложение «Функции Azure» предоставляет конечную точку через следующий пример URL-адреса. https:/nameofazuresataticwebapp.azurewebsites.net/api/functionname, как показано на изображении ниже.

Приложение «Функции Azure» со статическим выводом Azure:

Статический вывод Azure: