Let's Do DevOps

Let's Do DevOps

Share this post

Let's Do DevOps
Let's Do DevOps
šŸ”„Building a Teams Bot with AI Capabilities - Part 4 - Receiver Lambda for OAuth2 Tokens and StatešŸ”„

šŸ”„Building a Teams Bot with AI Capabilities - Part 4 - Receiver Lambda for OAuth2 Tokens and StatešŸ”„

aka, I don't want to authenticate to SSO each time I send you a message

Kyler Middleton's avatar
Kyler Middleton
Jul 09, 2025
āˆ™ Paid

Share this post

Let's Do DevOps
Let's Do DevOps
šŸ”„Building a Teams Bot with AI Capabilities - Part 4 - Receiver Lambda for OAuth2 Tokens and StatešŸ”„
Share

This blog series focuses on presenting complex DevOps projects as simple and approachable via plain language and lots of pictures. You can do it!

These articles are supported by readers, please consider subscribing to support me writing more of these articles <3 :)

This article is part of a series of articles, because 1 article would be absolutely massive.

  • Part 1: Create an Azure Bot and App Registration

  • Part 2: Register Bot in Teams with Teams Developer Portal

  • Part 3: Delegated Permissions and Making Lambda Stateful for Oauth2

  • Part 4 (this article): Building the Receiver lambda to store tokens and state

Hey all!

In the series so far we’ve registered an App Registration (permissions), an Azure Bot (Teams back-end Bot infra and link to permissions), and built a bot in the Teams Developer Portal (register name in Teams App). We also talked about how we’ll be building this Teams app with Delegated access tokens exclusively, which means we’ll need to establish some state for the tokens and conversations.

The use case for storing those two things are very different:

  • Storing Conversations - We only have one function URL, so we need some routing - on first contact, we’ll push a ā€œCardā€ to Teams to send users to the SSO login portal, and when the OAuth2 token is pushed to us, we’ll do our AI stuff. Since the first instance has shut down and discarded state, we’ll need to store the first contact payload to resume it when we have the token on second run!

  • Storing Tokens - Since our app is stateless, once we receive the token and run, the lambda shuts off and we lose the token. If we store it for next run, users don’t need to provide a token on each run!

We’ll go over this in more depth as we walk through the code.

There’s a lot going on here!!

If you don’t care about the walk-through, and would rather just skip to the codebase, we’ll be walking through this Receiver lambda code:

github.com/KyMidd/TeamsAIBot/blob/master/lambda/src/receiver.py

We’ll have one lambda handle several different logic paths:

  • Teams event inbound, we don’t have a token (or token is expired)

    • Build ā€œCardā€, push to user

    • Store Conversations for pickup when token received

    • Direct them to SSO so they can authorize an OAuth2 token for us

  • Teams event inbound, we have a token

    • Build payload, pass to Worker

  • OAuth2 token inbound

    • Store token

    • Find resumed Conversation and build payload around it

    • Pass to Worker

Lets talk about the first one first (as it should be)

Keep reading with a 7-day free trial

Subscribe to Let's Do DevOps to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
Ā© 2025 Kyler Middleton
Privacy āˆ™ Terms āˆ™ Collection notice
Start writingGet the app
Substack is the home for great culture

Share