diff --git a/README.md b/README.md index fdee50e..f87358f 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ These are the possible options: | `apiKey` |

An API key generated from a user profile in Mealie.

**REQUIRED** When not using username and password
**Type:** `string`
**Example:** `"eyhJbcG..."`
**Default value:** none

**Note:** You can generate a key by going to your user profile in Mealie then to API Tokens link (or using this path `/user/profile/api-tokens`).

| | `username` |

The username/email for your Mealie account.

**REQUIRED** When not using `apiKey`
**Type:** `string`
**Example:** `"yourmeailieemail@email.com"`
**Default value:** none

| | `password` |

The password for your for Mealie account.

**REQUIRED** When not using `apiKey`
**Type:** `string`
**Example:** `"Secret!"`
**Default value:** none

| -| `groupId` |

The Group ID (as a UUID) to use when fetching the meal plan.

**Type:** `string`
**Example:** `"c0aa0c1c-bdbb-4948-823b-2a725fb05ce1"`
**Default value:** none ("Home" group)

**Note 1:** You can get the UUID of a group from Settings > Groups.

**Note 2:** The default "Home" group is used when this is blank.

| +| `groupId` |

The Household ID (as a UUID) to use when fetching the meal plan.

**Type:** `string`
**Example:** `"c0aa0c1c-bdbb-4948-823b-2a725fb05ce1"`
**Default value:** none ("Family" household)

**Note 1:** You can get the UUID of a household from Settings > Households.

**Note 2:** The default "Family" household is used when this is blank.

**Note 3:** For Mealie v1, Households were called Groups, v2 changed this to Households and Groups moved within Households.| | `currentWeek` |

Only show meals for the current week. Set to `true` to display meals up-to the end of the week. The beginning of the week is set using `weekStartsOnMonday`. The number of meals displayed is limited by `dayLimit`, `entryLimit`, `priorDayLimit`, and `priorEntryLimit`.

**Type:** `boolean`
**Default value:** `true`
**Possible values:** `true` and `false`| | `weekStartsOnMonday` |

Show Monday as the first day of the week. Set to `true` to show Monday as the first day of the week.

**Type:** `boolean`
**Default value:** `false`
**Possible values:** `true` and `false`

**Note:** Only valid when `currentWeek` is set to `true`.

| | `dayLimit` |

How many days will be displayed after today.

**Type:** `integer`
**Example:** `5`
**Default value:** `7`
**Unit:** `days`

**Note:** If `0`, only today will be shown.

**Note 2:** If `currentWeek` is `true`, the max number of days is until the end of the week.| diff --git a/node_helper.js b/node_helper.js index 591819d..562f9f2 100644 --- a/node_helper.js +++ b/node_helper.js @@ -10,30 +10,13 @@ module.exports = NodeHelper.create({ this.token = null; this.tokenExpiration = null; this.outstandingRequest = false; + this.ApiVersion = "1.0.0"; }, socketNotificationReceived (notification, payload) { switch (notification) { case "MEALIE_INIT": - // Use API Key or fetch a token. - if (payload.apiKey) { - this.token = payload.apiKey; - this.initComplete(payload); - } else { - this.getToken(payload) - .then(() => { - this.initComplete(payload); - }) - .catch((error) => { - Log.error(`[${this.name}] Auth error:`, JSON.stringify(error.toString())); - - this.sendSocketNotification("MEALIE_ERROR", { - error: "AUTH_ERROR", - details: error, - identifier: payload.identifier - }); - }); - } + this.initApi(payload); break; case "MEALIE_MENU_GET": @@ -42,12 +25,60 @@ module.exports = NodeHelper.create({ } }, + async initApi (payload) { + try { + // Get API version + await this.getApiVersion(payload); + + // Use API key or fetch token + if (payload.apiKey) { + this.token = payload.apiKey; + } else { + await this.getToken(payload); + } + + this.initComplete(payload, this.token); + } catch (error) { + Log.error(`[${this.name}] Initialization error:`, JSON.stringify(error.toString())); + + this.sendSocketNotification("MEALIE_ERROR", { + error: "INIT_ERROR", + details: error, + identifier: payload.identifier + }); + } + }, + initComplete (payload) { this.sendSocketNotification("MEALIE_INITIALIZED", { identifier: payload.identifier }); }, + getApiVersion (payload) { + const url = new URL(`${payload.host}/api/app/about`); + + return fetch(url, { + method: "GET", + headers: { + Accept: "application/json" + } + }) + .then((response) => { + if (response.ok) { + return response; + } + throw response.statusText; + }) + .then((response) => response.json()) + .then((data) => { + this.ApiVersion = data.version; + }) + .catch((error) => { + throw error; + }); + }, + getToken (payload) { const url = new URL(`${payload.host}/api/auth/token`); const params = new URLSearchParams(); @@ -134,7 +165,11 @@ module.exports = NodeHelper.create({ Log.info(`[${this.name}] Fetching meals: Start Date ${startDate.format("YYYY-MM-DD")} - End date ${endDate.format("YYYY-MM-DD")}`); - const url = new URL(`${payload.host}/api/groups/mealplans`); + let url = new URL(`${payload.host}/api/groups/mealplans`); + // Check for new API endpoint. + if (this.versionCheck(this.ApiVersion, "2.0.0")) { + url = new URL(`${payload.host}/api/households/mealplans`); + } const params = new URLSearchParams(); params.append("start_date", startDate.format("YYYY-MM-DD")); @@ -193,6 +228,28 @@ module.exports = NodeHelper.create({ }); }, + versionCheck (version, required) { + const minParts = required + .replace(/[^0-9.]/ug, "") + .trim() + .split("."); + const newParts = version + .replace(/[^0-9.]/ug, "") + .trim() + .split("."); + for (let part = 0; part < newParts.length; part += 1) { + const verA = parseInt(newParts[part], 10); + const verB = parseInt(minParts[part], 10); + if (verA > verB) { + return true; + } + if (verA < verB) { + return false; + } + } + return true; + }, + getFirstDayOfWeek (weekStartsOnMonday) { const today = moment(); let firstDayOfWeek = moment(); diff --git a/translations/en.json b/translations/en.json index 581c80a..e4015e2 100644 --- a/translations/en.json +++ b/translations/en.json @@ -5,6 +5,7 @@ "ERROR_NO_USER": "You have not provided a username! Username is required when not using the apiKey.
Please set 'username' in config.js!", "ERROR_NO_PASS": "You have not provided a password! Password is required when not using the apiKey.
Please set 'username' in config.js!", "ERROR_MEAL_SORT_ORDER": "mealSortOrder should be an array of strings continaing: ['breakfast', 'lunch', 'dinner', 'side']. They should appear exactly once in the desired sort order.", + "INIT_ERROR": "Initialization Error: There was an error setting up Mealie.", "AUTH_ERROR": "Authentication Error: There was an error fetching a user token. Check your username and password.", "FETCH_ERROR": "Fetch Error: There was an error fetching data from Mealie.", "MEALIE_SUSPEND": "Function suspend - module: {name} with identifier: {identifier}",