Pmd
Pmd

Reputation: 41

Getting 401, when trying to triggered power automate(Http triggered) flow from streamlit app

I have tried below code to triggered the power automate flow:

def get_access_token_powerAutomate():
    tenant_id = os.getenv("TENANT_ID")
    client_id = os.getenv("CLIENT_ID")
    client_secret = os.getenv("CLIENT_SECRET")
    scope = 'https://graph.microsoft.com/.default'
   
    url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
   
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
   
    body = {
        'grant_type': 'client_credentials',
        'client_id': client_id,
        'client_secret': client_secret,
        'scope': scope
    }
   
    response = requests.post(url, headers=headers, data=body)
   
    if response.status_code == 200:
        access_token = response.json().get('access_token')
        if not access_token:
            st.error("Access token not found in the response.")
            return None
        return access_token
    else:
        st.error("Failed to obtain access token.")
        st.error(f"Response status: {response.status_code}")
        st.error(f"Response content: {response.content}")
        return None
 
def power_automateflow(organizer_upn, attendee_upns, meeting_notes, selected_subject, transcript_date):
    access_token = get_access_token_powerAutomate()
    st.write("access_token",access_token)
    if not access_token:
        st.error("Access token retrieval failed.")
        return
   
    mail_subject = f" Notes of {selected_subject} on {transcript_date}"
    # Data to be sent
    transcript_data = {
        'organizer_upn': organizer_upn,
        'attendee_upns': attendee_upns,
        'meeting_notes': meeting_notes,
        'mail_subject': mail_subject
    }
 
    # Set the headers with the access token
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Content-Type': 'application/json'
    }
 
    # Power Automate flow endpoint URL
    power_automate_url = os.getenv("POWER_AUTOMATE_URL")
    if not power_automate_url:
        st.error("Power Automate URL is not set.")
        return
 
    # Making the POST request to Power Automate flow
    response = requests.post(power_automate_url, headers=headers, json=transcript_data)
 
    if response.status_code == 200:
        st.success("Meeting Notes sent successfully for organizer's approval!")
        st.success("Check your mail once they approve.")
    else:
        st.error(f"Failed to send Meeting Notes. Status code: {response.status_code}")
        st.error(f"Response content: {response.content}")

I have added below permissions in registered app:

enter image description here

getting below errors:

Failed to send Meeting Notes. Status code: 401 Response content: b'{"error":{"code":"SecurityTokenInvalidSignature","message":"The provided authentication token is not valid, token signature is not properly formatted."}}',

any help will be thankful.

I have try the above code , and wanted to resolved mention issue.

Upvotes: 1

Views: 1772

Answers (1)

Rukmini
Rukmini

Reputation: 16154

To trigger the power automate (Http triggered) flow from streamlit app, you need to give API permissions of Power automate API

  • While calling the Power automate API the aud must be https://service.flow.microsoft.com not Microsoft Graph API.

Create a Microsoft Entra ID application and add API permissions like below:

enter image description here

The 401 error usually occurs if the access token does not contain required API permissions to call the API.

To resolve the error, pass scope as https://service.flow.microsoft.com//.default

Modify the code like below:

def get_access_token_powerAutomate():
    tenant_id = os.getenv("TENANT_ID")
    client_id = os.getenv("CLIENT_ID")
    client_secret = os.getenv("CLIENT_SECRET")
    scope = 'https://service.flow.microsoft.com//.default'
   
    url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
   
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
   
    body = {
        'grant_type': 'client_credentials',
        'client_id': client_id,
        'client_secret': client_secret,
        'scope': scope
    }
   
    response = requests.post(url, headers=headers, data=body)
   
    if response.status_code == 200:
        access_token = response.json().get('access_token')
        if not access_token:
            st.error("Access token not found in the response.")
            return None
        return access_token
    else:
        st.error("Failed to obtain access token.")
        st.error(f"Response status: {response.status_code}")
        st.error(f"Response content: {response.content}")
        return None
 
def power_automateflow(organizer_upn, attendee_upns, meeting_notes, selected_subject, transcript_date):
    access_token = get_access_token_powerAutomate()
    st.write("access_token",access_token)
    if not access_token:
        st.error("Access token retrieval failed.")
        return
   
    mail_subject = f" Notes of {selected_subject} on {transcript_date}"
    # Data to be sent
    transcript_data = {
        'organizer_upn': organizer_upn,
        'attendee_upns': attendee_upns,
        'meeting_notes': meeting_notes,
        'mail_subject': mail_subject
    }
 
    # Set the headers with the access token
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Content-Type': 'application/json'
    }
 
    # Power Automate flow endpoint URL
    power_automate_url = os.getenv("POWER_AUTOMATE_URL")
    if not power_automate_url:
        st.error("Power Automate URL is not set.")
        return
 
    # Making the POST request to Power Automate flow
    response = requests.post(power_automate_url, headers=headers, json=transcript_data)
 
    if response.status_code == 200:
        st.success("Meeting Notes sent successfully for organizer's approval!")
        st.success("Check your mail once they approve.")
    else:
        st.error(f"Failed to send Meeting Notes. Status code: {response.status_code}")
        st.error(f"Response content: {response.content}")

After changing the scope, you will be able to trigger the power automate flow successfully.

Upvotes: 2

Related Questions