iPaaS Lansweeper Custom GraphQL help

Hi Everyone,

I have been asked to pull some Lansweeper Asset details into TDx using iPaaS. I have been able to configure the Lansweeper prebuilt connector and I have created a flow that authenticates using the Oauth2 protocol, pulls back the site data, then starts a loop that will load a table in iPaaS with the general asset information. This information includes the primary key for the asset.

This is where I got stuck. I figured it would be as simple as copying one of the standard actions from the pre-built Lansweeper connector, finding the body of the request, and changing the query to get the information I am looking for, though I have not been able to find any part of an action that contains any graphQL.

I created an API key that generated a personal access token so I could write the graphQL since iPasS lets us import Postman collections. The request is successful in Postman using my personal access token, but when I import it into TDx it fails.

I have tried building a fresh custom action and importing the postman collection, copying a standard action and manually finding the graphQL location so I can copy/paste my query, and importing my postman collection into the action of the pre-built Lansweeper connector.

At the same time, one thing that sticks out to me is the way the endpoints in the prebuilt actions end. Almost all of them end with a {TDXACTION:x} where x is a number, for example:

/api/v2/graphql{TDXACTION:0}

Is this ending anything that I should worry about (perhaps it is a TDx variable that holds the missing part of the body of the request?)

Does anyone have any advice or links that may help me build my custom graphQL query as a custom action in a prebuilt connector?

Thanks,

Bryan

Asked by William Hancock on Fri 12/13/24 5:56 PM
Sign In to leave feedback or contribute an answer

Answers (5)

William Hancock Mon 12/16/24 7:02 PM

Since this is a community post, I wanted to leave a solution for this question. While I have tested it with the prebuilt Lansweeper API, I am pretty sure that it will work with any prebuilt connector that supports graphQL assuming that at least one prebuilt action is aiming at the correct endpoint for the API's graphQL server.

Tested and Working Solution:

The assumption is that you have tested the prebuilt connector from a flow in IpaaS and it is working, and now you want to create a custom query. The solution also assumes that you can copy at least 1 action from the prebuilt connector that requires authentication and is running a graphQL query. In the case of Lansweeper, we know that the Get Assets action is using graphQL based on the documentation, and we also know that asset data can only be queried by authorized applications (so authentication is completed for this query).

In connector area click on the Data Types option in left hand vertical menu

    - from main Data Types screen, click on green arrow to the right of Add (in upper right) and select Object from dropdown

        - The Add X (X = Options in this case) Data Type screen opens:

            - Fill in Name field

            - In the lower right Data Type area, select String in the dropdown

           - then click green Add property button to open new screen: Add Y (Y =  String in this case) Property

                - Name the property: query

                - Label the property: Query

                - feel free to create an example or a default value, though these fields are not necessary

                - click Add New at the bottom of the Add Y Property screen to save property and return to the previous screen

            - click Add New at the bottom of the Add X Data Type screen to save and retur to the Data Types main screen in IpaaS

Now we can copy a standard action and modify it to handle our custom queries:

     - In main connector screen click on the Actions option in left hand vertical menu

    - from main Actions screen, click on green arrow to the right of Add (in upper right) and select Copy Standard Actions

    - pick an action you know uses graphQL (check box must be checked), then click Next on bottom right of Standard Action selection screen

    - review your selection, then click on the Copy Standard Actions button on bottom right to return to main actions screen

    - click the name of the action you copied to open edit action screen

        - change name

        - Select the data type you just created for the Request Body Data Type from the drop down

        - click update to return to actions screen

        - click the test tube (between the check box item and the drop down arrow on the left of the action name) of the action you just edited.

        - a flow is opened and contains a single blank property (variable). You will need to paste in your graphQL query here

        - select the credentials you used to test the standard options

        - select the environment if you are using one

        - paste in your graphQL query:

            - lansweeper example below, you must include the opening and closing {} and supply your own site ID and asset key before this test will work correctly:

                {
                  site(id: "your_site_id_goes_here")
                  {
                    assetDetails(key:"your_asset_id_goes_here")
                    {
                      assetBasicInfo
                      {
                        assetUnique
                        cloudCategory
                        cloudEnvId
                        cloudEnvName
                        cloudOrgId
                        cloudOrgName
                        cloudProvider
                        cloudRegion
                        description
                        domain
                        firstSeen
                        fqdn
                        ipAddress
                        lastActiveScan
                        lastChanged
                        lastIpScan
                        lastLsAgent
                        lastLsFallBack
                        lastLsPush
                        lastPerformanceScan
                        lastSccmScan
                        lastScheduled
                        lastSeen
                        lastTried
                        lastTriggered
                        lastWorkGroupScan
                        lsAgentVersion
                        lsPushVersion
                        mac
                        name
                        origin
                        scannerType
                        scannerTypes
                        scanServer
                        sccmServer
                        subType
                        type
                        typeGroup
                        upTime
                        userDomain
                        userName
                      }

                      assetCustom
                      {
                        barCode
                        branchOffice
                        building
                        comment
                        contact
                        department
                        deviceVersion
                        dnsName
                        fields
                        {
                          fieldKey
                          name
                          value
                        }        
                        firmwareVersion
                        ftpHeader
                        hardwareVersion
                        httpServer
                        httpsServer
                        httpTitle
                        lastChanged
                        lastFullBackup
                        lastFullImage
                        lastPatched
                        location
                        manufacturer
                        model
                        orderNumber
                        purchaseDate
                        serialNumber
                        sku
                        softwareVersion
                        sshServer
                        stateName
                        warrantyDate      
                      }

                      assetGroups
                      {
                        assetGroupKey
                        dynamic
                        name
                      }


                    }
                  }
                }

 

     - Click Test button, the response should read: "HTTPResponseCode": "200: OK" if you were successful.

 

 

 

No feedback

William Hancock Mon 12/16/24 1:51 PM

Thanks Bennett,

I was able to copy/paste the body from my postman query into the text box for the query variable in the execute graphQL action and get an error free response.

I believe that I will be able to finish building a proof of concept flow to import the assets we need to import, and in looking at the difference between my postman imports and the execute graphQL method it seems that I misunderstood the import from postman option. I assumed it would import and recreate the postman operation in full, and my plan was to look for the graphQL query I built in the edit action UI to find what I needed to edit.

A few points of feedback:

  • Problem: The "copy standard action" function would have solved my issue from the start, except in the current implementation, it does not seem copy the action fully. I just tested to make sure I didn't miss something as obvious as the "request body data type" being selected in the prebuilt actions and not being included in my imported actions, and have confirmed that the request body is not copied.
  • Why it matters: I am coming from a technical side, where it is common practice to troubleshoot something by using a working example. Since I had confirmed that the prebuilt actions were working and we could now copy actions, I incorrectly assumed copying the action would provide an inside look at the differences in the working and broken actions.
  • Suggestion: have the action copy over in full, so that those of us who are curious can peel back the curtain and see exactly how the connectors are built. This should include any scripts that may be called by the action in the background or any other support systems.
  • Problem: Searching for "IpaaS connector scratch" did not provide the KB article referenced in this KB article: Creating and Requesting iPaaS Connectors (link: https://solutions.teamdynamix.com/TDClient/1965/Portal/KB/ArticleDet?ID=117970). The final topic in the linked article mentions that we should review that KB if we need to work on custom actions. I did look thorough 20 pages of search results and did not find this article, so it may not contain the name "scratch" in the title.
  • Solution: Add a link to this KB article. It could also be helpful to create a consolidated KB article that covers building a connector in a single article and addresses how each part of the connector relates to the others. I also think it could be beneficial to add a KB article that covers the copy standard action system.
  • Other Suggestion: It seems like graphQL is a very popular way to build API calls and get data, so it could be beneficial to create the "execute graphQL query" method to the standard actions when creating prebuilt connectors. Especially with something like Lansweeper or Active Directory, it seems likely that the prebuilt connectors will not be able to cover every use case, and this seems like it could be a good first step. A longer term design goal could be to create a query builder into that method, so that people can just copy/paste the fields they need and the json formatting would be handled behind the scenes.

Again, thanks for the help with this,

Bryan

No feedback
Hello Bryan,

Glad you are set here with a working call built with the LanSweeper documentation.

Regarding the first problem, I agree that it is strange to not see the GraphQL body come over as a data type. This is a relatively new feature, so I apologize for the issue! I would imagine that this is a bug in the system that our developers would love to hear about. Could I ask you to submit these notes as a bug ticket here: https://solutions.teamdynamix.com/TDNext/Apps/129/Tickets/New?formId=52622

We'll see if we can add some keywords to that article that will help improve your search results.

On the last suggestion, I would recommend that you submit the connector concierge form for this particular connector so that we can get to the appropriate party to request adding a GraphQL standard action. It's possible that our engineers have left that blank action out for the sake of keeping these sorts of connectors more simple while allowing advanced users to extend the connector.
- Bennett Forkner Mon 12/16/24 2:22 PM

William Hancock Mon 12/16/24 12:51 PM

Hi Carrie,

 

Here is the postman export, it is using a personal access token instead of the Oauth2 authorization which is used by the prebuilt connector. I replaced my api key, the site id, and the asset id. Also, I removed around 2,000 lines from the body of the actual graphQL query I built because I was not sure if there is a limitation on the text size a body can have in IpaaS.

 

Here is the postman export:

 

{
    "info": {
        "_postman_id": "63d7fecc-be9d-42a3-8078-5081db949f93",
        "name": "Lansweeper_test Copy",
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
        "_exporter_id": "39692380"
    },
    "item": [
        {
            "name": "New Request",
            "request": {
                "method": "POST",
                "header": [
                    {
                        "key": "Content-type",
                        "value": "application/json",
                        "type": "text"
                    },
                    {
                        "key": "Authorization",
                        "value": "Token my_personal_access_token",
                        "type": "text"
                    }
                ],
                "body": {
                    "mode": "graphql",
                    "graphql": {
                        "query": "{\r\n  site(id: \"my_site_id\") \r\n  {\r\n    assetDetails(key:\"my_asset_id\") \r\n    {\r\n      assetBasicInfo\r\n      {\r\n        assetUnique\r\n        cloudCategory\r\n        cloudEnvId\r\n        cloudEnvName\r\n        cloudOrgId\r\n        cloudOrgName\r\n        cloudProvider\r\n        cloudRegion\r\n        description\r\n        domain\r\n        firstSeen\r\n        fqdn\r\n        ipAddress\r\n        lastActiveScan\r\n        lastChanged\r\n        lastIpScan\r\n        lastLsAgent\r\n        lastLsFallBack\r\n        lastLsPush\r\n        lastPerformanceScan\r\n        lastSccmScan\r\n        lastScheduled\r\n        lastSeen\r\n        lastTried\r\n        lastTriggered\r\n        lastWorkGroupScan\r\n        lsAgentVersion\r\n        lsPushVersion\r\n        mac\r\n        name\r\n        origin\r\n        scannerType\r\n        scannerTypes\r\n        scanServer\r\n        sccmServer\r\n        subType\r\n        type\r\n        typeGroup\r\n        upTime\r\n        userDomain\r\n        userName\r\n      }\r\n\r\n      assetCustom\r\n      {\r\n        barCode\r\n        branchOffice\r\n        building\r\n        comment\r\n        contact\r\n        department\r\n        deviceVersion\r\n        dnsName\r\n        fields\r\n        {\r\n          fieldKey\r\n          name\r\n          value\r\n        }        \r\n        firmwareVersion\r\n        ftpHeader\r\n        hardwareVersion\r\n        httpServer\r\n        httpsServer\r\n        httpTitle\r\n        lastChanged\r\n        lastFullBackup\r\n        lastFullImage\r\n        lastPatched\r\n        location\r\n        manufacturer\r\n        model\r\n        orderNumber\r\n        purchaseDate\r\n        serialNumber\r\n        sku\r\n        softwareVersion\r\n        sshServer\r\n        stateName\r\n        warrantyDate      \r\n      }\r\n\r\n      assetGroups\r\n      {\r\n        assetGroupKey\r\n        dynamic\r\n        name\r\n      }\r\n\r\n\r\n    }\r\n  }\r\n}",
                        "variables": ""
                    }
                },
                "url": {
                    "raw": "https://api.lansweeper.com/api/v2/graphql",
                    "protocol": "https",
                    "host": [
                        "api",
                        "lansweeper",
                        "com"
                    ],
                    "path": [
                        "api",
                        "v2",
                        "graphql"
                    ]
                }
            },
            "response": []
        },
        {
            "name": "New Request Copy",
            "request": {
                "method": "POST",
                "header": [
                    {
                        "key": "Content-type",
                        "value": "application/json",
                        "type": "text"
                    },
                    {
                        "key": "Authorization",
                        "value": "Token my_personal_access_token",
                        "type": "text"
                    }
                ],
                "body": {
                    "mode": "graphql",
                    "graphql": {
                        "query": "{\r\n  site(id: \"my_site_id\") \r\n  {\r\n    assetDetails(key:\"my_asset_id\") \r\n    {\r\n\r\n      activeDirectoryGroups\r\n      {\r\n        description\r\n        name\r\n        type\r\n      }\r\n    }\r\n  }\r\n}",
                        "variables": ""
                    }
                },
                "url": {
                    "raw": "https://api.lansweeper.com/api/v2/graphql",
                    "protocol": "https",
                    "host": [
                        "api",
                        "lansweeper",
                        "com"
                    ],
                    "path": [
                        "api",
                        "v2",
                        "graphql"
                    ]
                }
            },
            "response": []
        }
    ]
}

 

 

 

 

No feedback

Bennett Forkner Mon 12/16/24 12:49 PM

Hello William,

We were actually able to look into your environment and find the connector definition that you were working with.

The LanSweeper API describes that you need to structure your query in the body of the connector definition like so:

{

        "query": "{ authorizedSites { sites { id name } } }"

}

See here for details on their end: https://developer.lansweeper.com/docs/data-api/guides/getting-data/​​​​​​​

I structured out a data type called "GraphQLBody" and set it up to mimic the above structure. Then I linked it to a new copy of your action called "Execute GraphQL" and tested it in a flow. That seemed to do the trick.

As for the question about the {TDXACTION:0} and such, that is just a way to keep the identifiers of each action unique, but it does not have any affect on the action itself.

Does that answer your question / work on your end?

Bennett Forkner

Consultant, Technical Services

TeamDynamix

No feedback

Carrie Willis Mon 12/16/24 12:36 PM

Hi William,

Can you share some more context of what specifically you're trying to do? You mentioned that you can get something to work in Postman, but not in iPaaS -- can you share the URL and any payload data (with anything sensitive removed, of course!) so that we can take a look?


Thank you,
Carrie Willis
Managing Consultant, Technical Services

No feedback