Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Azure Functions v4 Model for webhookCallback #737

Open
mildronize opened this issue Jan 15, 2025 · 8 comments · May be fixed by #738
Open

Support Azure Functions v4 Model for webhookCallback #737

mildronize opened this issue Jan 15, 2025 · 8 comments · May be fixed by #738

Comments

@mildronize
Copy link

Background

First of all, I’d like to thank the team behind grammy for creating such an amazing Telegram framework! I’ve enjoyed working with it, especially on my open-source bot using Cloudflare Workers.

Recently, I tried to use the webhookCallback feature with Azure Functions v4 (the latest official version of the Node.js runtime).

However, I encountered an issue where Cloudflare Workers did not fully support Node.js APIs (details here). As a result, I returned to Azure Functions for deployment. After reviewing the webhookCallback interface, I found that it works well with the Azure Functions v3 model (as tested with the following code):

import { webhookCallback } from 'grammy';
await webhookCallback(bot, "azure")(request, context);

Environment

  • Runtime: Node.js 20
  • grammy Version: 1.34.0

Issue Summary

  1. The grammy documentation does not specify which versions of Azure Functions are supported. Based on my tests, it seems only Azure Functions v3 is compatible, and Azure Functions v4 is not yet supported.
  2. To assist others, I created a template for grammy with Azure Functions v3 using Nammatham v1, to help developers get started more easily.
  3. This is not a complaint! The work you’ve done is fantastic, and if I have some free time, I’d be happy to contribute to Azure Functions v4 support. If the maintainers can guide me on where to start, I’d greatly appreciate it.

Thank you for taking the time to read this issue, and keep up the great work!

@KnorpelSenf
Copy link
Member

KnorpelSenf commented Jan 15, 2025

Hi! Thanks for the kind words!

Re-reading the code, I am actually surprised that grammY 1.34 works with v3. Isn't v3 supposed to have the request as the second argument?

/** Azure Functions */
const azure: AzureAdapter = (request, context) => ({
update: Promise.resolve(request.body as Update),
header: context.res?.headers?.[SECRET_HEADER],
end: () => (context.res = {
status: 200,
body: "",
}),
respond: (json) => {
context.res?.set?.("Content-Type", "application/json");
context.res?.send?.(json);
},
unauthorized: () => {
context.res?.send?.(401, WRONG_TOKEN_ERROR);
},
});

It looks like the order of context and request is wrong.

That being said, we clearly need a new adapter to support v4.

I opened #738 which should fix both issues. You can install it from GitHub via

npm install github:grammyjs/grammY#support-azure-v4

Could you test the following two cases and confirm that they work?

  • Azure Functions v3 with webhookCallback(bot, "azure")
  • Azure Functions v4 with webhookCallback(bot, "azure-v4")

@KnorpelSenf KnorpelSenf linked a pull request Jan 15, 2025 that will close this issue
@KnorpelSenf
Copy link
Member

import { webhookCallback } from 'grammy';
await webhookCallback(bot, "azure")(request, context);

Oh now I see it. You basically added a workaround that fixes the issue in grammY. That's why it did not crash on your end. This was never supposed to be necessary.

@mildronize
Copy link
Author

mildronize commented Jan 15, 2025

@KnorpelSenf Thank you for your explanation. I now understand your points. In the current version of grammY (1.3.4), using the original Azure Functions v3 model might cause issues due to incorrect argument order.

Somehow, with my framework, Nammatham, this can be resolved as it manually pass the arguments. For example:

import { webhookCallback } from 'grammy';
await webhookCallback(bot, "azure")(request, context);

Thank you so much for addressing the issue so quickly! I'm pleasantly surprised and excited about this progress. I'll now prepare a repository to test both the v3 and v4 adapters and will share the results with you once they are ready.

@mildronize
Copy link
Author

mildronize commented Jan 15, 2025

@KnorpelSenf For v3 result test, I've successfully run grammY on locally, but I've found that the type of Context in @azure/functions@v3.5.1 not compatible with your provided in the library Context.

Here is the code for v3: https://github.com/mildronize/grammy-azure-functions-test/tree/main/func-v3

the type error is here:

CleanShot 2568-01-16 at 00 14 39

the full error:

Argument of type 'Context' is not assignable to parameter of type '{ res?: { status: number; body: string; headers?: Record<string, string>; set?: (key: string, value: string) => void; send?: { (body: unknown): void; (status: number, body: unknown): void; }; }; }'.
  Types of property 'res' are incompatible.
    Type '{ [key: string]: any; }' is missing the following properties from type '{ status: number; body: string; headers?: Record<string, string>; set?: (key: string, value: string) => void; send?: { (body: unknown): void; (status: number, body: unknown): void; }; }': status, body

the code that error found

const telegramBot: AzureFunction = async function (
  context: Context,
  request: HttpRequest,
): Promise<void> {
  await webhookCallback(bot, "azure")(context, request);
};

Type of Azure/Functions Context

As you can see in the Official Azure Functions Code, https://github.com/Azure/azure-functions-nodejs-library/blob/v3.5.1/types/Context.d.ts#L11-L71, you will see the context is not match as the error occurs.

And your context will be https://github.com/grammyjs/grammY/blob/support-azure-v4/src/convenience/frameworks.ts#L82-L94

Solution

I've created the PR that fix that of your Context: #739

and the result as show below

CleanShot 2568-01-16 at 00 27 13

@KnorpelSenf
Copy link
Member

Epic, thank you!

@KnorpelSenf
Copy link
Member

KnorpelSenf commented Jan 15, 2025

@mildronize it's merged, can you confirm that the pull request #738 introduces the right changes now?

@mildronize
Copy link
Author

mildronize commented Jan 16, 2025

@KnorpelSenf let's me test it on azure func v4
And deploy on azure already, I'll let you know later

@mildronize
Copy link
Author

mildronize commented Jan 16, 2025

@KnorpelSenf

Problem in Type v4

I've founded that type is incorrect in Azure Functions v4 (@azure/functions@4.6.0), due the original type of

Image

After i've fixed typed,

Image

I can run them smoothly, I've tested locally and already deployed on Azure for Both v3, V4

Test Result for v3

Image

Test Result for v4

Image

Solution

Due to Azure Functions v4 type of InvocationContext and HttpRequest is incorrect, I've fixed in the PR #742

After merge this PR, I think everything work fine both v3 and v4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants