Skip to content

Comments

fix: always attach the function bot access token to the context if available#2513

Merged
zimeg merged 24 commits intomainfrom
zimeg-fix-context-function-token
May 5, 2025
Merged

fix: always attach the function bot access token to the context if available#2513
zimeg merged 24 commits intomainfrom
zimeg-fix-context-function-token

Conversation

@zimeg
Copy link
Member

@zimeg zimeg commented Apr 29, 2025

Summary

This PR adds to the refactors of #2424 to always attach the function bot access token to the context if it's available.

Changes of the linked PR now use a shared selectToken function that no longer relies on this value in context to determine which token to use - either workflow, bot, or user - and now use the attachFunctionToken argument:

bolt-js/src/App.ts

Lines 1580 to 1591 in d61f2cd

// Returns either a bot token, a user token or a workflow token for client, say()
function selectToken(context: Context, attachFunctionToken: boolean): string | undefined {
if (attachFunctionToken) {
// If functionBotAccessToken exists on context, the incoming event is function-related *and* the
// user has `attachFunctionToken` enabled. In that case, subsequent calls with the client should
// use the function-related/JIT token in lieu of the botToken or userToken.
if (context.functionBotAccessToken) {
return context.functionBotAccessToken;
}
}
return context.botToken !== undefined ? context.botToken : context.userToken;
}

Preview

Before changes we had implicit use of this value to decide which token to use in the app.function listener:

bolt-js/src/App.ts

Lines 973 to 978 in 657416f

// Attach and make available the JIT/function-related token on context
if (this.attachFunctionToken) {
if (functionBotAccessToken) {
context.functionBotAccessToken = functionBotAccessToken;
}
}

bolt-js/src/App.ts

Lines 1102 to 1105 in 657416f

// If functionBotAccessToken exists on context, the incoming event is function-related *and* the
// user has `attachFunctionToken` enabled. In that case, subsequent calls with the client should
// use the function-related/JIT token in lieu of the botToken or userToken.
const token = context.functionBotAccessToken ? context.functionBotAccessToken : selectToken(context);

function selectToken(context: Context): string | undefined {
// If attachFunctionToken = false, fallback to botToken or userToken
return context.functionBotAccessToken ? context.functionBotAccessToken : context.botToken || context.userToken;
}

Notes

Including this in context gives a choice of using this token in certain circumstances, even if attachFunctionToken is false! 🤖 ✨

Requirements

@zimeg zimeg added bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented semver:patch labels Apr 29, 2025
@zimeg zimeg requested a review from WilliamBergamin April 29, 2025 02:22
@zimeg zimeg self-assigned this Apr 29, 2025
@codecov
Copy link

codecov bot commented Apr 29, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 92.96%. Comparing base (6eeb1df) to head (790cd9f).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2513      +/-   ##
==========================================
- Coverage   92.97%   92.96%   -0.01%     
==========================================
  Files          36       36              
  Lines        7441     7437       -4     
  Branches      652      649       -3     
==========================================
- Hits         6918     6914       -4     
  Misses        518      518              
  Partials        5        5              

☔ 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.

Copy link
Contributor

@WilliamBergamin WilliamBergamin left a comment

Choose a reason for hiding this comment

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

This is an awesome catch 🥇 🚀

I agree the expected behavior should be to always set the context.functionBotAccessToken as the workflow token if it is found in a payload

We only want to set it to the token for the client if this.attachFunctionToken = true

@WilliamBergamin
Copy link
Contributor

@zimeg any chance we can add a unit tests to ensure this behavior is maintained in the future 🙏

Base automatically changed from refactor-function-listener-for-future-auto-ack-changes to main April 30, 2025 14:16
@zimeg zimeg added this to the 4.2.2 milestone Apr 30, 2025
@zimeg
Copy link
Member Author

zimeg commented Apr 30, 2025

@WilliamBergamin Thanks so much once again for the changes of #2424 - that unlocked this fix 👾 ✨

Before merging I agree it'd be best to add tests for this to avoid regressions. I hope to visit this soon!

@WilliamBergamin
Copy link
Contributor

@zimeg this may be needed sooner then we expected in #2508

Copy link
Member Author

@zimeg zimeg left a comment

Choose a reason for hiding this comment

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

@WilliamBergamin Thanks for bumping this! 🤖

I added a test to cover both the function and action listeners which brought one more question that I'm curious about before merging this, but I appreciate that this is surfaced from these tests!

Comment on lines +787 to +788
assert.strictEqual(context.functionExecutionId, functionExecutionId);
assert.strictEqual(context.functionBotAccessToken, functionBotAccessToken);
Copy link
Member Author

Choose a reason for hiding this comment

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

Suggested change
assert.strictEqual(context.functionExecutionId, functionExecutionId);
assert.strictEqual(context.functionBotAccessToken, functionBotAccessToken);
assert.strictEqual(context.functionExecutionId, functionExecutionId);
assert.strictEqual(context.functionBotAccessToken, functionBotAccessToken);
assert.deepStrictEqual(context.functionInputs, inputs);

📣 Here we are not testing that functionInputs are added to context but I'm not sure if this is something we want to change in this PR?

It's not clear to me if this should be included following L1624 from body.event.inputs for convenience:

bolt-js/src/App.ts

Lines 1616 to 1635 in 76140ed

function extractFunctionContext(body: StringIndexed) {
let functionExecutionId: string | undefined = undefined;
let functionBotAccessToken: string | undefined = undefined;
let functionInputs: FunctionInputs | undefined = undefined;
// function_executed event
if (body.event && body.event.type === 'function_executed' && body.event.function_execution_id) {
functionExecutionId = body.event.function_execution_id;
functionBotAccessToken = body.event.bot_access_token;
}
// interactivity (block_actions)
if (body.function_data) {
functionExecutionId = body.function_data.execution_id;
functionBotAccessToken = body.bot_access_token;
functionInputs = body.function_data.inputs;
}
return { functionExecutionId, functionBotAccessToken, functionInputs };
}

Copy link
Contributor

Choose a reason for hiding this comment

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

If adding a test for functionInputs in the context is a small change then we can do it in this PR 💯 but if it is larger then maybe we do it in another PR

Copy link
Member Author

Choose a reason for hiding this comment

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

Good thinking. I'm finding this change involves an update to another file which does seem outside the scope of this PR 🫡

Copy link
Contributor

@WilliamBergamin WilliamBergamin left a comment

Choose a reason for hiding this comment

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

Nice 💯

Ship it as is or add a test for the inputs in the context 🚀

Comment on lines +787 to +788
assert.strictEqual(context.functionExecutionId, functionExecutionId);
assert.strictEqual(context.functionBotAccessToken, functionBotAccessToken);
Copy link
Contributor

Choose a reason for hiding this comment

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

If adding a test for functionInputs in the context is a small change then we can do it in this PR 💯 but if it is larger then maybe we do it in another PR

Copy link
Member Author

@zimeg zimeg left a comment

Choose a reason for hiding this comment

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

@WilliamBergamin Thanks for both sharing thoughts on these changes and tests, and the review once again 🙏 ✨

I'll merge these changes and follow up with a few more focused PRs soon!

Comment on lines +787 to +788
assert.strictEqual(context.functionExecutionId, functionExecutionId);
assert.strictEqual(context.functionBotAccessToken, functionBotAccessToken);
Copy link
Member Author

Choose a reason for hiding this comment

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

Good thinking. I'm finding this change involves an update to another file which does seem outside the scope of this PR 🫡

@zimeg zimeg merged commit cad34f5 into main May 5, 2025
18 checks passed
@zimeg zimeg deleted the zimeg-fix-context-function-token branch May 5, 2025 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented semver:patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants