Julia Ebert
Julia Ebert

Reputation: 1623

View random ngrok URL when run in background

When I start an ngrok client with ./ngrok tcp 22 it runs in the foreground and I can see the randomly generated forwarding URL, such as tcp://0.tcp.ngrok.io:12345 -> localhost:22.

If I run in it the background with ./ngrok tcp &, I can't find any way to see the forwarding URL. How can I run ngrok in the background and still see the URL?

Upvotes: 59

Views: 44279

Answers (16)

Mykyta
Mykyta

Reputation: 111

The easiest way for me to check random generated URL is to go to ngrok official site > dashboard > endpoints > status and check the URLs and status of my endpoints

PS: A comment was created when there was no documentation to fetch those endpoints via API. I described it here

Upvotes: 3

avalanchy
avalanchy

Reputation: 851

If you want to get the first tunnel then jq will be your friend:

curl -s localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url'

When running more than one instance of ngrok then use the tunnel name /api/tunnels/:name.

Upvotes: 28

zwcloud
zwcloud

Reputation: 4889

Here is a C# solution that fetches first URL from ngrok Agent API provided by localhost:4040/api.

//fetch xml from API `api/tunnels/command_line`
using var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, 
    "http://localhost:4040/api/tunnels/command_line");
request.Headers.Add(HttpRequestHeader.Accept.ToString(), "application/xml");
var response = await httpClient.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();

//parse and get the first PublicURL element's text
const string Xpath = "/tunnelResource/PublicURL";
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(content);
var xmlNode = xmlDocument.SelectSingleNode(Xpath);
var xmlElement = xmlNode as XmlElement;
var url = xmlElement.InnerText;

Upvotes: 0

Mykyta
Mykyta

Reputation: 111

Use the ngrok API to get all active URLs

You will need to generate a token first (https://dashboard.ngrok.com/api)

Then fetch the active endpoints from the API

curl \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/endpoints

check documentation: https://ngrok.com/docs/api/resources/endpoints

Upvotes: 4

Hemanth Kondapalli
Hemanth Kondapalli

Reputation: 1302

Run ./ngrok http & This runs the ngrok tunnel as a background process. Ngrok usually opens a window showing the assigned URL but since we are using the nohup command this is not visible.

Thus, then run curl http://127.0.0.1:4040/api/tunnels too see the URL assigned by ngrok

Upvotes: 6

Alex Cory
Alex Cory

Reputation: 11865

If you're using nodejs I did this

const getURL = async () => {
  // inspect if the callback is working at: http://127.0.0.1:4040/inspect/http 
  const ngrok = await import('ngrok')
  const api = ngrok.getApi();
  const { tunnels } = JSON.parse(await api?.get('api/tunnels') ?? '{}')
  // if we already have a tunnel open, disconnect. We're only allowed to have 4
  if (tunnels?.length > 0) await ngrok.disconnect()
  return await ngrok.connect(3000)
}

Upvotes: 0

Abhijit
Abhijit

Reputation: 547

A Node.js solution.

Bonus: It copies the url to the clipboard in Windows, Mac and Linux1

const http = require("http");
const { execSync } = require("child_process");

const callback = (res) => {
    let data = "";
    res.on("data", (chunk) => (data += chunk));
    res.on("end", () => {
        const resJSON = JSON.parse(data);
        const tunnels = resJSON.tunnels;

        const { public_url: url } = tunnels.find(({ proto }) => proto === "https");

        console.log(url);

        // Copy to clipboard
        switch (process.platform) {
            case "win32":
                execSync(`echo ${url} | clip`);
                break;
            
            case "darwin":
                execSync(`echo ${url} | pbcopy`);
                break;
                
            case "linux":
                // NOTE: this requires xclip to be installed
                execSync(`echo ${url} | xclip -selection clipboard`);
                break;
                
            default:
                break;
        }
    });
};

http.get("http://localhost:4040/api/tunnels", callback);

[1] You need to install xclip first:

sudo apt-get install xclip

Upvotes: 0

Johnny
Johnny

Reputation: 316

If you love PowerShell, here it is in variables.

$ngrokOutput = ConvertFrom-Json (Invoke-WebRequest -Uri http://localhost:4040/api/tunnels).Content
$httpsUrl = $ngrokOutput.tunnels.public_url[0]
$httpUrl = $ngrokOutput.tunnels.public_url[1]

Upvotes: 2

Abe Petrillo
Abe Petrillo

Reputation: 2447

There are a couple of ways.

You can either:

1) Visit localhost:4040/status in your browser to see a bunch of information, or

2) Use curl to hit the API: localhost:4040/api/tunnels

Upvotes: 69

Jirawat Kusolpredee
Jirawat Kusolpredee

Reputation: 57

There is a better way to do that just login to your account on ngrok.com. Your URL will be in your dashboard.

Upvotes: 0

Rex Tess
Rex Tess

Reputation: 41

import json
import requests


def get_ngrok_url():
    url = "http://localhost:4040/api/tunnels/"
    res = requests.get(url)
    res_unicode = res.content.decode("utf-8")
    res_json = json.loads(res_unicode)
    for i in res_json["tunnels"]:
        if i['name'] == 'command_line':
            return i['public_url']
            break

This is an edit of JUN_NETWORKS python 3 code. It outputs the HTTPS URL only. I find Ngrok will randomly change the order of which is URL is displayed first sometimes outputting HTTP. The additional loop will consistently look for the 'tunnel' named 'command_line' which is the HTTPS URL.

Upvotes: 4

Cruz Nunez
Cruz Nunez

Reputation: 3149

In Ruby

require 'httparty'

# get ngrok public url
begin
  response = HTTParty.get 'http://localhost:4040/api/tunnels'
  json = JSON.parse response.body
  new_sms_url = json['tunnels'].first['public_url']
rescue Errno::ECONNREFUSED
  print 'no ngrok instance found. shutting down'
  exit
end

Upvotes: 2

JUN_NETWORKS
JUN_NETWORKS

Reputation: 361

In Python3

import json
import requests


def get_ngrok_url():
    url = "http://localhost:4040/api/tunnels"
    res = requests.get(url)
    res_unicode = res.content.decode("utf-8")
    res_json = json.loads(res_unicode)
    return res_json["tunnels"][0]["public_url"]

This returned json have 2 url for http and https. If you want only https url, you res_json["tunnels"][index num]["proto"]

Upvotes: 2

James Broad
James Broad

Reputation: 1280

If it helps anyone I wrote a quick script to extract the generated random url in Node:

It makes assumption you're only interested in the secure url.

const fetch = require('node-fetch')
fetch('http://localhost:4040/api/tunnels')
  .then(res => res.json())
  .then(json => json.tunnels.find(tunnel => tunnel.proto === 'https'))
  .then(secureTunnel => console.log(secureTunnel.public_url))
  .catch(err => {
    if (err.code === 'ECONNREFUSED') {
      return console.error("Looks like you're not running ngrok.")
    }
    console.error(err)
  })

If you wanted all tunnels:

const fetch = require('node-fetch')
fetch('http://localhost:4040/api/tunnels')
  .then(res => res.json())
  .then(json => json.tunnels.map(tunnel => tunnel.public_url))
  .then(publicUrls => publicUrls.forEach(url => console.log(url)))
  .catch(err => {
    if (err.code === 'ECONNREFUSED') {
      return console.error(
        "Looks like you're not running ngrok."
      )
    }
    console.error(err)
  })

Upvotes: 4

mohanjot
mohanjot

Reputation: 1510

May be I'm a little too late in answering but would be glad if it is helpful for anyone visiting the question.

***Above answers are solutions to see/check the redirection URL. However to run ngrok in background, you could try using screen in linux . Incase you need help here a quick reference

Steps: 1. Just run the ngrok in screen and then detach. 2. Use the python script given by Gerard above to see the URL.

I have followed the same process and it works!

Upvotes: 0

Gerard
Gerard

Reputation: 191

This little Python (2.7) script will call the ngrok API and print the current URL's:

import json
import os 

os.system("curl  http://localhost:4040/api/tunnels > tunnels.json")

with open('tunnels.json') as data_file:    
    datajson = json.load(data_file)


msg = "ngrok URL's: \n'
for i in datajson['tunnels']:
  msg = msg + i['public_url'] +'\n'

print (msg)

Upvotes: 19

Related Questions