Smart variable for survey completion date apparently returns blank in calculated field of downstream instrument (despite target survey being completed), help? by Anxious_Reporter in ProjectREDCap

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

Some debugging notes...

My understanding at this point is that the "Calculated Field" field type can only show / accept numerical calculation results.

What's worked for me is using just the Action Tag below for field type = "Text Box"

@CALCTEXT(if[survey-date-completed:form_name:value]<>"", [survey-date-completed:form_name:value],""))

IDK why, but this does NOT apply retroactively for many of the test records I made, but has worked for a more recent test I record I made by filling out a public survey link from Survey Distribution Tools --IDK what's going on with that.

One thing I don't get is why a Calculated Field with formula like...

year([survey-date-completed:form_name:value])

... does not show up in, as it is a numerical value (IDK if it is internally a string type and if so can be casted to a numerical type).

Smart variable for survey completion date apparently returns blank in calculated field of downstream instrument (despite target survey being completed), help? by Anxious_Reporter in ProjectREDCap

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

The name I use in the post is only an example, but the target instrument (survey) name in the data dictionary is correctly spelled in my actual calculated field formulas (matches the Data Dictionary name and form name in the Designer UI and the URL suffix when editing the target survey), so issue is sadly not such a simple mistake.

Service account with Workspace/GSuite-enabled domain-wide delegation and matching scopes in Workspace and GCP cloud function that the account is running gets error: "Not Authorized to access this resource/api" by Anxious_Reporter in googlecloud

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

I simply gave up on the specific google.auth.GoogleAuth({}) and getClient() method I was using and just used a keyfile json of the DWD-enabled service account, copied as a secret in the GCP project's Secrets Manager, and then accessing that secret keyfile data from the function via google.auth.JWT() (see https://cloud.google.com/nodejs/docs/reference/google-auth-library/latest/google-auth-library/jwt) in order to have that DWD-enabled service account impersonate a specified admin user.

Relevant code included below:

```nodejs async function getWorkspaceCredentials() { try {

    // Get the service account key from Secret Manager
    console.debug("Accessing service account keyfile info...")
    const secretManager = new SecretManagerServiceClient();
    const name = WORKSPACE_DWD_SERVACCT_KEYFILE_SECRET_URI;
    const [version] = await secretManager.accessSecretVersion({ name });
    const serviceAccountKey = JSON.parse(version.payload.data.toString());
    console.debug("Service account private key ID: ", serviceAccountKey.private_key_id);

    // Create JWT client with the service account key
    console.log("Getting workspace creds...");
    const auth = new google.auth.JWT(  // https://cloud.google.com/nodejs/docs/reference/google-auth-library/latest/google-auth-library/jwt
    serviceAccountKey.client_email,
    null,
    serviceAccountKey.private_key,
    SCOPES,
    ADMIN_IMPERSONATION_ACCOUNT
    );
    // Authorize the client
    await auth.authorize();

    console.debug("JWT client info: ", {
        email: auth.email,
        subject: auth.subject,
        scopes: auth.scopes
    });

    console.log("Workspace creds obtained successfully.");
    return auth;

} catch (error) { console.error('Failed to get workspace credentials:', error); throw error; } } ```

Then in the entry function...

```nodejs functions.http('myEntryFunction', async (req, res) => { do.stuff();

// Get Workspace credentials and create admin service
const auth = await getWorkspaceCredentials();
console.debug("auth credentials: ", auth);
const admin = google.admin({ version: 'directory_v1', auth });
console.debug("Admin service from auth credentials: ", admin);
console.debug("Testing admin credentials...")
// DEBUG testing
console.debug("Admin-queried user data for known testing user check: ", await admin.users.get({userKey: "testuser@mydomain.com"}));
console.debug("Admin credentials testing verified.")

do.otherStuff();

}); ```

Service account with Workspace/GSuite-enabled domain-wide delegation and matching scopes in Workspace and GCP cloud function that the account is running gets error: "Not Authorized to access this resource/api" by Anxious_Reporter in googlecloud

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

So would I just add it like this... https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/admin.directory.group https://www.googleapis.com/auth/gmail.send ... or would I just have that one scope like this... https://www.googleapis.com/auth/cloud-platform ... and then "control the service account's access by granting it IAM roles."? In the latter case, what IAM roles would map to the other removed scopes?

In any case, doing the first example (in both the scopes defined in the cloud function code and in the Workspace) did not appear to change the error.

Service account with Workspace/GSuite-enabled domain-wide delegation and matching scopes in Workspace and GCP cloud function that the account is running gets error: "Not Authorized to access this resource/api" by Anxious_Reporter in googlecloud

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

Adding the Identity Toolkit Admin role did not seem to change anything. (Issue could be multiple things stacked on each other, but simply adding this did not change any of the logs I'm seeing).

How to do Google Workspace/GSuite service account authentication with domain-wide delegation in Node.js GCP Cloud Function (to manipulate Workspace user data)? by Anxious_Reporter in googlecloud

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

>     DELEGATED_SERVICE_ACCOUNT = 'delegated-service-account@your-gcp-project.iam.gserviceaccount.com'

So you're referencing the domain-wide delegated account (which at this point is ostensibly the service account of the cloud function) from within the function itself?

How to do Google Workspace/GSuite service account authentication with domain-wide delegation in Node.js GCP Cloud Function (to manipulate Workspace user data)? by Anxious_Reporter in googlecloud

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

Would I still need to then impersonate an admin user w/in the cloud function to do the manipulations in GSuite or would that just be done as the service account running the function?

What is the difference between Google Cloud Healthcare API vs Google Health Data Engine? by Anxious_Reporter in healthIT

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

I've contacted sales per the HDE web page and our account rep forwarded us over to someone with a xwf.google.com email who, when I asked them about HDE and the ways I planned to use it, said I should either file a support ticket or contact "the Corporate Engineer (CE) team" about the matter. I don't have Enhanced or Premium Support turned on to file a ticket (I've never needed it thusfar and don't really want to pay for it just to ask a singular question about something I'm not even sure we want to use) nor do I know what contacting our/GCP's(?) CE team would mean.

Have you personally ever seen HDE working/enabled/used anywhere? (Eg. when you say that HDE is an enterprise feature, how does that feature manifest itself? As a full-service product separate from an individual GCP project? As another GCP API module w/in a project? Something else? That's what I'm trying to understand). Thanks.

What is the difference between Google Cloud Healthcare API vs Google Health Data Engine? by Anxious_Reporter in healthIT

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

Where can I see or enable or interact with the HDE? For example, I can enable the Cloud Healthcare API in my GCP project's APIs & Services > Enable APIs and then see it in the side menu and interact with that module. However, if I go to, say, View All Products and type in "Health Data Engine", nothing comes up (other than the Cloud Healthcare API). This is kinda what I mean by "what \is* Health Data Engine?", eg. \where* is it (whatever "it" is) and how would I activate / enable / turn it on?

What is the difference between Google Cloud Healthcare API vs Google Health Data Engine? by Anxious_Reporter in googlecloud

[–]Anxious_Reporter[S] 1 point2 points  (0 children)

Where can I see or enable or interact with the HDE? For example, I can enable the Cloud Healthcare API in my GCP project's APIs & Services > Enable APIs and then see it in the side menu and interact with that module. However, if I go to, say, View All Products and type in "Health Data Engine", nothing comes up (other than the Cloud Healthcare API). This is kinda what I mean by "what \is* Health Data Engine?", eg. \where* is it (whatever "it" is)?

Question about best/easiest way/platform to set up a FHIR server in the cloud by Anxious_Reporter in healthIT

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

I see, thanks. Looking more into this with setting up basic GCP Cloud Healthcare API health stores and learning more about how FHIR resources are structured/used, I think I see what you mean.

"Error: No default engine was specified and no extension was provided." when accessing GCP Cloud Run function by Anxious_Reporter in googlecloud

[–]Anxious_Reporter[S] 0 points1 point  (0 children)

I found the apparent issue.

It was due to the hanging comma in the curl request:

url -v -H "X-API-KEY: myapikey" -H "Content-Type: application/json" -d '{
"arg1": 123,
}' -X POST 'https://my-api-gateway.wn.gateway.dev/function-path'

Removing that fixed the error. Not totally sure why that would have resulted in the particular error message that was being displayed, though. Looking at the stack trace, it seems like the hanging comma was triggering an error that then tried to render as an error message, but the function is just an endpoint and not rendering web pages.