0

NOTE: There is no issue here, The issue was with my functions.json script file location. It was pointing to an old script file. The minute I pointed to a new one, it started working.

I am not sure why this is happening, I have a try-catch block and the function never hits the catch block but the image I am trying upload never shows up in the container.

I am new to NODEJS. Since I cant achieve the same thing using C# functions, I decided to write it in the node.

Problem: Azure function Service bus topic trigger, take the message payload and grabs a screenshot of the page using puppeteer. The output from the buffer is in form of the buffer, I am trying to upload this to Azure storage blob.

import { AzureFunction, Context } from "@azure/functions";
import { ServiceBusMessage } from "@azure/service-bus";
import * as puppeteer from 'puppeteer';
import * as BlobServiceClient from "azure-storage";
import { Readable } from 'stream';

const serviceBusTopicTrigger: AzureFunction = async function (context: Context, mySbMsg: ServiceBusMessage): Promise<void> {
    try {
        const promotionId = context.bindingData.userProperties.promotionId;
        context.log('Player Screen Grabber ServiceBus topic trigger function processing message started', promotionId);
        const playerURL = process.env['playerURL'] + promotionId + '/';
        let browser = await puppeteer.launch({ headless: true });
        let page = await browser.newPage();
        await page.goto(playerURL, { waitUntil: 'networkidle2' });
        await page.setViewport({ width: 1920, height: 1080 });
        const screenshotBuffer = await page.screenshot({
            encoding: 'binary'
        });
        await page.close();
        await browser.close();
        const newPlayerScreenShotStream = new Readable({
            read() {
                this.push(screenshotBuffer);
            },
        });
        var fileName = promotionId + ".png";
        context.bindings.fileName = fileName;
        context.bindings.storage = screenshotBuffer;
        context.done();
        context.log('Player Screen Grabber ServiceBus topic trigger function processing message ended', promotionId);
    }
    catch (error) {
        throw error;
    }
};

enter image description here

0

1 Answer 1

1

According to your infromation you provide, you want to use dymaic name in Azure function blob storage output bining. If so, we cannot use context.bindings.<> to implement it. For more details, please refer to here and here

If you want to implement it, you have the following two choices.

if you define the message's body as json, we can directly read the value with binding expression in function

For example

My message

enter image description here

function.json

{
  "bindings": [
    {
      "name": "mySbMsg",
      "type": "serviceBusTrigger",
      "direction": "in",
      "topicName": "",
      "subscriptionName": "",
      "connection": "MYSERVICEBUS"
    },
    {
      "type": "blob",
      "direction": "out",
      "name": "outputBlob",
      "path": "outcontainer/{fileName}.png",
      "connection": "AzureWebJobsStorage"
    }
  ],
  "scriptFile": "../dist/ServiceBusTopicTrigger1/index.js"
}

Function code

import { AzureFunction, Context } from "@azure/functions";
import * as puppeteer from "puppeteer";

const serviceBusTopicTrigger: AzureFunction = async function (
  context: Context,
  mySbMsg: any
): Promise<void> {
  try {
    context.log("ServiceBus topic trigger function processed message", mySbMsg);
    const promotionId = context.bindingData.userProperties.promotionId;

    const playerURL =
      "https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=v2";
    let browser = await puppeteer.launch({ headless: true });
    let page = await browser.newPage();
    await page.goto(playerURL, { waitUntil: "networkidle2" });
    await page.setViewport({ width: 1920, height: 1080 });
    const screenshotBuffer = await page.screenshot({
      encoding: "binary",
    });
    await page.close();
    await browser.close();
    context.bindings.outputBlob = screenshotBuffer;
  } catch (error) {
    throw error;
  }
};

export default serviceBusTopicTrigger;

enter image description here

enter image description here

  • Using Azure Blob storage sdk Function code
import { AzureFunction, Context } from "@azure/functions";
import * as puppeteer from "puppeteer";
import { BlobServiceClient } from "@azure/storage-blob";
const serviceBusTopicTrigger: AzureFunction = async function (
  context: Context,
  mySbMsg: any
): Promise<void> {
  try {
    context.log("ServiceBus topic trigger function processed message", mySbMsg);
    const promotionId = context.bindingData.userProperties.promotionId;

    const playerURL =
      "https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=v2";
    let browser = await puppeteer.launch({ headless: true });
    let page = await browser.newPage();
    await page.goto(playerURL, { waitUntil: "networkidle2" });
    await page.setViewport({ width: 1920, height: 1080 });
    const screenshotBuffer = await page.screenshot({
      encoding: "binary",
    });
    await page.close();
    await browser.close();
    // the storage account connection string
    const constr = process.env["AzureWebJobsStorage"];
    const blobserviceClient = BlobServiceClient.fromConnectionString(constr);
    const containerClient = blobserviceClient.getContainerClient("output");
    const blob = containerClient.getBlockBlobClient(`${promotionId}.png`);
    await blob.uploadData(screenshotBuffer);
  } catch (error) {
    throw error;
  }
};

export default serviceBusTopicTrigger;

My message enter image description here

Result enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot. After digging, I realised that the issue is with functions.json script file location. It was running an old script.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.