Lovelace: PostNL

Thanks for the hard work and the initiative. I liked it as it avoided having too much apps on my phone. Hopefully postnl can find a solution for you and us.

Thanks Peter for the work and congratulations with your daughter.

1 Like

Guys,

Have a look at https://github.com/ToonSoftwareCollective/postnl

It seems like the Rooted Toon community have found a way to get the needed information from the PostNL website.

Iā€™m not an experienced programmer and I might be completely wrong, but it is worthed to have a look at it.

Best regards,
Rien

4 Likes

Indeed it shows the deliveries over the last 3 months. historical and current.

Thereā€™s actually a new API!
See here: https://developer.postnl.nl/#/All

This is not new(at least not to me) but this is not linked to a PostNL account. So not usable for everyone. Besides that: It does not show mail

As far as I can tell there is still no way for consumer(with an account) to use an API. So we have to wait and see how/if PostNL will develop something

Iā€™ve been exploring the unofficial implementation the Toon community made at https://github.com/ToonSoftwareCollective/postnl

It looks like the script postnl.sh provides a (reliable) way to receive all packages in json. Iā€™ve been using it to populate a custom db. Might be a point for someone to work on a integration, then again, this is still unofficial and we donā€™t need breaking implementations around.

6 Likes

I saw this topic and (tl:dr, sorry) I seems the plugin isnā€™t working (and findable in HACS). Is there an updating coming?

1 Like

I Know toon is working, is it possible to use some of their components?

1 Like

GitHub - ToonSoftwareCollective/postnl

Well, that script doesnā€™t work anymore. The step 2 fails with:

You don't have permission to access
"http://botfender-forward.akamai.com/api/v1/attempt?"
on this server.

Peter Nijssen summarized it well. PostNL is blocking bot requests (for their own reasons), and they provide no API for end-users (their developer API seems to be focused on businesses such as online stores). So, let me end my post with:

I know this plugin has ended and there is no end-user API available.
But I saw that PostNL has Google Assistant integration (https://www.postnl.nl/campagnes/daan/). Could HomeAssistant talk with GoogleAssistant and obtain package information this way? Of course this is not ideal, and not very reliable (because the response may variate / no version control available); but maybe someone here likes the challenge to integrate this way with PostNL.
Or maybe someone here knows about an existing generic way to link google assistant integrations with home assistant?

1 Like

I just saw this page on the PostNL website! :open_mouth:
https://www.postnl.nl/zakelijke-oplossingen/pakket-versturen/it-koppelingen-webwinkels/postnl-api
How nice will it be if this integration can be back online

1 Like

As far as I can see it is not meant to be used by us as consumers, but for webshop developers to integrate PostNL services in their software. I browsed through the API a little and couldnā€™t find any command or so to generate a list of mail or packages that are on their way.

I got a successfully response with my PostNL account and the bash script from ToonSoftwareCollective: postnl/postnl.sh at 67e49fc71fb43a9a2d56cc9d94ec4f29798fdaf7 Ā· ToonSoftwareCollective/postnl Ā· GitHub

Use the script 1 call per hour otherwise you are flagged as bot, if PostNL flag you as bot you need to wait 2 to 3 hours to try again.

This is a sample response:

{
	"lastSynchronizationDate": "1753-01-01T00:00:00+01:00",
	"receiver": [{
			"shipmentType": "LetterboxParcel",
			"effectiveDate": "2021-04-16T00:00:00+02:00",
			"key": "3SMYPA00000000-NL-0000XX",
			"barcode": "3SMYPA00000000",
			"country": "NL",
			"postalCode": "0000XX",
			"isInternational": false,
			"product": {
				"productCode": "2928",
				"productOption": "016,010",
				"productCharacteristic": "119,021",
				"rerouteToRetailRequiresIdentification": true,
				"features": "StandardDeliveryPlace"
			},
			"description": "ORD000029983",
			"pickup": null,
			"delivery": {
				"barcode": "3SMYPA00000000",
				"status": "InTransit",
				"phase": {
					"index": 2,
					"message": "Zending is gesorteerd",
					"route": null
				},
				"returnEligibility": {
					"isEligible": false,
					"isFreeReturn": false,
					"canReturnAtRetail": false,
					"customReturn": null,
					"pendingReturnAtRetail": false
				},
				"firstDeliveryAttemptExpired": false,
				"firstDeliveryAttemptDate": null,
				"isDelivered": false,
				"hasProofOfDelivery": false,
				"deliveryDate": null,
				"timeframe": {
					"plannedDate": null,
					"plannedFrom": null,
					"plannedTo": null,
					"date": "2021-04-17T00:00:00+02:00",
					"from": "2021-04-17T08:00:00+02:00",
					"to": "2021-04-17T18:00:00+02:00",
					"timeframeType": "Specific",
					"note": null,
					"minutesOverdue": -518
				},
				"deliveryStatusType": "Standard"
			},
			"beforeFirstDeliveryAttempt": true,
			"firstDeliveryAttemptFailed": false,
			"amounts": {},
			"extraInformation": [{
				"data": {
					"text": "Past door de brievenbus."
				},
				"type": "Unknown"
			}],
			"sender": {
				"addressType": "Sender",
				"companyName": "Sender",
				"departmentName": null,
				"lastName": "Retour Afdeling",
				"middleName": null,
				"firstName": null,
				"street": "ExampleStreet",
				"houseNumber": "22",
				"houseNumberSuffix": null,
				"building": null,
				"floor": null,
				"doorCode": null,
				"district": null,
				"region": null,
				"postalCode": "0000CX",
				"town": "DEN HAAG",
				"country": "NL",
				"canUpdateProfileAddress": null
			},
			"receiver": {
				"addressType": "Recipient",
				"companyName": null,
				"departmentName": null,
				"lastName": "Naam Achternaam",
				"middleName": null,
				"firstName": null,
				"street": "Straat",
				"houseNumber": "01",
				"houseNumberSuffix": null,
				"building": null,
				"floor": null,
				"doorCode": null,
				"district": null,
				"region": null,
				"postalCode": "0000XX",
				"town": "Den Haag",
				"country": "NL",
				"canUpdateProfileAddress": null
			},
			"originalReceiver": {
				"addressType": "Recipient",
				"companyName": null,
				"departmentName": null,
				"lastName": "Naam Achternaam",
				"middleName": null,
				"firstName": null,
				"street": "Straat",
				"houseNumber": "01",
				"houseNumberSuffix": null,
				"building": null,
				"floor": null,
				"doorCode": null,
				"district": null,
				"region": null,
				"postalCode": "0000XX",
				"town": "Den Haag",
				"country": "NL",
				"canUpdateProfileAddress": null
			},
			"return": null,
			"deliveryLocation": null,
			"dimensions": {
				"weight": 85.0,
				"volume": 2855475.0,
				"height": 37.0,
				"width": 225.0,
				"depth": 343.0
			},
			"multiColloPackages": [],
			"notifications": [],
			"generatedTitles": {
				"receiver": "Sender",
				"sender": " Naam Achternaam"
			},
			"order": 0,
			"trackedShipment": {
				"id": 308378497,
				"barcode": "3SMYPA00000000",
				"postalCode": "0000XX",
				"country": "NL",
				"title": null,
				"listNameKey": "receiver",
				"box": "Receiver",
				"status": "InTransit",
				"source": "ManuallyAddedThroughMobile",
				"order": null,
				"key": "3SMYPA00000000-NL-0000XX"
			},
			"tripInformation": null,
			"allObservations": [{
				"observationDate": "2021-04-16T09:48:51+02:00",
				"observationCode": "A01"
			}, {
				"observationDate": "2021-04-16T09:50:46+02:00",
				"observationCode": "A98"
			}, {
				"observationDate": "2021-04-16T09:50:46+02:00",
				"observationCode": "A95"
			}, {
				"observationDate": "2021-04-16T22:42:43+02:00",
				"observationCode": "B01"
			}, {
				"observationDate": "2021-04-16T22:43:58+02:00",
				"observationCode": "J01"
			}],
			"isReturnShipment": false,
			"pickUpRetailBarcode": null
		},
		{
			"shipmentType": "Parcel",
			"effectiveDate": "2021-04-12T00:00:00+02:00",
			"key": "3SMYPA00000000-NL-0000XX",
			"barcode": "3SMYPA00000000",
			"country": "NL",
			"postalCode": "0000XX",
			"isInternational": false,
			"product": {
				"productCode": "0185",
				"productOption": "001",
				"productCharacteristic": "112",
				"rerouteToRetailRequiresIdentification": true,
				"features": "None"
			},
			"description": null,
			"pickup": null,
			"delivery": {
				"barcode": "3SMYPA00000000",
				"status": "Delivered",
				"phase": {
					"index": 4,
					"message": "Zending is bezorgd bij de buren op nr. 28",
					"route": "NeighbourDelivery"
				},
				"returnEligibility": {
					"isEligible": true,
					"isFreeReturn": false,
					"canReturnAtRetail": false,
					"customReturn": null,
					"pendingReturnAtRetail": false
				},
				"firstDeliveryAttemptExpired": false,
				"firstDeliveryAttemptDate": null,
				"isDelivered": true,
				"hasProofOfDelivery": false,
				"deliveryDate": "2021-04-13T16:49:38+02:00",
				"timeframe": {
					"plannedDate": null,
					"plannedFrom": null,
					"plannedTo": null,
					"date": "2021-04-13T00:00:00+02:00",
					"from": "2021-04-13T16:05:00+02:00",
					"to": "2021-04-13T18:05:00+02:00",
					"timeframeType": "Specific",
					"note": null,
					"minutesOverdue": 0
				},
				"deliveryStatusType": "Standard"
			},
			"beforeFirstDeliveryAttempt": true,
			"firstDeliveryAttemptFailed": false,
			"amounts": {},
			"extraInformation": [],
			"sender": {
				"addressType": "Sender",
				"companyName": "Bol.com",
				"departmentName": null,
				"lastName": null,
				"middleName": null,
				"firstName": null,
				"street": "Postbus",
				"houseNumber": "10004",
				"houseNumberSuffix": null,
				"building": null,
				"floor": null,
				"doorCode": null,
				"district": null,
				"region": null,
				"postalCode": "5140DA",
				"town": "Waalwijk",
				"country": "NL",
				"canUpdateProfileAddress": null
			},
			"receiver": {
				"addressType": "Neighbour",
				"companyName": "De Buurman",
				"departmentName": null,
				"lastName": "Buurman",
				"middleName": null,
				"firstName": null,
				"street": "Straat",
				"houseNumber": "28",
				"houseNumberSuffix": null,
				"building": null,
				"floor": null,
				"doorCode": null,
				"district": null,
				"region": null,
				"postalCode": "0000XX",
				"town": "Den Haag",
				"country": "NL",
				"canUpdateProfileAddress": null
			},
			"originalReceiver": {
				"addressType": "Recipient",
				"companyName": "Naam Achternaam",
				"departmentName": null,
				"lastName": null,
				"middleName": null,
				"firstName": "Naam",
				"street": "Straat",
				"houseNumber": "01",
				"houseNumberSuffix": null,
				"building": null,
				"floor": null,
				"doorCode": null,
				"district": null,
				"region": null,
				"postalCode": "0000XX",
				"town": "Den Haag",
				"country": "NL",
				"canUpdateProfileAddress": null
			},
			"return": null,
			"deliveryLocation": null,
			"dimensions": {
				"weight": 560.0,
				"volume": 8982250.0,
				"height": 95.0,
				"width": 15.0,
				"depth": 310.0
			},
			"multiColloPackages": [],
			"notifications": [],
			"generatedTitles": {
				"receiver": "Bol.com",
				"sender": "Naam Achternaam"
			},
			"order": 1,
			"trackedShipment": {
				"id": 716600986,
				"barcode": "3SMYPA00000000",
				"postalCode": "0000XX",
				"country": "NL",
				"title": null,
				"listNameKey": "receiver",
				"box": "Receiver",
				"status": "InTransit",
				"source": "ManuallyAddedThroughMobile",
				"order": null,
				"key": "3SMYPA00000000-NL-0000XX"
			},
			"tripInformation": null,
			"allObservations": [{
				"observationDate": "2021-04-12T20:10:02+02:00",
				"observationCode": "A98"
			}, {
				"observationDate": "2021-04-12T20:10:02+02:00",
				"observationCode": "A95"
			}, {
				"observationDate": "2021-04-12T20:11:41+02:00",
				"observationCode": "A01"
			}, {
				"observationDate": "2021-04-12T20:14:08+02:00",
				"observationCode": "B01"
			}, {
				"observationDate": "2021-04-12T20:14:58+02:00",
				"observationCode": "A96"
			}, {
				"observationDate": "2021-04-13T10:50:16+02:00",
				"observationCode": "J01"
			}, {
				"observationDate": "2021-04-13T10:50:36+02:00",
				"observationCode": "J40"
			}, {
				"observationDate": "2021-04-13T11:18:06+02:00",
				"observationCode": "A19"
			}, {
				"observationDate": "2021-04-13T11:19:11+02:00",
				"observationCode": "J05"
			}, {
				"observationDate": "2021-04-13T11:19:11+02:00",
				"observationCode": "A19"
			}, {
				"observationDate": "2021-04-07T17:19:47+02:00",
				"observationCode": "I01"
			}],
			"isReturnShipment": false,
			"pickUpRetailBarcode": null
		}
	],
	"sender": [],
	"orders": []
}

For me its working and got a working response tested 16-04-2021

This thread is about the lovelace card which depends on a library providing the data within Home Assistant. The library that provided the data can be found here: GitHub - iMicknl/python-postnl-api: Python wrapper for the PostNL API, a way to track packages using their online portal.

The entire discussion would thus better fit within that library.

Iā€™ve been trying to reach out to PostNL a while back to see if something was possible but they no longer respond.

Can you provide a sample json which the python wrapper gives back and you uses in your card? maybe i can get it to work again :thinking:

I have requested PostNL an update about their plans about a month ago and I am currently having conversations with them. Will update you guys in a couple of days.

8 Likes

Any updates ?

There is still no official ā€œthingā€ we can use but they told me we can use the web login flow to connect with their API, as long as we keep the traffic within limits which were mentioned here earlier. (once an hour, else we are flagged as a bot).

So in essence, what needs to be done is the following;

  1. Update the PostNL library here by fixing the authentication problem (there is already a pull request) and update the calls to the PostNL API to match their current API.
  2. Create a custom component and add it to HACS. Probably we can review the old component and update it to todays standards of HA.
  3. Update the PostNL Lovelace card to match todays standards of HA.

Make sure we only request an update once an hour, so we are not flagged as a bot.

I am happy to pick up the last point as soon as point 1 and 2 are resolved :slight_smile:

5 Likes