Skip to content

fix(aws-lambda): accept lowercased secret-token header for HTTP API#900

Merged
KnorpelSenf merged 1 commit into
grammyjs:mainfrom
glacierphonk:fix-aws-lambda-secret-token
Apr 20, 2026
Merged

fix(aws-lambda): accept lowercased secret-token header for HTTP API#900
KnorpelSenf merged 1 commit into
grammyjs:mainfrom
glacierphonk:fix-aws-lambda-secret-token

Conversation

@glacierphonk
Copy link
Copy Markdown
Contributor

Summary

Follow-up to #896. The awsLambda and awsLambdaAsync adapters in src/convenience/frameworks.ts read the X-Telegram-Bot-Api-Secret-Token header with a case-sensitive lookup against the title-case constant. That works under API Gateway REST API (payload 1.0), which preserves the original client header case, but fails under API Gateway HTTP API (payload 1.0 or 2.0), which lowercases every inbound header name. Users on HTTP API with a configured secretToken had every update rejected 401, because event.headers["X-Telegram-Bot-Api-Secret-Token"] is undefined when the actual key is "x-telegram-bot-api-secret-token".

AWS documents the HTTP API lowercasing in the payload format structure:

The following examples show the structure of each payload format version. All headernames are lowercased.

REST API users were and are fine; I need them to stay fine.

What changed

 const awsLambda: LambdaAdapter = (event, _context, callback) => ({
     get update() {
         return JSON.parse(event.body ?? "{}");
     },
-    header: event.headers[SECRET_HEADER],
+    header: event.headers[SECRET_HEADER] ??
+        event.headers[SECRET_HEADER_LOWERCASE],

Identical change in awsLambdaAsync. Title-case lookup first (REST API), lowercase fallback second (HTTP API). Both constants already exist at the top of the file and are used by other adapters.

No type changes — LambdaAdapter / LambdaAsyncAdapter already declare headers: Record<string, string | undefined>.

Coverage matrix

Integration Payload Header casing delivered Before After
REST API 1.0 X-Telegram-Bot-Api-Secret-Token works works
HTTP API 1.0 x-telegram-bot-api-secret-token 401 works
HTTP API 2.0 x-telegram-bot-api-secret-token 401 works

Test plan

  • deno check --allow-import src/mod.ts — clean
  • deno task test — 38 suites, 443 steps, all pass
  • Manual smoke for both adapters:
    • title-case key → returns value (REST API path)
    • lowercase key → returns value (HTTP API path)
    • missing header → returns undefined
  • Verified on a live Lambda deployment (not required for merge; happy to do so if you want).

Context

cc @KnorpelSenf — you green-lit this follow-up in #896. Same reasoning, different adapter pair.

The awsLambda and awsLambdaAsync adapters read the
X-Telegram-Bot-Api-Secret-Token header with a case-sensitive lookup
against the title-case constant. This works for API Gateway REST APIs
(payload format 1.0), which preserve the original client header case,
but fails for API Gateway HTTP APIs (payload 1.0 or 2.0), which
lowercase all inbound header names. Users on HTTP API with a
configured secretToken therefore had every update rejected 401.

AWS documents the HTTP API lowercasing behaviour in the payload
format structure section:
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html

Falls back to the lowercase constant so both integration types work
without regressing REST API users. Parallels PR grammyjs#896 for the Azure
adapter.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 20, 2026

Codecov Report

❌ Patch coverage is 0% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.17%. Comparing base (b04bfee) to head (aa042f2).
⚠️ Report is 120 commits behind head on main.

Files with missing lines Patch % Lines
src/convenience/frameworks.ts 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #900      +/-   ##
==========================================
- Coverage   45.52%   44.17%   -1.36%     
==========================================
  Files          19       19              
  Lines        5520     6694    +1174     
  Branches      360      463     +103     
==========================================
+ Hits         2513     2957     +444     
- Misses       3003     3651     +648     
- Partials        4       86      +82     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@KnorpelSenf
Copy link
Copy Markdown
Member

Why does REST API 1.0 still work after this change, given that there is now a mismatch in casing?

Copy link
Copy Markdown
Member

@KnorpelSenf KnorpelSenf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah hold on, looking at the diff helped, nevermind

@KnorpelSenf KnorpelSenf merged commit c865dd3 into grammyjs:main Apr 20, 2026
8 checks passed
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 this pull request may close these issues.

2 participants