node.js - Azure Function Timer Trigger Never Triggered - Stack Overflow

admin2025-04-29  1

I'm trying to use a timer trigger to run a refresh of an access token but for some reason the function is never triggered.

app.timer('RefreshAccessTokenTimer', {
    schedule: '* * * * *', 
    handler: async (timer, context) => {
        context.log('Timer function triggered:', timer.scheduleStatus);
        context.log(`Schedule status: ${JSON.stringify(timer.scheduleStatus)}`);

        // Retrieve tenantId, clientId, clientSecret, and refreshToken from secure storage
        const tenantId = process.env.TENANT_ID;
        const clientId = process.env.CLIENT_ID;
        const clientSecret = process.env.CLIENT_SECRET;
        const refreshToken = process.env.REFRESH_TOKEN; // Update with your secure storage method

        try {
            const refreshedToken = await refreshAccessToken(tenantId, clientId, clientSecret, refreshToken);
            context.log('Token refreshed successfully:', refreshedToken);

            // Update the stored refresh token if necessary
            process.env.REFRESH_TOKEN = refreshedToken.refreshToken;
            process.env.ACCESS_TOKEN = refreshedToken.accessToken;
        } catch (error) {
            context.log.error('Error refreshing token:', error.message);
        }
    },
});

I ran it locally and saw my expected output but when I deploy it to azure I don't see any logs what so ever so I can't tell what's wrong. My deployment logs say that everything is fine as well.

I'm trying to use a timer trigger to run a refresh of an access token but for some reason the function is never triggered.

app.timer('RefreshAccessTokenTimer', {
    schedule: '* * * * *', 
    handler: async (timer, context) => {
        context.log('Timer function triggered:', timer.scheduleStatus);
        context.log(`Schedule status: ${JSON.stringify(timer.scheduleStatus)}`);

        // Retrieve tenantId, clientId, clientSecret, and refreshToken from secure storage
        const tenantId = process.env.TENANT_ID;
        const clientId = process.env.CLIENT_ID;
        const clientSecret = process.env.CLIENT_SECRET;
        const refreshToken = process.env.REFRESH_TOKEN; // Update with your secure storage method

        try {
            const refreshedToken = await refreshAccessToken(tenantId, clientId, clientSecret, refreshToken);
            context.log('Token refreshed successfully:', refreshedToken);

            // Update the stored refresh token if necessary
            process.env.REFRESH_TOKEN = refreshedToken.refreshToken;
            process.env.ACCESS_TOKEN = refreshedToken.accessToken;
        } catch (error) {
            context.log.error('Error refreshing token:', error.message);
        }
    },
});

I ran it locally and saw my expected output but when I deploy it to azure I don't see any logs what so ever so I can't tell what's wrong. My deployment logs say that everything is fine as well.

Share Improve this question edited Jan 7 at 5:24 Ikhtesam Afrin 6,5872 gold badges4 silver badges10 bronze badges asked Jan 7 at 3:16 Alex WachowskiAlex Wachowski 1 1
  • Is it a javascript or typescript function? – Ikhtesam Afrin Commented Jan 7 at 3:34
Add a comment  | 

1 Answer 1

Reset to default 0
  • Use a valid 6 digit CRON expression like 0 * * * * * in your function code.

  • If your function is not getting triggered then you can check in the associated application insight to know about the error message if any.

  • I have used below code which worked for me locally as well in Azure function app.

const { app } = require('@azure/functions');
const axios = require('axios');

app.timer('RefreshAccessTokenTimer', {
    schedule: '0 * * * * *',
    handler: async (timer, context) => {
        context.log('Timer function triggered:', timer.scheduleStatus);
        context.log(`Schedule status: ${JSON.stringify(timer.scheduleStatus)}`);

        const tenantId = process.env.TENANT_ID;
        const clientId = process.env.CLIENT_ID;
        const clientSecret = process.env.CLIENT_SECRET;
        const refreshToken = process.env.REFRESH_TOKEN; 

        try {
            const refreshedToken = await refreshAccessToken(tenantId, clientId, clientSecret, refreshToken);
            context.log('Token refreshed successfully:', refreshedToken);

            process.env.REFRESH_TOKEN = refreshedToken.refreshToken;
            process.env.ACCESS_TOKEN = refreshedToken.accessToken;
        } catch (error) {
            context.log.error('Error refreshing token:', error.message);
        }
    }
});

async function refreshAccessToken(tenantId, clientId, clientSecret, refreshToken) {
    const tokenEndpoint = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
    const params = new URLSearchParams();

    params.append('grant_type', 'refresh_token');
    params.append('client_id', clientId);
    params.append('client_secret', clientSecret);
    params.append('refresh_token', refreshToken);

    try {
        const response = await axios.post(tokenEndpoint, params.toString(), {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
        });

        return {
            accessToken: response.data.access_token,
            refreshToken: response.data.refresh_token || refreshToken, 
        };
    } catch (error) {
        throw new Error(`Failed to refresh access token: ${error.response?.data?.error_description || error.message}`);
    }
}
  • I have added the environment variables in local settings file.
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "TENANT_ID": "932****af6d",
    "CLIENT_ID": "c266****78ea5",
    "CLIENT_SECRET": "_lg8Q*****bPu",
    "REFRESH_TOKEN": "1.AX0AK*****7Z5g"
  }
}

I am able to get expected result locally.

Azure Functions Core Tools
Core Tools Version:       4.0.6280 Commit hash: N/A +421f0144b42047aa289ce691dc6db4fc8b6143e6 (64-bit)
Function Runtime Version: 4.834.3.22875

[2025-01-07T06:38:34.375Z] Debugger listening on ws://12****5d43f1
[2025-01-07T06:38:34.376Z] For help, see: https://nodejs.org/en/docs/inspector
[2025-01-07T06:38:34.376Z] Debugger attached.
[2025-01-07T06:38:34.495Z] Worker process started and initialized.

Functions:

        RefreshAccessTokenTimer: timerTrigger

For detailed output, run func with --verbose flag.
[2025-01-07T06:38:39.413Z] Host lock lease acquired by instance ID '0000000000000000000000000D2022A4'.
[2025-01-07T06:39:00.073Z] Executing 'Functions.RefreshAccessTokenTimer' (Reason='Timer fired at 2025-01-07T12:09:00.0403321+05:30', Id=0685fd5f-3322-48cc-b4ca-9cc1a90d006d)
[2025-01-07T06:39:00.180Z] Schedule status: {"last":"0001-01-01T00:00:00","next":"2025-01-07T12:09:00+05:30","lastUpdated":"0001-01-01T00:00:00"}
[2025-01-07T06:39:00.180Z] Timer function triggered: {
  last: '0001-01-01T00:00:00',
  next: '2025-01-07T12:09:00+05:30',
  lastUpdated: '0001-01-01T00:00:00'
}
[2025-01-07T06:39:07.986Z] Token refreshed successfully: {
  accessToken: 'eyJ0eXA******f2yqSu6jaIA',  
  refreshToken: '1.AX0AK*****5g1A'
}
[2025-01-07T06:39:08.010Z] Executed 'Functions.RefreshAccessTokenTimer' (Succeeded, Id=0685fd5f-3322-48cc-b4ca-9cc1a90d006d, Duration=7960ms)
  • After deploying your code to function app, make sure to add the environment variables in Environment Variables -> App settings .

  • My function got triggered successfully.

转载请注明原文地址:http://anycun.com/QandA/1745934048a91326.html