Custom Connectors Archives - Aric Levin's Digital Transformation Blog http://aric.isite.dev/tag/custom-connectors/ Microsoft Dynamics 365, Power Platform and Azure Wed, 11 May 2022 08:40:20 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.3 Update Data in your CDS using Azure SQL Server, Azure Functions or Connectors from SQL Data http://aric.isite.dev/dynamics/post/cds-azuresql-azurefunc-connector/ Mon, 14 Sep 2020 00:30:00 +0000 https://aric.isite.dev/index.php/2020/09/14/update-data-in-your-cds-using-azure-sql-server-azure-functions-or-connectors-from-sql-data/ Recently, while working on a project that needed to update the Exchange rates in CDS, I was tasked at finding a solution that would be able to retrieve data from a SQL Server hosted on an Azure Virtual Machine. There were so many different approaches, and security was the main one, but I decided to do a deep dive and testing out how Power Automate will be able to accommodate these requests.

The post Update Data in your CDS using Azure SQL Server, Azure Functions or Connectors from SQL Data appeared first on Aric Levin's Digital Transformation Blog.

]]>
Recently, while working on a project that needed to update the Exchange rates in CDS, I was tasked at finding a solution that would be able to retrieve data from a SQL Server hosted on an Azure Virtual Machine. There were so many different approaches, and security was the main one, but I decided to do a deep dive and testing out how Power Automate will be able to accommodate these requests.

The first thing of course was the creation of the SQL Server database and add the data to it. I created a table in SQL Server that would be updated on a regular basis containing the Exchange Rates that I needed. For the purpose of this post, I used Azure SQL Server, and not a managed instance or a SQL Server hosted on Azure. The image below show the table and values that were added to the SQL Server database.

Exchange Rates Solution - SQL DB Design

You can see in the image that we store the Exchange Rate Code, The Exchange Rate Date (in Date format and string format) and the Exchange Rate value on that particular date.

Next, I created an entity in CDS to store that information. I called the new entity Transaction, and added fields of the Transaction Amount, Exchange Rate and the Transaction Amount in US Dollars. When adding a new record to the Transaction table we will only add the Currency and the Transaction Amount.

The first test that was to be performed was to create a Power Automate flow, that would get triggered on the creation of a new Transaction record, retrieve the Code Name of the currency, and then call Azure SQL Server (using Username and Password connection), to get the rows that correspond to the query that we provided.

I then initialized a CurrentDate variable that would contain today’s today in the format of the Date String that I created in the database. The formula for that date was:
formatDateTime(utcNow(), ‘yyyyMMdd’)

I used the Get rows (V2) action, adding a Filter Query which would specify a condition where the Exchange Rate Code is the code I previously retrieved and the Date is the current date, which was set in the previous step. The Select Query would return the value of the Exchange Rate value that I needed.

The image below shows the steps to get here.

Exchange Rate Solution - Power Automate Flow #1

Next, although I know I will have a single result, I still did an Apply to Each as I used the Get Rows for my SQL Server connection. I add the value property to the Apply to each action, and then add a Compose Step to calculate the amount in US dollars. The calculation here is slightly more complex, but still considerably easy if you know the names of your actions and items. This uses the mul to multiple two values, and conversion of each of the values to float to allow this multiplication to happen.

mul(float(items(‘Apply_to_each_3’)?[‘ExRateValue’]), float(triggerOutputs()?[‘body/nyc_transactionamount’]))

The final step here is to update the Transaction record and passing the ExchangeRateValue from the SQL query results and the Transaction Amount in US dollars. The image below shows the logic that is built in the Apply to each section.

Exchange Rate Solution - Power Automate Flow #2

Next we save the flow, and we need to test this logic. In order to test this, we navigate to our Model-driven app, and provide the Currency and the Transaction amount, as shown in the below image. As the flow was created to trigger on create of a new transaction record or update of the total amount, this will execute. The image below shows the information that was entered in the record before the flow executed. You will notice that the transaction number, transaction exchange rate and transaction amount (USD) are left empty.

Exchange Rates Solution - New Transaction record (CDS)

You can wait approximately 5-10 seconds and then be able to see the results in the flow as shown below:

Exchange Rates Solution - Completed Transaction record (CDS)

Now that we saw that we could do this by connecting to SQL Server directly, I was going to test a few other alternatives. I created an Azure function that would connect to the SQL Server and retrieve the same value for me. The main purpose is that this Azure function would be available across the board, even if you did not have access to SQL Server. You will need to add the System.Data.SqlClient nuget package to your Azure function project and to the header of your file. Your function code will expect two values as part of a query string, the currency code and the formatted date. The code is not fully optimized, but you can see the code below:

Exchange Rate Solution - Azure Api function (Code)

Now that we created the Azure function, let’s take a look at how the modified Power Automate flow will look like. The trigger and the first three action will be the same. Instead of the Get Rows, we would have an HTTP request, and we would pass the formatted URL, containing the code and the date parameters that we need to pass to the Azure function. We would use a compose action, similarly to what we did before to multiply the result from the Azure function (Exchange Rate) and the total amount of the base currency: mul(float(body(‘HTTP’)), float(triggerOutputs()?[‘body/nyc_transactionamount’]))

Finally we would update the record in CDS with the values of the Exchange Rate and the result of the multiplication. The image below shows the final flow:

Exchange Rate Solution - Power Automate flow calling Azure Api function

I ran the same tests in CDS and the results were the same, only using an API, so that it could be called from anywhere.

Now that I saw that this works, I wanted to add another option to this. I build a custom connector that would call the Azure API, so that it could be accessed directly from flow. This worked nice as well. The image below shows the test that I ran within the connector builder, and can be added to the Power Automate flow easily.

Exchange Rate Solution - Custom Connector

Although this entire process is doable, and somewhat cumbersome as you have to update your Exchange Rates on a daily basis and make sure that the data in your database is synched, there are APIs that are available for use that will allow you to just call a custom API and retrieve the data that you are looking for.

One of these solutions is called XE Currency Data, and for $800/year you can get 10,000 API requests per month. Additional requests are available of course at a higher price. I have not reviewed other vendors of a similar api, but this seems to be something that should be readily available and maybe even available for free for smaller request numbers.

The post Update Data in your CDS using Azure SQL Server, Azure Functions or Connectors from SQL Data appeared first on Aric Levin's Digital Transformation Blog.

]]>
The Road to modern Virus Scanning http://aric.isite.dev/azure/post/road-virus-scan/ Thu, 02 Jul 2020 05:34:00 +0000 https://aric.isite.dev/index.php/2020/07/02/the-road-to-modern-virus-scanning/ I have been working in the Government space for a few years now, and most implementations of the Dynamics and Azure tenants and environments are hosted in the Government Cloud. This means that there are a lot of restrictions that we have to deal with, not only from Microsoft but also from the internal IT policies.

The post The Road to modern Virus Scanning appeared first on Aric Levin's Digital Transformation Blog.

]]>
I have been working in the Government space for a few years now, and most implementations of the Dynamics and Azure tenants and environments are hosted in the Government Cloud. This means that there are a lot of restrictions that we have to deal with, not only from Microsoft but also from the internal IT policies.

A few years back we launched our first Dynamics application where one of the requirements was the ability to scan files that were uploaded by end users, whether from the Dynamics application or from Dynamics Portals. These documents would be uploaded to an Azure Blob Storage Container, and as they were uploaded copies to a separate quarantine container until they would be scanned.

At the time our options for a Virus Scan solution were limited. We had an On-Premise Virus Scanning McAffee appliance that was available to us, and we ended up with a solution that would check every few minutes if there were pending quarantined uploads, we would scan them and then move them from the quarantine container back to the clean container.

The below diagram is the high level solution that was implemented.

Virus Scanning Solution - Scheduled Run

This solution worked fine when the traffic was not high, but we did experience at time of high traffic that it would not complete processing the files in the allocated time, and needed a separate solution. The heavy traffic was mostly experienced in the last few months during the COVID-19 pandemic where the amount of applications that we received were substantial higher.

We needed to find a solution to have a quicker turnaround. We have used the Azure Service Bus in previous projects to pass information between our Dynamics environment and our On-Premise servers, so this should work. We would change the process to handle this in real time. As the file is uploaded to our Azure Storage Container, we would immediately fire the Azure Service Bus.

I have written a few posts about Azure Service Bus in the past, so if you are interested in that implementation, click here.

This solution would call the Azure Service Bus listener as soon as the file is uploaded and sent to the Virus Scanner. We could also bypass the need of the quarantine container immediately and only send it there after the Scan if the file was infected. The diagram below shows the new solution.

Virus Scan Solution - Real Time (Azure Service Bus)

As I mentioned that we are in GCC and there are a lot of limitations both from the list of available connectors and the implementations that can be done, but I wanted to address this as if it was done in a Commercial Cloud.

I noticed a couple of weeks ago that Microsoft announced the availability of a new Virus Scanner connector called Virus Total. I was not aware of other options but when I did some searching I encountered the availability of three connectors that have the capabilities of scanning documents (or document streams): Virus Total, Cloudmersive Virus Scan and Microsoft Defender ATP. This was great, it would simplify this logic.

Regardless of which Virus Scanner you are using, you will need to get an API key from the vendor of the Virus Scanning connector in order to establish a connector. Depending on your load of scanning the your cost can be free or cost you some money. I think most of these vendors offer about 4000 free scans a month.

If you are using Dynamics Portals or Power Apps Portals, you can upload your documents to either an Azure Blob Storage Container or SharePoint. The following flow executes when a new filter is uploaded to a SharePoint folder, scans the file for Virus and creates a CDS record with the Status of a Successful or Unsuccessful scan. Let’s review this step by step.

The first part is going to be our trigger. When a new document is uploaded to SharePoint (or Azure Blob) the flow will be triggered to get the content of that document. In case of SharePoint, the single step will provide us with the Content of the Document. If using Azure Blob, we will need an additional step to get the content of the blob based on the path of the file.

Virus Scan Solutiion - Power Automate Trigger (SharePoint or Azure Blob)

Next, we will call the Scan file for Viruses. In this case we used the action from Cloudmersive, but any of the connectors should work just fine for this.

Virus Scan Solution - Scanning via ISV Connector

After the scanning is complete we will add a condition to our flow that looks for the result from the Scan. The CleanResult will return True if there are no Viruses and False otherwise. We can then determine what action we want to do. Delete the file, move to quarantine container or folder, write a record, etc… Your choice. In our case I just wrote it to CDS.

Virus Scan Solution - Post Scanning

That is basically it. You can add additional logic as you see needed, but this is all it takes. Again if you are in Government Cloud or your IT is blocking certain connectors this might not be the solution for you, but if you are able to implement this, it might save you a lot of trouble and headaches.

The post The Road to modern Virus Scanning appeared first on Aric Levin's Digital Transformation Blog.

]]>
Eventbrite to CDS Integration – Part 2 (Eventbrite Settings) http://aric.isite.dev/flow/post/eb-cds-integration-ii/ Sun, 29 Dec 2019 23:30:00 +0000 https://aric.isite.dev/index.php/2019/12/29/eventbrite-to-cds-integration-part-2-eventbrite-settings/ In the second post will concentrate on the configuration of Eventbrite. We assume that you have already an Eventbrite account and you can create your own events. If you don’t have an Eventbrite account yet, this is the time to create one. You only need an email address and to set a password in order to create an Eventbrite account. Eventbrite is available as a free or paid service. Everything in this series of posts was done using the free Eventbrite account.

The post Eventbrite to CDS Integration – Part 2 (Eventbrite Settings) appeared first on Aric Levin's Digital Transformation Blog.

]]>
In the second post will concentrate on the configuration of Eventbrite. We assume that you have already an Eventbrite account and you can create your own events. If you don’t have an Eventbrite account yet, this is the time to create one. You only need an email address and to set a password in order to create an Eventbrite account. Eventbrite is available as a free or paid service. Everything in this series of posts was done using the free Eventbrite account.

Once you have created your account and are logged onto Eventbrite, on the top banner, click on the arrow next to the profile picture and select Account Settings.

Eventbrite Integration - EB Account Settings

This will load the Account Settings page. At the bottom of the Account Settings navigation, there are two items available under Developer Links API Keys and Webhooks. We will first configure an API key.

Click on the Create API Key button. A new form will pop ask asking for contact information, application Url, oAuth Redirect URI, Application Name and Description. Enter the details for your application. Once this information has been entered, you will see the name API Key details under the API Key

Eventbrite Integration - API Keys

Copy the data from the Api Screen. You will need it for later in the process. You can always come back to Eventbrite account settings and copy these values again.

The next thing that we need to do is Add two Webhooks. The first is for the Event creation and the second is for the Attendee registration. Based on the way that you configure Eventbrite and the type of events that you have, you might want to configure additional webhooks. In order to add a Webhook, we need to provide a Payload URL. Since we are going to use flows (Microsoft Power Automate) to receive the HTTP requests, we need to create those first and get the Url addresses from them, which is what we did in the previous section.

Events Webhook:

Eventbrite Integration - Event Webhook

Attendees Webhook:

Eventbrite Integration - Attendee Webhooks

1 – PREREQUISITES | 2 – EVENTBRITE SETTINGS | 3 – CUSTOM CONNECTOR | 4 – EVENT FLOW | 5 – ATTENDEE FLOW | 6 – TESTING

The post Eventbrite to CDS Integration – Part 2 (Eventbrite Settings) appeared first on Aric Levin's Digital Transformation Blog.

]]>
Eventbrite to CDS Integration – Part 3 (Custom Connector) http://aric.isite.dev/flow/post/eb-cds-integration-iii/ Sun, 29 Dec 2019 23:30:00 +0000 https://aric.isite.dev/index.php/2019/12/29/eventbrite-to-cds-integration-part-3-custom-connector/ In the third post will create our custom connector in order to connect with Eventbrite. The custom connector will allow us to call the Eventbrite api to retrieve the required information about the Events and the Attendees that have not been provided by the Webhook.

The post Eventbrite to CDS Integration – Part 3 (Custom Connector) appeared first on Aric Levin's Digital Transformation Blog.

]]>
In the third post will create our custom connector in order to connect with Eventbrite. The custom connector will allow us to call the Eventbrite api to retrieve the required information about the Events and the Attendees that have not been provided by the Webhook.

Inside of your Power Apps solution, click on the New button on the command bar, select Other and then Choose Custom Connector. In the Custom Connector page, upload an image for use with the connector, specify a background color (if you would like), enter a description and specify the host and base url of the host.

The Host url is www.eventbriteapi.com, and the base url is /v3/.

Eventbrite Integration - Custom Connector General Tab

On the security tab, select API Key as the method of authentication. This will pull up the API key dialog where you will enter the parameters for the API key. Enter API Key in the Parameter label, and Authorization in the Parameter name. The parameter location should stay as Header.

Eventbrite Integration - Custom Connector Security Tab (Api Key Authentication)
Click on the Definition step to continue. We will need to specify two Actions for the Definition. The first action is to get the event information and the second action is to get the attendee information. On the left hand side of the screen click on the New Action link to add the first action. The table below shows the values for each of the properties for the new Action Link:

Field Name Value
Summary Retrieve Event
Description Retrieve Event Information from Eventbrite
Operation ID RetrieveEvent
Visibility none
Verb GET
URL https://www.eventbriteapi.com/v3/events/{event_id}/
Query
Headers
Body
Response 200

Eventbrite Integration - Custom Connector Retrieve Event Definition

Field Name Value
Summary Retrieve Event
Description Retrieve Event Information from Eventbrite
Operation ID RetrieveEvent
Visibility none
Verb GET
URL https://www.eventbriteapi.com/v3/events/{event_id}/attendees/{attendee_id}/
Query
Headers
Body
Response 200

Eventbrite Integration - Custom Connector Retrieve Attendee Definition

You can now Save your Custom Connector.

1 – PREREQUISITES | 2 – EVENTBRITE SETTINGS | 3 – CUSTOM CONNECTOR | 4 – EVENT FLOW | 5 – ATTENDEE FLOW | 6 – TESTING

The post Eventbrite to CDS Integration – Part 3 (Custom Connector) appeared first on Aric Levin's Digital Transformation Blog.

]]>
Eventbrite to CDS Integration – Part 4 (Event Flow) http://aric.isite.dev/flow/post/eb-cds-integration-iv/ Sun, 29 Dec 2019 23:30:00 +0000 https://aric.isite.dev/index.php/2019/12/29/eventbrite-to-cds-integration-part-4-event-flow/ In this fourth post we will update the original flow that we created for when a new event is created in Eventbrite. The flow should have a couple of steps as the baseline. The steps include When a HTTP request is received, and the Initialize Variable action.

The post Eventbrite to CDS Integration – Part 4 (Event Flow) appeared first on Aric Levin's Digital Transformation Blog.

]]>
In this fourth post we will update the original flow that we created for when a new event is created in Eventbrite. The flow should have a couple of steps as the baseline. The steps include When a HTTP request is received, and the Initialize Variable action.

When the Webhook calls the flow, there are certain values that are being passed. One of those values is the action that is being performed (under the config section of the json file).

In our Initialize Variable action, we previously specified the following Action: Action Type, of type String. We did not specify the Value, which we left for now. The value should be as follows (based on the json schema that we provided):

first(split(triggerBody()?[‘config’]?[‘action’],’.’))

Eventbrite Integration - Event Flow Initialize Variable Action Type

The next action will allow us to get the Event Number. We need this number to verify if the Event already exists in our CDS environment and we need to update it, or if we need to create a new event in our environment. This action will also be an Initialize Variable action as shown in the image below.

Eventbrite Integration - Event Flow Initialize Variable Event Number

The value of the Initialize Variable action is: last(take(split(triggerBody()?[‘api_url’],’/’),6)), which will return the event number from the api url.

We now need to verify if the action type corresponds to an event. We will add a condition action that will compare the action type to “event”. If the result will be valid, we will retrieve additional data from the event by calling the custom connector, or terminate the flow if the result is not valid.

Eventbrite Integration - Event Flow Condition Action Type = Event?
If the results from the condition action is No (not valid), we terminate the flow with a status of cancelled. I the results from the condition action is Yes (valid) we will perform a few additional steps which include:

  • Retrieve Event (from Custom Connector)
  • List Events (to check if I already have an event)
  • Condition to check if I have existing Events
    • If yes, Update event
    • If no, Create new event

Eventbrite Integration - Event Flow Condition Results

The Retrieve Event action, calls the custom connector and expects a single string variable containing the event id that we want to retrieve. The Event Number has been provided for the Initialize Variable action prior to the conditions.

Eventbrite Integration - Event Flow Custom Connector Retrieve Event

You will need to make sure that you specify the Api Key to your custom connector before the follow can execute. When you Edit the connection and the Api key prompt shows up, make sure that you enter Bearer before the Api key. For example, if your Private Token (API key) in Eventbrite is ICE1MDAC3YBZKOAIDS1W then you will have to enter Bearer ICE1MDAC3YBZKOAIDS1W in the popup window.

Eventbrite Integration - Custom Connector Authentication Key

Next we retrieve any events from CDS that already have this Event Number. We can retrieve this done by using a Filter Query or a Fetch Xml Query in the List Records action of the Common Data Service (Current Environment) connector. For our purpose we used the Filter Query, but the Fetch Xml can be used as well.

Eventbrite Integration - Event Flow List Events

We can now add a condition to check if an event exists with that number by checking the length of the results from the List Events action: length(body(‘List_Events’)?[‘value’])

Eventbrite Integration - List Events Condition

The results of the condition are simple. If it does exist, we call an Apply to each that will update all the records (there should be only one), and if it does not exist we create a new event record. You will notice in the screenshots below we use the results from the Retrieve Event from the custom connector and use those parameters in our Create and Update actions.

Eventbrite Integration - List Event Condition Results (Yes/No)

1 – PREREQUISITES | 2 – EVENTBRITE SETTINGS | 3 – CUSTOM CONNECTOR | 4 – EVENT FLOW | 5 – ATTENDEE FLOW | 6 – TESTING

The post Eventbrite to CDS Integration – Part 4 (Event Flow) appeared first on Aric Levin's Digital Transformation Blog.

]]>
Eventbrite to CDS Integration – Part 5 (Attendee Flow) http://aric.isite.dev/flow/post/eb-cds-integration-v/ Sun, 29 Dec 2019 23:30:00 +0000 https://aric.isite.dev/index.php/2019/12/29/eventbrite-to-cds-integration-part-5-attendee-flow/ In this fifth post we will update the original flow that we created for when a new attendee is registered in Eventbrite. Your flow should have a couple of steps as the baseline. The steps include When a HTTP request is received, and the Initialize Variable action.

The post Eventbrite to CDS Integration – Part 5 (Attendee Flow) appeared first on Aric Levin's Digital Transformation Blog.

]]>
In this fifth post we will update the original flow that we created for when a new attendee is registered in Eventbrite. Your flow should have a couple of steps as the baseline. The steps include When a HTTP request is received, and the Initialize Variable action.

When the Webhook calls the flow, there are certain values that are being passed. One of those values is the action that is being performed (under the config section of the json file). We start by initializing the variables based on the data that is provided from the HTTP Request. The three variables that we are able to initialize are the Action Type, Event Number and Attendee Number (as shown below):

Eventbrite Integration - Attendee Flow Initialize Variables 1

The following tables shows the values of the three variables that we initialized:

Variable Name

Value

Action Type

first(split(triggerBody()?[‘config’]?[‘action’],’.’))

Event Number

first(split(last(split(triggerBody()?[‘api_url’],’events/’)),’/’))

Attendee Number

first(split(last(split(triggerBody()?[‘api_url’],’attendees/’)),’/’))

We next initialize the Event Id and Contact Id variables. These variables do not have a value at this point, and they are retrieved from the Common Data Service connector when looking for matching events and attendees.

Eventbrite Integration - Attendee Flow Initialize Variables 2

The next step is to validate the action type and make sure that the action type is Attendee. Since this flow is only called from the webhook directly, we probably can bypass this, but this is still good practice.

Eventbrite Integration - Attendee Flow Condition Validate Action Type is Attendee

The no condition will just terminate the flow, while the yes condition will go through the steps of retrieving the attendee information from Eventbrite, and retrieving any attendees that match the attendee number from CDS. We then call an additional condition action to check for the number of results from the retrieval of contact records from CDS. The flow looks like this:

Eventbrite Integration - Attendee Flow Condition Action Type = Attendee Results

The condition expression to check for the number of results is: length(body(‘Retrieve_contacts_matching_Attendee_Number’)?[‘value’])

The results of this condition will determine if we update the existing Contact record or create a new contact record. The yes condition result will call the Update Contact, while the no condition result will retrieve the eventid, and create a new attendee (contact) record.

Eventbrite Integration - Attendee Flow - Has Attendee = Yes

Eventbrite Integration - Attendee Flow - Has Attendee = No

1 – PREREQUISITES | 2 – EVENTBRITE SETTINGS | 3 – CUSTOM CONNECTOR | 4 – EVENT FLOW | 5 – ATTENDEE FLOW | 6 – TESTING

The post Eventbrite to CDS Integration – Part 5 (Attendee Flow) appeared first on Aric Levin's Digital Transformation Blog.

]]>