Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pipe the result of "ngrok http 8000" to another file?

I use ngrok for testing webhooks, and I find myself constantly copy/pasting the newly generated ngrok host into several places, so I decided to automate this process, but can't seem to find a clean way to extract the url from the ngrok process.

I expected to be able to pipe the output to a file, then extract it using regex or something, but the stdout appears to be empty.

For example, the following command results in an empty file: ngrok http 8000 > test.txt

This is the output of ngrok http 8000:

output of ngrok http 8000

I managed to find a hack using python+selenium and ngrok's "inspect":

#!/usr/bin/env python3
from selenium import webdriver

from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.firefox.options import Options
from selenium.common.exceptions import WebDriverException

def main():
    opts = Options()
    opts.headless = True
    bot = webdriver.Firefox(options=opts)
    bot.get('http://localhost:4040/inspect/http')
    url_xpath = '/html/body/div[2]/div/div/div/div/ul/li[1]/a'
    WebDriverWait(bot, 10).until(EC.element_to_be_clickable((By.XPATH, url_xpath)))
    url = bot.find_element_by_xpath(url_xpath).text
    print(url.partition('://')[2])
    bot.close()


if __name__ == '__main__':
    main()

But this is slow, and a ton of code for something so trivial. Also, it doesn't account from ngrok randomly changing the inspect port.

Is there a better way to do this?

like image 332
Lord Elrond Avatar asked Oct 23 '25 22:10

Lord Elrond


1 Answers

Instead of get result output from ngrok http <port>, you can use agent api.

Like screenshot in your question, when you execute ngrok http proxy, ngrok serves Web Interface (http://127.0.0.1:4040 in this case.)

This, Web Interface also support some APIs including able to retrieve public url (this is what you want).

After execute ngrok, try curl http://localhost:4040/api/tunnels/ than result json will be like below.

{"tunnels":[{"name":"command_line","ID":"361e06eef2409dfeb996134e0b004f35","uri":"/api/tunnels/command_line","public_url":"https://0cdc-222-111-197-23.jp.ngrok.io","proto":"https","config":{"addr":"http://localhost:8080","inspect":true},"metrics":{"conns":{"count":0,"gauge":0,"rate1":0,"rate5":0,"rate15":0,"p50":0,"p90":0,"p95":0,"p99":0},"http":{"count":0,"rate1":0,"rate5":0,"rate15":0,"p50":0,"p90":0,"p95":0,"p99":0}}}],"uri":"/api/tunnels"}

Unfortunately, because response is in json format, parse and get public_url is needed. I recommend using parsing tools like jq.

for example,

curl http://localhost:4040/api/tunnels/ | jq .tunnels[0].public_url
# will prints "https://0cdc-222-111-197-23.jp.ngrok.io"
like image 105
SeongjunKang Avatar answered Oct 25 '25 13:10

SeongjunKang



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!