SampleApp-Webhooks-DotNet for Oauth1 app- Deprecated
This sample app is meant to provide working examples of how to integrate your app with the Intuit Small Business ecosystem. Specifically, this sample application demonstrates the following:
- Implementing webhooks endpoint to receive event notifications.
- Best practices to be followed while processing the event notifications.
- Sample code using QuickBooks Online SDK to call CDC API to sync data between the app and the QuickBooks Online company.
Please note that while these examples work, features not called out above are not intended to be taken and used in production business applications. In other words, this is not a seed project to be taken cart blanche and deployed to your production environment.
For example, certain concerns are not addressed at all in our samples (e.g. security, privacy, scalability). In our sample apps, we strive to strike a balance between clarity, maintainability, and performance where we can. However, clarity is ultimately the most important quality in a sample app.
Therefore there are certain instances where we might forgo a more complicated implementation (e.g. caching a frequently used value, robust error handling, more generic domain model structure) in favor of code that is easier to read. In that light, we welcome any feedback that makes our samples apps easier to learn from.
- Requirements
- [First Use Instructions](#First Use Instructions)
- [Running the code](#Running the code)
- [Project Structure](#Project Structure)
- [Reset the App](#Reset the app)
In order to successfully run this sample app you need a few things:
- Visual Studio 2015 with MVC5 and SQL server express 2012, .Net Framework 4.6.1
- A developer.intuit.com account
- An app on developer.intuit.com and the associated app token, consumer key, and consumer secret.
- QuickBooks .NET SDK (already included in the sample app). You need to update/restore it using Nuget Package Manager
- Two sandbox companies, connect both companies with your developer.intuit.com->QBO app and generate the oauth tokens using existing sample apps or OAuth Playground. (The tokens and app keys would be required for saving the tokens in the webhooks sample app and testing the notification for the sandbox company.)
- Fiddler
- Ngrok
- Azure subscription
- Clone/Download the GitHub repo to your computer
- Fill in the web.config with values (app token, consumer key, consumer secret) by copying over from the keys section for your app.
- Also add webhooks subscribed entities in comma separated format(WebhooksEntities) and webhooks verifier token that was generated when you subscribed for webhoooks event.
- Enable logging in the config file by updating the local folder path in web.config(ServiceRequestLoggingLocation).
- Open the project from Visual Studio
- Populate the data in to tables from /Scripts folder after modifying the values for your sandbox companies’ realmid, some default datetime, access token, access token secret, daatasource as QBO. Run it only once.
For webhooks, it is a requirement that your subscribe curl should be exposed over internet. It can be a rest endpoint or an azure app service. In the sample app we have, I will demonstrate both azure and localhost based testing for the webhooks. Once the sample app code is set on your computer, you can do the following steps to run the app:
For Ngrok based local testing of the sample app-
- Build the the project. Resolve any dll conflicts using Nuget Package Manager.
- Run the initial scripts for adding sandbox apptokens to the LocalDB->OAuthTokens table from Scripts->InsertScriptWebhooks.sql
- Download ‘ngrok.exe’ from https://ngrok.com/. This will help in mapping the localhost port of the sample app to the ngrok url exposed over internet.
- Run your sample app to see what port is displayed on the browser.
- Suppose it is running on https://localhost:49304/. After this, save this port information in a text file and then you need stop the sample app.
- Run ngrok.exe and then type the following cmd- ngrok http 49304 -host-header="localhost:49304" (Here my sample app’s port number was 49304. In your case it might be different. So change the values below in port to the value you have saved from step 3.) Generic cmd- ngrok http <> -host-header=”localhost:<>”
- Then you will get a mapping https url in the ngrok cmd prompt- Forwarding https://92832de0.ngrok.io -> localhost:49304 (Do not use the http url rather only https as only that supports webhooks)
- Copy the url https://92832de0.ngrok.io and paste it in browser and run it. You will get a bad gateway or some other error. Ignore it. Do not close the browser.
- Copy this same url https://92832de0.ngrok.io as the webhooks url for the app on developer.intuit.com and save.
- Now add a breakpoint point at the start of your sample app in HomeController.
- Then run the sample app and it will open localhost:49304 on a second tab of the browser.
- Close the localhost:49304 tab but the Visual Studio instance will keep running from IDE and the iis process will attach to https://92832de0.ngrok.io now.
- Do F10 for next 1 or 2 lines to make sure ngrok url is indeed attached to the iis process.
- Then remove the breakpoint and do F5(run).
- This is it. You are now exposing the sample app over internet via ngrok url.
- The WebHooks server can now send notifications to your sample app.
- You can download fiddler from google and run it alongside your sample app.
- Make some changes in the sandbox company you have.
- In about 5 mins, you can see fiddler logs the send a 200 response for the post on url https://92832de0.ngrok.io and there is also a CDC request and response logged.
- You can then go to the LocalDb table OAuthTokens in the sample app and right click and do Show Data or do a New query-> Select * from OAuthTokens. You will see the realmlastupdated date-time has changed to reflect the webhooks notifications received time.
- You can keep this ngrok.exe and https://92832de0.ngrok.io url running along with fiddler to track notifications are received after every 5 mins if there are changes as frequent.
For Azure based cloud testing of the sample app-
Note:You should have a valid Azure subscription to test this.
- Build the the project. Resolve any dll conflicts using Nuget Package Manager.
- Comment out the logging code in the DataServiceFactory.
//serviceContext.IppConfiguration.Logger.RequestLog.EnableRequestResponseLogging = true; //serviceContext.IppConfiguration.Logger.RequestLog.ServiceRequestLoggingLocation = ConfigurationManager.AppSettings["ServiceRequestLoggingLocation"];
- Build the project in release mode. Right click on the project. Do publish.
- Go to Profile->Select a publish target->Microsoft Azure App service->Enter your Azure creds->Select subscription and create a New resource group if you do not have any.
- The Hosting tab will then display your selected values.
- Then go to Services tab.
- Add a SQL Sever and DB for WebHooks.
- Then select Create button.
- This will start the publish process of the sample app to Azure.
- Add a Firewall rule to the SQL server on Azure for adding the IP of the computer from where you will be accessing the server.
- Then from left side go to ->Server explorer->Azure->SQL databases->Right click your DB ->SQL Server Object Explorer.
- Open the Webhooks Db that you just now created on Azure from SQL Server Object Explorer.
- Right click on Tables->Add new table and then run this script CREATE TABLE [dbo].[OAuthTokens] ( [Id] INT IDENTITY (1, 1) NOT NULL, [realmid] NVARCHAR (MAX) NOT NULL, [realmlastupdated] DATETIME NOT NULL, [access_token] NVARCHAR (MAX) NULL, [access_secret] NVARCHAR (MAX) NULL, [datasource] NVARCHAR (MAX) NULL, CONSTRAINT [PK_dbo.OAuthTokens] PRIMARY KEY CLUSTERED ([Id] ASC) );
- Do Update from Top menu. This will create the OAuthTokens table in Webhooks DB you created on Azure.
- Then go to Azure Portal->SQL DB->WebHooks Databse->Settings->Get Ado.net connection string for this DB.
- Go to the sample apps web.config. Change the LocalDB connectionstring to now map to Azure Webhooks DB. It should look something like this.
- Then save the sample app.
- Run the initial scripts for adding sandbox apptokens to the Webhooks Azure DB from Scripts->InsertScriptWebhooks.sql
- Then again save the sample app. Build it in debug and release mode.
- Again right click your project in solution explorer and publish again.
- Then your sample app will be hosted on cloud and the browser will run the sample app. Copy the cloud/azure app url.
- Configure the cloud app url in the webhooks app on developer.intuit.com and you should start getting notifications on the sample app.
- Make some changes in sandbox company and then go to the Webhooks Azure OAuthTokens in the sample app in SQL Server Object Explorer ->right click and do Show Data or do a New query-> Select * from OAuthTokens
- You will see updated realmlastupdatedtime.
- Note: By default, Azure already enables HTTPS for your app with a wildcard certificate for the *.azurewebsites.net domain. So, verify that https in indeed used for wbehooks.
Standard MVC5 template is used for the sample app
Controller-
- HomeController.cs (For receiving post of webhooks notifications from Intuit server)
Models-
DTO-
- OAuthTokensRealmLastUpdateddto.cs (Wrapper for OAuthTokens table data)
- WebhooksNotificationdto.cs (Wrapper for Webhooks Notifications from POST on the sample app’s url)
Service-
- DataServiceFactory.cs (For getting the ServiceContext object from App Keys and Tokens)
- CDCSyncService.cs (For making CDC calls to QBO API)
Utility-
- ProcessNotificationData.cs (For Signature Verification of Webhooks payload and a separate thread implementation for queue processing of the webhooks data and cdc api calls for the realms)
- DBUtility.cs (For making DB calls for OAuthTokens)
View-
- Index.cshtml (Displays default page for the Webhooks app)
You can always right click the LocalDB table or the Azure table from from SQL Server object explorer and run a new query- Delete from OAuthTokens - to delete the existing records and start afresh.