Skip to content

Instantly share code, notes, and snippets.

@khskekec
Last active April 3, 2025 04:59
Show Gist options
  • Save khskekec/6c13ba01b10d3018d816706a32ae8ab2 to your computer and use it in GitHub Desktop.
Save khskekec/6c13ba01b10d3018d816706a32ae8ab2 to your computer and use it in GitHub Desktop.
HTTP dump of Libre Link Up used in combination with FreeStyle Libre 3
@StephanBroYT
Copy link

I found a solution to the problem by selecting a different country in libre link up, but now I can't share my data , the invite just doesn't come in

About 90% of the time this would be caused by the invite being blocked by spam filters. (Sometimes the message is sent to you but your client moves it to a spam folder, but sometimes the message does not get anywhere near you).
Never tried it, but I believe you may be able to work around this by pre-installing the LibreLinkUp app
From their FAQ (https://librelinkup.com/faqs)
I downloaded the LibreLinkUp app before receiving the connection invitation email from the FreeStyle Libre app user. Can I still connect with the FreeStyle Libre app user?
If you downloaded the LibreLinkUp app on your smartphone, you will see a pop-up message asking whether you would like to accept the invitation the next time you open the app. Tap Allow to confirm the connection.

I don't get the allow button

I FOUND THE ANSWER TO MY PROBLEM!!!!! I need to replace url with url = β€˜https://api.libreview.ru’ and everything will work, probably because I live in Russia and there is a different API system here.

@sgmoore
Copy link

sgmoore commented Oct 4, 2024

FOUND THE ANSWER TO MY PROBLEM!!!!! I need to replace url with url = β€˜https://api.libreview.ru’ and everything will work, probably because I live in Russia and there is a different API system here.

Interesting. Do you know what you got in the data field when you tried https://api.libreview.io ?

@StephanBroYT
Copy link

Interesting. Do you know what you got in the data field when you tried https://api.libreview.io ?

When I used https://api.libreview.io/ it just said that no such account existed

@avostokova
Copy link

I found a solution to the problem by selecting a different country in libre link up, but now I can't share my data , the invite just doesn't come in

About 90% of the time this would be caused by the invite being blocked by spam filters. (Sometimes the message is sent to you but your client moves it to a spam folder, but sometimes the message does not get anywhere near you).
Never tried it, but I believe you may be able to work around this by pre-installing the LibreLinkUp app
From their FAQ (https://librelinkup.com/faqs)
I downloaded the LibreLinkUp app before receiving the connection invitation email from the FreeStyle Libre app user. Can I still connect with the FreeStyle Libre app user?
If you downloaded the LibreLinkUp app on your smartphone, you will see a pop-up message asking whether you would like to accept the invitation the next time you open the app. Tap Allow to confirm the connection.

I don't get the allow button

I FOUND THE ANSWER TO MY PROBLEM!!!!! I need to replace url with url = β€˜https://api.libreview.ru’ and everything will work, probably because I live in Russia and there is a different API system here.

Hello, bro!
Π― Ρ‚ΠΎΠΆΠ΅ ΠΈΠ· Π Π€, Ρƒ мСня вопрос ΠΏΠΎ запросам ΠΊ api.libreview.ru Π² связи с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ сСйчас Π²Ρ€ΠΎΠ΄Π΅ Π²Ρ‹Π΄Π°ΡŽΡ‚ Π»ΠΈΠ±Ρ€Π°2 ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ ΠΌΠΈΠ½ΡƒΡ‚Ρƒ, поэтому Ρ…ΠΎΡ‚Π΅Π» Π±Ρ‹ Π΄Π°Π½Π½Ρ‹Π΅ Π΄Π΅Ρ€Π³Π°Ρ‚ΡŒ ΠΈΠ· api ΠΈ дальшС с Π½ΠΈΠΌΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ. ΠŸΠΎΠ΄ΡΠΊΠ°ΠΆΠΈΡ‚Π΅, Π²Ρ‹ Ρ‡Π΅Π³ΠΎ-Ρ‚ΠΎ добились Π² этом? БСйчас ΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡΡŒ Π΄ΠΆΡƒΠ³Π»ΡƒΠΊΠΎ+иксдрип. Но протСстил ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ послС обновлСния ΠΈ ΠΌΠ½Π΅ ΠΏΠΎΠ½Ρ€Π°Π²ΠΈΠ»ΠΎΡΡŒ ΠΊΠ°ΠΊ ΠΎΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ…ΠΎΡ‡Ρƒ Ρ‡Π΅Π³ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΡΠΊΠ»Π΅ΠΏΠ°Ρ‚ΡŒ для получСния Π΄Π°Π½Π½Ρ‹Ρ… нСпосрСдствСнно ΠΈΠ· api

@StephanBroYT
Copy link

I found a solution to the problem by selecting a different country in libre link up, but now I can't share my data , the invite just doesn't come in

About 90% of the time this would be caused by the invite being blocked by spam filters. (Sometimes the message is sent to you but your client moves it to a spam folder, but sometimes the message does not get anywhere near you).
Never tried it, but I believe you may be able to work around this by pre-installing the LibreLinkUp app
From their FAQ (https://librelinkup.com/faqs)
I downloaded the LibreLinkUp app before receiving the connection invitation email from the FreeStyle Libre app user. Can I still connect with the FreeStyle Libre app user?
If you downloaded the LibreLinkUp app on your smartphone, you will see a pop-up message asking whether you would like to accept the invitation the next time you open the app. Tap Allow to confirm the connection.

I don't get the allow button

I FOUND THE ANSWER TO MY PROBLEM!!!!! I need to replace url with url = β€˜https://api.libreview.ru’ and everything will work, probably because I live in Russia and there is a different API system here.

Hello, bro! Π― Ρ‚ΠΎΠΆΠ΅ ΠΈΠ· Π Π€, Ρƒ мСня вопрос ΠΏΠΎ запросам ΠΊ api.libreview.ru Π² связи с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ сСйчас Π²Ρ€ΠΎΠ΄Π΅ Π²Ρ‹Π΄Π°ΡŽΡ‚ Π»ΠΈΠ±Ρ€Π°2 ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ ΠΌΠΈΠ½ΡƒΡ‚Ρƒ, поэтому Ρ…ΠΎΡ‚Π΅Π» Π±Ρ‹ Π΄Π°Π½Π½Ρ‹Π΅ Π΄Π΅Ρ€Π³Π°Ρ‚ΡŒ ΠΈΠ· api ΠΈ дальшС с Π½ΠΈΠΌΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ. ΠŸΠΎΠ΄ΡΠΊΠ°ΠΆΠΈΡ‚Π΅, Π²Ρ‹ Ρ‡Π΅Π³ΠΎ-Ρ‚ΠΎ добились Π² этом? БСйчас ΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡΡŒ Π΄ΠΆΡƒΠ³Π»ΡƒΠΊΠΎ+иксдрип. Но протСстил ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ послС обновлСния ΠΈ ΠΌΠ½Π΅ ΠΏΠΎΠ½Ρ€Π°Π²ΠΈΠ»ΠΎΡΡŒ ΠΊΠ°ΠΊ ΠΎΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ…ΠΎΡ‡Ρƒ Ρ‡Π΅Π³ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΡΠΊΠ»Π΅ΠΏΠ°Ρ‚ΡŒ для получСния Π΄Π°Π½Π½Ρ‹Ρ… нСпосрСдствСнно ΠΈΠ· api

ΠŸΡ€ΠΈΠ²Π΅Ρ‚. Π”Π°, сСйчас Π½Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π»ΠΈΠ±Ρ€Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π±Π΅Π· сканирования ΠΊΠ°ΠΆΠ΄ΡƒΡŽ ΠΌΠΈΠ½ΡƒΡ‚Ρƒ, ΠΈ Π² api ΠΎΠ½ΠΈ Ρ‚ΠΎΠΆΠ΅ Π΅ΡΡ‚ΡŒ, сСйчас я ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ https://github.com/timoschlueter/nightscout-librelink-up Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΈΡ… Π½Π° nightscout, Π² Π°ΠΏΠΈ Π»ΠΈΠ±Ρ€Ρ‹ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ помСнялось. Π£ мСня Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ https://github.com/StephanBroYT/Yandex-Alice-Libre/ Ρ‚Π°ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ API Π½Π° python

@Tarman34
Copy link

Hi, I'm getting 400 error code with "RequiredHeaderMissing" from today. Also version has to be updated to min. 4.12.0 but I can't figure out that new header missing. Any suggestion? Thx

@gui-dos
Copy link

gui-dos commented Dec 10, 2024

@Tarman34:

A new "Account-Id" HTTP header is now required, passing the SHA256 digest of a user's id as a 64-char hexadecimal string.

You can have a look at my Swift one-liners I PRed with JohanDegraeve/xdripswift@13e4a1e7 ;-)

@adamlounds
Copy link

There's an additional endpoint at GET /llu/connections/{patientId}/logbook which returns manual device scans. Response data is the expected array of glucoseItems.

Still no obvious way to extract insulin injections or food as recorded in the logbook :(

{
	"status": 0,
	"data": [{
		"FactoryTimestamp": "12/10/2024 4:27:43 PM",
		"Timestamp": "12/10/2024 4:27:43 PM",
		"type": 1,
		"ValueInMgPerDl": 128,
		"TrendArrow": 3,
		"TrendMessage": null,
		"MeasurementColor": 1,
		"GlucoseUnits": 0,
		"Value": 7.1,
		"isHigh": false,
		"isLow": false
	}, ...

@Tarman34
Copy link

@Tarman34:

A new "Account-Id" HTTP header is now required, passing the SHA256 digest of a user's id as a 64-char hexadecimal string.

You can have a look at my Swift one-liners I PRed with JohanDegraeve/xdripswift@13e4a1e7 ;-)

Thanks a lot my man... You saved my (my daughter's) life!!!

@sgmoore
Copy link

sgmoore commented Dec 11, 2024

There's an additional endpoint at GET /llu/connections/{patientId}/logbook which returns manual device scans.

Do you mind me asking how you discovered this?

Still no obvious way to extract insulin injections or food as recorded in the logbook :(

Which of course is the one I really want! I guess this is because this info isn't available in the LibreLinkUp app so Abbott don't need it.

@adamlounds
Copy link

adamlounds commented Dec 11, 2024

I discovered by tracing activity on the llu app on my phone.

Turns out it was already documented in a GitHub repo (or https://libreview-unofficial.stoplight.io/docs/libreview-unofficial/4503bd234db99-get-logbook) & I had missed it :)
(nb that repo is a bit out-of-date though, it does not include the Account-Id header for example)

@robberwick
Copy link

robberwick commented Dec 11, 2024

Another good approach for discovering those endpoints is to download the LLU apk from https://librelinkup.en.aptoide.com/app and decompile it. Because it's a react native app, it's fairly straightforward to search through the JavaScript to find all the places where it calls the upstream API, and grab the URLS and parameters for those.

@adamlounds
Copy link

adamlounds commented Dec 12, 2024

@robberwick thanks for that :) I can't quite unbundle the react native app inside the apk, but there's a bunch of useful things in there. I just ran prettier on resources/assets/app/bundle.js so it wasn't all on one line πŸ™‚

The product type can be inferred from the connections response's patientDevice.dtid as follows:

40068 - FSL3
40067 - FSL2
40066 - FSL1 or FSL2

for 40066, if patientDevice.alarms is true, it's a FLS2.

I assume patientDevice fields as follows

did : v1 uuid, date implies it's date of manufacture not activation (eg 2024-04-13 19:26:53.077364.4 UTC)
dtid: device type id
v: version
ll: lower limit (68)
fixedLowThreshold: 70 (? not sure what's different between this and lower limit?)
hl: high limit (239)
alarms: true (does this device support alarms via bluetooth, AIUI FSL1 does not)

@robberwick
Copy link

That's super useful @adamlounds - thanks πŸ‘

@robberwick
Copy link

Interestingly, although you don't list it, I've often seen patientDevice also have a u field containing what looks like a Unix timestamp. Only recently did I see an instance without that field present for the first time. Whether or not it's device type dependent, I don't know 🀷

@adamlounds
Copy link

adamlounds commented Dec 12, 2024

Could be duplication in the graph response. I get

		"sensor": {
			"deviceId": "",
			"sn": "MH019HA5WR",
			"a": 1733129659,
			"w": 60,
			"pt": 3,
			"s": true,
			"lj": false
		},

and

		"activeSensors": [{
			"sensor": {
				"deviceId": "c8648a8c-f9cb-11ee-be17-5e03ce2d2a0d",
				"sn": "MH019HA5WR",
				"a": 1733129659,
				"w": 60,
				"pt": 3,
				"s": true,
				"lj": false
			},
			"device": {
				"did": "c8648a8c-f9cb-11ee-be17-5e03ce2d2a0d",
				"dtid": 40066,
				"v": "2.11.2.8275",
				"ll": 68,
				"h": true,
				"hl": 239,
				"u": 1730932499,
				"fixedLowAlarmValues": {
					"mgdl": 60,
					"mmoll": 3.3
				},
				"alarms": true,
				"fixedLowThreshold": 70
			}
		}],

I think the sensor.pt (product type) is 0 for FSL1, 3 for FSL2, 4 for FSL3, but the dtid is 40066-8 as above.
Nothing like redundancy and inconsistency, right? Not sure why the sensor has a deviceId in one section and not the other, either πŸ˜€

sensor.a is the activation time (2024-12-02T08:54:19Z). I'm not sure what the device.u timestamp is, this one is 2024-11-06T22:34:59Z Β―_(ツ)_/Β―

also note that the initial gist was for a FSL3 but alarms was false. v must be based on the freestyle libre model if it's 3.3.1 here but 2.something for my FSL2

"patientDevice": {
        "did": "2d97357e-d250-11ec-b409-0242ac110004",
        "dtid": 40068,
        "v": "3.3.1",
        "ll": 65,
        "hl": 130,
        "u": 1653016896,
        "fixedLowAlarmValues": {
          "mgdl": 60,
          "mmoll": 3.3
        },
        "alarms": false
},

@kanomade
Copy link

Is it possible to get glucose values for a date range, or let's say the past 3 hours?

@robberwick
Copy link

robberwick commented Dec 15, 2024

@kanomade Not directly via the LLU api, no. The graph data will give you all the measurements that would be displayed in the app, so approximately 12 hours worth. It would be up to you to filter that data for the readings that you're interested in.

@kanomade
Copy link

@kanomade Not directly via the LLU api, no. The graph data will give you all the measurements that would be displayed in the app, so approximately 12 hours worth. It would be up to you to filter that data for the readings that you're interested in.

/llu/connections/{patientId}/graph only gives me one measurement. Are you saying that it should return me all available measurements? I don't understand your answer.

@kanomade
Copy link

Am I likely to get an error or refused connection if I don't cache the token, but re-request it on every request, lets say every 5 min?

@sgmoore
Copy link

sgmoore commented Dec 16, 2024

/llu/connections/{patientId}/graph only gives me one measurement. Are you saying that it should return me all available measurements?

You may be looking at the wrong bit of the result. Details are at the very end of this original gist (before all the comments)
Specifically these bits :

The last measurement is present in glucoseMeasurement:

Instead you can find historical measurements in graphData. The data has the same shape as above.

@kanomade
Copy link

In data.connection.glucoseMeasurement, there is FactoryTimestamp and Timestamp. Neiither of them correspond to either local time or UTC. Local time is 11:31AM and I get:
FactoryTimestamp: '12/14/2024 10:46:21 AM',
Timestamp: '12/14/2024 11:46:21 AM',
So it looks like Timestamp is UTC, and FactoryTimestamp is closer to local time, but showing a reading 45 minutes ago. Can anyone shed some light on this???

@kanomade
Copy link

/llu/connections/{patientId}/graph only gives me one measurement. Are you saying that it should return me all available measurements?

You may be looking at the wrong bit of the result. Details are at the very end of this original gist (before all the comments) Specifically these bits :

The last measurement is present in glucoseMeasurement:

Instead you can find historical measurements in graphData. The data has the same shape as above.

Graph data is showing as empty, like this in the JSON:

"graphData":[]

@adamlounds
Copy link

adamlounds commented Dec 16, 2024

Am I likely to get an error or refused connection if I don't cache the token, but re-request it on every request, lets say every 5 min?

No, you'll be fine. It's just better/friendlier to cache the token if you can.

Is your sensor talking to your phone correctly? If you use the LibreView app, what is the latest data it shows?

@earlgraycz
Copy link

Hi Guys,

Does anyone know how to properly detect if an app is without a sensor signal? For example at a long distance for bluetooth?

Thank you.

@Mohmedsabry
Copy link

when i use https://api-eu.libreview.io/llu/connections i get a empty date [] and i tried https://api-eu.libreview.io/llu/connections/(user_id as sha256)/graph get message MissingCachedUser

@Mohmedsabry
Copy link

Hi All, I could use some help, for some reason I can query the data without issue in Postman, but when I copy the code from postman to xampp and try running the code, I get a cloudflare error, any assistance would be greatly appreciated.

Postman results: image Copy code from Postman: image PHP code in xampp results: image

To reiterate, code is identical between Postman and PHP script in XAMPP

what is headers required

@sgmoore
Copy link

sgmoore commented Dec 23, 2024

when i use https://api-eu.libreview.io/llu/connections i get a empty date []

I presume you mean you get empty data. That usually means that you do not have any followers/connections which in turn means you have not followed yourself. (This confusing step is required as LibreLinkUp was designed for other people to see your data, not for you to see your own data, so the workaround is to add yourself as a follower to your own main account)

and i tried https://api-eu.libreview.io/llu/connections/(user_id as sha256)/graph get message MissingCachedUser

It should be patientId (not user id) and you get this information from data returned by https://api-eu.libreview.io/llu/connections. So if you don't have any followers/connections I don't know what id you are using.

what is headers required

This is a snippet of my C# code. This works for me even though it has not been changed to include the header mentioned by gui-dos , namely

A new "Account-Id" HTTP header is now required, passing the SHA256 digest of a user's id as a 64-char hexadecimal string.

Also I'm still using version 4.7 but others have said they need to use version 4.12.0

    var request = new HttpRequestMessage
	{
		Method = method,
		RequestUri = new Uri(url),
		Headers =
		{
			{ "product"         , "llu.android"         },
			{ "version"         , "4.7"                 },
			{ "Accept"          , "application/json"    },
			{ "cache-control"   , "no-cache"            },
			{ "accept-encoding" , "gzip"                },
			{ "connection"      , "Keep-Alive"          },
			{ "user-agent"      , "Mozilla/5.0 (Windows NT 10.0; rv:129.0) Gecko/20100101 Firefox/129.0" }
		}
	};

	if (!String.IsNullOrEmpty(token))
		request.Headers.Add("Authorization", $"Bearer {token}");

@Mohmedsabry
Copy link

Mohmedsabry commented Dec 23, 2024

when i use https://api-eu.libreview.io/llu/connections i get a empty date []

I presume you mean you get empty data. That usually means that you do not have any followers/connections which in turn means you have not followed yourself. (This confusing step is required as LibreLinkUp was designed for other people to see your data, not for you to see your own data, so the workaround is to add yourself as a follower to your own main account)

and i tried https://api-eu.libreview.io/llu/connections/(user_id as sha256)/graph get message MissingCachedUser

It should be patientId (not user id) and you get this information from data returned by https://api-eu.libreview.io/llu/connections. So if you don't have any followers/connections I don't know what id you are using.

what is headers required

This is a snippet of my C# code. This works for me even though it has not been changed to include the header mentioned by gui-dos , namely

A new "Account-Id" HTTP header is now required, passing the SHA256 digest of a user's id as a 64-char hexadecimal string.

Also I'm still using version 4.7 but others have said they need to use version 4.12.0

    var request = new HttpRequestMessage
	{
		Method = method,
		RequestUri = new Uri(url),
		Headers =
		{
			{ "product"         , "llu.android"         },
			{ "version"         , "4.7"                 },
			{ "Accept"          , "application/json"    },
			{ "cache-control"   , "no-cache"            },
			{ "accept-encoding" , "gzip"                },
			{ "connection"      , "Keep-Alive"          },
			{ "user-agent"      , "Mozilla/5.0 (Windows NT 10.0; rv:129.0) Gecko/20100101 Firefox/129.0" }
		}
	};

	if (!String.IsNullOrEmpty(token))
		request.Headers.Add("Authorization", $"Bearer {token}");

thank you i tried your code and it fails after login just add Account-id header it works fine and upgrade version to 4.12 it must

@samuele4414
Copy link

hi i have some problem while getting the data from this code
async function getConnections() {
try {
console.log("DIO DI CHIAMATA COLLECTIONS CHE NON FUNZIONA", ACCOUNT_ID);
const response = await fetch(${API_BASE_URL}/llu/connections, {
method: "GET",
headers: {
...HEADERS,
Authorization: Bearer ${AUTH_TOKEN},
"account-id": ACCOUNT_ID
}
});

const data = await response.json();

if (data.message && data.message === "AccountIdMismatch") {
  throw new Error("Account ID does not match");
}

} catch (error) {
console.error("❌ Errore", error.message);
return null;
}
}

i'm able to login with this code

async function login() {
try {
const response = await fetch(${API_BASE_URL}/llu/auth/login, {
method: "POST",
headers: HEADERS,
body: JSON.stringify({
email: CREDENTIALS.email,
password: CREDENTIALS.password
})
});

const text = await response.text();
console.log("πŸ” Risposta ricevuta:", text);

const data = JSON.parse(text);

if (data.status !== 0 || !data.data.authTicket) {
  throw new Error("Login fallito. Controlla le credenziali.");
}

AUTH_TOKEN = data.data.authTicket.token;
ACCOUNT_ID = data.data.user.id;
console.log("βœ… Token ottenuto:", AUTH_TOKEN);
console.log("βœ… Account ID:", ACCOUNT_ID);

} catch (error) {
console.error("❌ Errore nel login:", error.message);
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment