How to fix a 401 error received when executing the actions.run function in Pipedream for creating a draft in Gmail?

This topic was automatically generated from Slack. You can find the original thread here.

Hi Team,
I am trying to use tool calling to create draft in my gmail. Below is the snippet I am trying to use:

from pipedream import Pipedream
from infrastructure.config.settings import get_settings

def create_draft(user_email: str, to: str, subject: str, body: str):
    try:
        settings = get_settings()
        pipedream_client = Pipedream(
            client_id=settings.pipedream_client_id,
            client_secret=settings.pipedream_client_secret,
            project_environment=settings.pipedream_environment,
            project_id=settings.pipedream_project_id
        )
        accounts = pipedream_client.accounts.list()
        account = next((account for account in accounts if account.external_id == user_email), None)
        execute_tool_response = pipedream_client.actions.run(
            id="gmail-create-draft",
            external_user_id=user_email,
            configured_props={ "to": to, "subject": subject, "body": body, "from_email": user_email, "gmail": {
                "auth_provision_id": account.id
                } 
            },
        )
    except Exception as e:
        return str(e)
    return execute_tool_response

And here is the connected account screenshot:

But, when executing the actions.run, it’s giving me 401. By looking into the error message, it looks like that token it’s generated expires on “Mon, 01 Jan 1990 00:00:00 GMT”. Please help fixing the issue. Thanks in advance. ALso attaching the full error message json.

Hey ,

external_user_id=user_email,
Your external_user_id looks weird, the external user id usually be the uuid, for example

demo-39570d3e-7db3-43ed-8259-3faf1a6dec2c

hi ,
Thanks a lot for supporting me. But the issue is still not resolved. I am getting the same error. Here’s what changed.

  1. Changed the external user id to proper format:
  2. Changed the code to accommodate the above change:
def create_draft(user_email: str, to: str, subject: str, body: str):
    try:
        settings = get_settings()
        pipedream_client = Pipedream(
            client_id=settings.pipedream_client_id,
            client_secret=settings.pipedream_client_secret,
            project_environment=settings.pipedream_environment,
            project_id=settings.pipedream_project_id
        )
        accounts = pipedream_client.accounts.list()
        account = accounts.items[0]
        execute_tool_response = pipedream_client.actions.run(
            id="gmail-create-draft",
            external_user_id=account.external_id,
            configured_props={ "to": to, "subject": subject, "body": body, "from_email": user_email, "gmail": {
                "auth_provision_id": account.id
                }
            },
        )
    except Exception as e:
        return str(e)
    return execute_tool_response

Looping in @U02A06JPKEH as I reported the issue to him first.

Hey , my suggestion is that you can try to use Pipedream Connect with Pipedream Typescript SDK first to understand how it works first. Then you can switch to Python once you understand everything.

See the detailed demo here: https://pipedream-connect-demo.vercel.app/connect/demo

Thanks , to test the connect functionality do I have to test it all in the UI? Can I not add a user from nextjs UI and then invoke the tool as a python function? I am trying to highlight::

Why the token is having expiry in 1990? What can cause this? Is it a bug in python API?

PS: In the snippet I attached, pipedream_client.accounts.list() works. But, pipedream_client.actions.run gives me the error and the actions run is the python equivalent of what is found at: One SDK, thousands of API integrations
Few more pointers:

  1. I am in Pipedream free plan.
  2. If I need to upgrade to another plan, just to test out Pipedream will work form my usecase or not, what is the plan I need to go for?

I wonder if the connected account for Gmail is maybe not working, since it doesn’t sound like you’re getting a 401 from Pipedream, it sounds like the 401 is maybe coming from Gmail. Can you also try listing that account and checking account.healthy and account.dead for that Gmail account?

Thanks Danny, but I am currently using curl command to invoke the action and it works. Which proves no issue with my gmail/outlook account. I keep getting 401 when using python api only.

Can you show me your cURL command? Do other action executions work?

I have tried gmail and outlook find mail and create draft actions which work using curl but not using the python scripts: The details mentioned here: Slack

:eyes:

Interesting, I can reproduce your issue. I cannot however reproduce it across all actions, for example actions.run() works for me for google_sheets-list-worksheets, so I’m trying some other Gmail actions now

Hm actually it might’ve been an error with my env, it’s working end to end for me. Here’s my full code snippet:

import os
import json
from dotenv import load_dotenv
from pipedream import Pipedream

load_dotenv()

client = Pipedream(
  project_id=os.getenv("PIPEDREAM_PROJECT_ID"),
  project_environment=os.getenv("PIPEDREAM_ENVIRONMENT"),
  client_id=os.getenv("PIPEDREAM_CLIENT_ID"),
  client_secret=os.getenv("PIPEDREAM_CLIENT_SECRET"),
)

external_user_id = os.getenv("EXTERNAL_USER_ID")
account_id = os.getenv("ACCOUNT_ID")
configured_props = {
  "gmail": {
    "authProvisionId": account_id
  },
  "to": "[danny@pipedream.com](mailto:danny@pipedream.com)",
  "subject": "Hello, world!",
  "body": "This is a test"
}
payload = {
  "external_user_id": external_user_id,
  "id": "gmail-create-draft",
  "configured_props": configured_props
}

print("=== REQUEST PAYLOAD ===")
print(f"external_user_id: {external_user_id}")
print(f"payload: {json.dumps(payload, indent=2)}")
print("=====================\n")

response = client.actions.run(
  external_user_id=external_user_id,
  id="gmail-create-draft",
  configured_props=configured_props
)
print(json.dumps(response, indent=2, default=str))
(venv) ➜  python python actions.run.py
=== REQUEST PAYLOAD ===
external_user_id: abc-123
payload: {
  "external_user_id": "abc-123",
  "id": "gmail-create-draft",
  "configured_props": {
    "gmail": {
      "authProvisionId": "apn_WYhze96"
    },
    "to": "[danny@pipedream.com](mailto:danny@pipedream.com)",
    "subject": "Hello, world!",
    "body": "This is a test"
  }
}
=====================

"exports={'$summary': 'Successfully created a draft message'} os=[] ret={'id': 'r-5701578632676129437', 'message': {'id': '19912f4aea3afeda', 'threadId': '19912f4aea3afeda', 'labelIds': ['DRAFT']}} stash_id=None t={'br': 1756959648596, 'bp': 1756959648596, 'bls': 1756959648596, 'ble': 1756959649498}"

I really started working. Ur example and my example both are working !!

Weird, no changes on your end?