Next

Empty.

Open the NuGet Package Manager

Add these

Make your project look like this. Add two classes (WebApiConfig and GitHubWebHookHandler) and Global.asax.
Add the Default page as a standard web page, and set it to 'set as default page'. This isn't really necessary, but it'll give the app a place to open to if you run it in the dev environment.

Web.config
Note: The code shown does not handle security, or this key, that's an additional complexity and we'll take that on later
<configuration>
<appSettings>
<add key="MS_WebHookReceiverSecret_GitHub" value="xxxxxxxxxxxx0c780e49a5c72972590571fd8" />
</appSettings>
<system.web>
Global.asax
Imports System.Web.Http
Imports System.Web.SessionState
Public Class Global_asax
Inherits System.Web.HttpApplication
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
'log the app opening
Dim logName = "Application"
Dim objEventLog As EventLog = New EventLog()
objEventLog.Source = logName
objEventLog.WriteEntry("global_asax", EventLogEntryType.Warning)
'this is a delegate, apparantly
System.Web.Http.GlobalConfiguration.Configure(AddressOf WebApiConfig.Register)
End Sub
End Class
WebApiConfig
Imports System
Imports System.IO
Imports System.Net
Imports System.Web
Imports System.Web.Http
Imports FPCommon
Module WebApiConfig
Sub Register(ByVal config As System.Web.Http.HttpConfiguration)
Dim strError As String = ""
Try
'this is called att app start from Global.asax
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
config.MapHttpAttributeRoutes()
config.Routes.MapHttpRoute(name:="DefaultApi", routeTemplate:="api/{controller}/{id}", defaults:=New With {Key .id = RouteParameter.[Optional]})
config.InitializeReceiveGitHubWebHooks()
Catch ex As Exception
ErrorHandler.globalErrorHandler(ex, strError, "vb", "sg", True)
End Try
End Sub
End Module
GitHubWebHookHandler
Imports System
Imports System.IO
Imports System.Net
Imports System.Threading.Tasks
Imports Microsoft.AspNet.WebHooks
Imports Newtonsoft.Json.Linq
Public Class GitHubWebHookHandler
Inherits WebHookHandler
Public Sub New()
Dim strError As String = ""
Try
Me.Receiver = Microsoft.AspNet.WebHooks.GitHubWebHookReceiver.ReceiverName
Dim strSubject As String = String.Format("GitHubWebHookHandler New {0:hh:mm:ss}", Now)
MailHandler.sendMail("credit@ngabrick.com", "steve@4penny.net", "", "", "webhook api notice", strSubject, MailHandler.ErrorHandlingTypeType.Ignore, "", "mail.ngabrick.com", False)
Catch ex As Exception
Throw ex
End Try
End Sub
Public Overrides Function ExecuteAsync(ByVal generator As String, ByVal context As WebHookHandlerContext) As Task
Dim strError As String = ""
Try
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
Dim entry As JObject = context.GetDataOrDefault(Of JObject)()
'"entry" is a JSON object, handle the incoming data here
Catch ex As Exception
Throw ex
End Try
Return Task.FromResult(True)
End Function
End Class
Now, go over to GitHub
Create a free account, if you need to
Add a repo, if you need to
Navigate to the repository
Click on Settings, then Webhooks

Fill this in as shown below. Your code needs to be public on the internet. It is possible to test without publishing to the internet... but that's a different article. Notice the 'secret' area. Github sends a 'secret' (they look like GUIDs) and the .NET app receives the secret and that way you know that someone is not spoofing you. This article does not handle the security, that's the next article.

You can set yourself up for as many notifications as you'd like, but it's quick and easy to set yourself up to receive 'stars'


This is the result. If you've coded all the above correctly, when you click the 'star' in Github you'll get the text below in the ExecuteAsync method. Find this line of code and handle the data. I didn't include it in the sample code because you won't want to do it my way. Recommend that you deserialize the JSON and then store it somehow in a database.
Dim entry As JObject = context.GetDataOrDefault(Of JObject)()
Resulting JSON
{
"action": "deleted",
"starred_at": null,
"repository": {
"id": 762457507,
"node_id": "R_kgDOLXItow",
"name": "Compare-Net-Objects",
"full_name": "sgray128/Compare-Net-Objects",
"private": false,
"owner": {
"login": "sgray128",
"id": 161059510,
"node_id": "U_kgDOCZmStg",
"avatar_url": "https://avatars.githubusercontent.com/u/161059510?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/sgray128",
"html_url": "https://github.com/sgray128",
"followers_url": "https://api.github.com/users/sgray128/followers",
"following_url": "https://api.github.com/users/sgray128/following{/other_user}",
"gists_url": "https://api.github.com/users/sgray128/gists{/gist_id}",
"starred_url": "https://api.github.com/users/sgray128/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/sgray128/subscriptions",
"organizations_url": "https://api.github.com/users/sgray128/orgs",
"repos_url": "https://api.github.com/users/sgray128/repos",
"events_url": "https://api.github.com/users/sgray128/events{/privacy}",
"received_events_url": "https://api.github.com/users/sgray128/received_events",
"type": "User",
"site_admin": false
},
"html_url": "https://github.com/sgray128/Compare-Net-Objects",
"description": null,
"fork": false,
"url": "https://api.github.com/repos/sgray128/Compare-Net-Objects",
"forks_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/forks",
"keys_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/teams",
"hooks_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/hooks",
"issue_events_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/issues/events{/number}",
"events_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/events",
"assignees_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/assignees{/user}",
"branches_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/branches{/branch}",
"tags_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/tags",
"blobs_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/statuses/{sha}",
"languages_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/languages",
"stargazers_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/stargazers",
"contributors_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/contributors",
"subscribers_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/subscribers",
"subscription_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/subscription",
"commits_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/contents/{+path}",
"compare_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/merges",
"archive_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/downloads",
"issues_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/issues{/number}",
"pulls_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/pulls{/number}",
"milestones_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/milestones{/number}",
"notifications_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/labels{/name}",
"releases_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/releases{/id}",
"deployments_url": "https://api.github.com/repos/sgray128/Compare-Net-Objects/deployments",
"created_at": "2024-02-23T20:28:33Z",
"updated_at": "2024-02-29T15:28:38Z",
"pushed_at": "2024-02-23T21:37:59Z",
"git_url": "git://github.com/sgray128/Compare-Net-Objects.git",
"ssh_url": "git@github.com:sgray128/Compare-Net-Objects.git",
"clone_url": "https://github.com/sgray128/Compare-Net-Objects.git",
"svn_url": "https://github.com/sgray128/Compare-Net-Objects",
"homepage": null,
"size": 11875,
"stargazers_count": 0,
"watchers_count": 0,
"language": "C#",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 0,
"license": {
"key": "ms-pl",
"name": "Microsoft Public License",
"spdx_id": "MS-PL",
"url": "https://api.github.com/licenses/ms-pl",
"node_id": "MDc6TGljZW5zZTE5"
},
"allow_forking": true,
"is_template": false,
"web_commit_signoff_required": false,
"topics": [],
"visibility": "public",
"forks": 0,
"open_issues": 0,
"watchers": 0,
"default_branch": "master"
},
"sender": {
"login": "sgray128",
"id": 161059510,
"node_id": "U_kgDOCZmStg",
"avatar_url": "https://avatars.githubusercontent.com/u/161059510?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/sgray128",
"html_url": "https://github.com/sgray128",
"followers_url": "https://api.github.com/users/sgray128/followers",
"following_url": "https://api.github.com/users/sgray128/following{/other_user}",
"gists_url": "https://api.github.com/users/sgray128/gists{/gist_id}",
"starred_url": "https://api.github.com/users/sgray128/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/sgray128/subscriptions",
"organizations_url": "https://api.github.com/users/sgray128/orgs",
"repos_url": "https://api.github.com/users/sgray128/repos",
"events_url": "https://api.github.com/users/sgray128/events{/privacy}",
"received_events_url": "https://api.github.com/users/sgray128/received_events",
"type": "User",
"site_admin": false
}
}