python-3.xazure-functionsazure-function-appqueuetrigger

QueueTrigger Bindings for Sendgrid -Python


Guided by this post I have written the following queuetrigger code intended to send emails when a message is queued.

import logging
import sendgrid
import azure.functions as func
import os
def main(msg: func.QueueMessage) -> None:
    logging.info('Python queue trigger function processed a queue item: %s',
                 msg.get_body().decode('utf-8'))
    
   
    data = {
        "personalizations": [
          {
            "to": [
              {
                "email": "rrrrrrrr"
              }
            ],
            "subject": "Sending with SendGrid is Fun"
          }
        ],
        "from": {
          "email": "ghyu"
        },
        "content": [
          {
            "type": "text/plain",
            "value": "and easy to do anywhere, even with Python"
          }
         ]
    }
    print('Sending email using SendGrid:', data)
    with open(os.environ[_AZURE_FUNCTION_SENDGRID_OUTPUT_ENV_NAME], 'wb') as f:
      json.dump(data,f)

function.json

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "msg",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "outqueue1",
      "connection": "storageaccountautom92bb_STORAGE"
    },
    
    {
      
      "name": "outputMessage",
      "type": "sendGrid",
      "from": "ghyu",
      "apiKey": "MY_SENDGRID_API_KEY",
      "direction": "out"
    }
  ],
  "disabled": false
}

local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "hjk",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "storageaccountautom92bb_STORAGE": "hjk",
    "MY_SENDGRID_API_KEY": "tyhuE",
    "_AZURE_FUNCTION_SENDGRID_OUTPUT_ENV_NAME" : "GIS klop",
    "_AZURE_FUNCTION_QUEUE_INPUT_ENV_NAME" : "msg"
  }
}

Whereas the function responds to messages as they queue, it is not able to send emails. It throws an error;

the following parameters are declared in function.json but not in Python: {'outputMessage'}
  1. How best can I resolve this?
  2. Are the outward bindings correct?

Solution

  • Azure Function banned the port of send email, so we must use sendgrid to send email.(This is a third part tools but it was been integrated into azure functions binding, so we can directly use it.)

    For example, if you want to send email from email A to email B.

    First, go to the sendgrid website, create a sender and verify the email A:

    enter image description here

    After that, email A is ready to send emails by sendgrid.

    Now we need to generate a SendGrid API key and copy and store the API key:(This will be filled in the Values section of local.settings.json as an environment variable to read.)

    enter image description here

    Then, you can use it to send emails:

    host.json

    {
      "version": "2.0",
      "logging": {
        "applicationInsights": {
          "samplingSettings": {
            "isEnabled": true,
            "excludedTypes": "Request"
          }
        }
      },
      "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[1.*, 3.1.0)"
      }
    }
    

    local.settings.json

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=0730bowmanwindow;AccountKey=xxxxxx;EndpointSuffix=core.windows.net",
        "FUNCTIONS_WORKER_RUNTIME": "python",
        "SendGrid_API_Key": "SG._-yYnhzER2SEbAvzOxSHnA.xxxxxx",
        "0730bowmanwindow_STORAGE": "DefaultEndpointsProtocol=https;AccountName=0730bowmanwindow;AccountKey=xxxxxx;EndpointSuffix=core.windows.net"
      }
    }
    

    function.json

    {
      "scriptFile": "__init__.py",
      "bindings": [
        {
          "name": "msg",
          "type": "queueTrigger",
          "direction": "in",
          "queueName": "myqueue",
          "connection": "0730bowmanwindow_STORAGE"
        },
        {
          "type": "sendGrid",
          "name": "sendGridMessage",
          "direction": "out",
          "apiKey": "SendGrid_API_Key",
          "from": "emailA@emailA.com"
        }
      ]
    }
    

    __init__.py

    import logging
    import json
    import azure.functions as func
    
    
    def main(msg: func.QueueMessage, sendGridMessage: func.Out[str]) -> None:
        logging.info('Python queue trigger function processed a queue item: %s',
                     msg.get_body().decode('utf-8'))
        value = "Sent from Azure Functions"
    
        message = {
            "personalizations": [ {
              "to": [{
                "email": "emailB@emailB.com"
                }]}],
            "subject": "Azure Functions email with SendGrid",
            "content": [{
                "type": "text/plain",
                "value": value }]
        }
        sendGridMessage.set(json.dumps(message))
    

    After that, I send a message to 'myqueue', and emailB get the email:

    enter image description here

    By the way, this can only guarantee successful delivery, because some mailboxes refuse to accept mail sent through sendgrid. In this case, you will still get a 200 response, but the recipient will not receive the mail.(In this case, the recipient needs to go to the mailbox settings to lift the relevant restrictions.)