Private GitHub Repo and Autohokey

Published: 2019-05-06

How to connect to a GitHub Private Repository to download files.

This can be useful if you want to automatically update your application to the latest release.

#SingleInstance, force
#NoEnv

#Include %A_ScriptDir%\..\json\JSON.ahk ;https://github.com/cocobelgica/AutoHotkey-JSON

;------------------------------------------------------------------
;GLOBALS

global g_url := "https://api.github.com/repos/<username>/<repository>/releases"
global g_file := "filename.zip"
global g_saveto := A_Desktop . "/" . g_file

; You need to generate this in your github account
global g_token := "74jf8gh7ihdg9orlkk948rjfugnry369jgirn857" ; <-- not a real token, demo purposes

;------------------------------------------------------------------
;MAIN CODE

r := false

request := comobjcreate("WinHttp.WinHttpRequest.5.1") ; Lets get our "navigator"

request.Open("GET", g_url , false)
request.SetRequestHeader("Authorization", "token " . g_token)
request.Send() ; Get the releases information

if (request.responsetext = "failed" || request.status != 200 || comobjtype(request.responsestream) != 0xd) {
      FileAppend, % "Error:`r`n"
          . "Status: `r`n" . request.status . "`r`n"
          . "Headers: `r`n" . request.getallresponseheaders() . "`r`n"
          . "Response: `r`n" . request.responsetext
          . "`r`n", *
}
else
{
  jsObj := JSON.Load(request.ResponseText) ; Parse the JSON file returned from the GitHub API

  for index, element in jsObj.1.assets
  {
    ; we need to get a certain file out of all the assets
    if (element.name = g_file) {
      g_url := element.url
    }
  }
}

  request.option(6) := 0 ;no redirects
  request.open("GET", g_url, false)
  request.setrequestheader("Authorization", "token " . g_token)
  request.setrequestheader("Accept", "application/octet-stream")
  request.send() ;FIRST request gets the 302 redirect to AWS

  if (request.responsetext = "failed" || request.status != 302 || comobjtype(request.responsestream) != 0xd) {
      FileAppend, % "Error:`r`n"
          . "Status: `r`n" . request.status . "`r`n"
          . "Headers: `r`n" . request.getallresponseheaders() . "`r`n"
          . "Response: `r`n" . request.responsetext
          . "`r`n", *
  }
  else
  {
    g_url := request.getresponseheader("Location") ;get the redirect URL

    request.open("GET", g_url, false)
    request.send() ;SECOND request gets the file to download

    if (request.responsetext = "failed" || request.status != 200 || comobjtype(request.responsestream) != 0xd) {
        FileAppend, % "Error:`r`n"
            . "Status: `r`n" . request.status . "`r`n"
            . "Headers: `r`n" . request.getallresponseheaders() . "`r`n"
            . "Response: `r`n" . request.responsetext
            . "`r`n", *
    }
    else
    {
        g_url := request.getresponseheader("Content-Length")

        URLDownloadToFile, % g_url, % g_saveto ; download the file

        if (ErrorLevel = 1) {
            FileAppend, % splash_msg_prog . "Download Failed..."
        } else {
            FileAppend, % splash_msg_prog . "File downloaded!"
        }

        FileAppend, % "Done!`r`n", *
    }
  }
}
return