diff --git a/manifest.konnector b/manifest.konnector index d5dc065bc7ae78abb91d5947070b0484ffff6e12..e35dd9aae7fc1c540ec40a7bfb38c8c1b55ad7f4 100644 --- a/manifest.konnector +++ b/manifest.konnector @@ -1,13 +1,13 @@ { "version": "1.0.0", - "name": "Enedis Api Connector", + "name": "Enedis", "type": "konnector", "language": "node", "icon": "icon.png", - "slug": "enedis-api-konnector", - "source": "git@github.com:hsubtil/enedis-konnector.git", + "slug": "enedis-konnector", + "source": "https://forge.grandlyon.com/web-et-numerique/llle_project/enedis-konnector.git", "editor": "Grand Lyon", - "vendor_link": "www.grandlyon.com", + "vendor_link": "https://www.enedis.fr/", "categories": ["energy"], "frequency": "daily", "fields": { @@ -23,8 +23,7 @@ "screenshots": [], "permissions": { "accounts": { - "type": "io.cozy.accounts", - "verbs": ["GET"] + "type": "io.cozy.accounts" }, "half hour enedis load profile data": { "type": "io.enedis.minute" @@ -43,35 +42,29 @@ } }, "developer": { - "name": "Cozy Cloud", - "url": "https://cozy.io" + "name": "GRand Lyon", + "url": "https://www.grandlyon.com/" }, "langs": ["fr", "en"], "locales": { - "short_description": "Courbe de charge depuis le site Enedis", + "short_description": "Récupère vos donnéees de courbe de charge depuis l'API Enedis", "long_description": "Ce connecteur récupère la courbe de charge électrique enregistrée par le compteur Linky", "permissions": { "load profile": { "description": "La courbe de charge électrique enregistrée par le compteur Linky" }, - "files": { - "description": "Nécessaire (à voir pourquoi)" - }, "accounts": { "description": "Utilisé pour obtenir les données du compte" } } }, "en": { - "short_description": "Load profile from Enedis website", + "short_description": "Fetch your Load profile from Enedis API", "long_description": "This connector fetches the electrical load profile recorded by the Linky electricity meter", "permissions": { "load profile": { "description": "The load profile recorded by Linky" }, - "files": { - "description": "Required (why ?)" - }, "accounts": { "description": "Required to get the account's data" } diff --git a/src/helpers/getAccountId.js b/src/helpers/getAccountId.js new file mode 100644 index 0000000000000000000000000000000000000000..65ed6d5a9ea31dfffa64b460e9588980547d0f25 --- /dev/null +++ b/src/helpers/getAccountId.js @@ -0,0 +1,12 @@ +function getAccountId() { + try { + return process.env.NODE_ENV === 'development' || + process.env.NODE_ENV === 'test' + ? 'fakeAccountId' + : JSON.parse(process.env.COZY_FIELDS).account + } catch (err) { + throw new Error(`You must provide 'account' in COZY_FIELDS: ${err.message}`) + } +} + +module.exports = getAccountId diff --git a/src/index.js b/src/index.js index 3252758bc589da587496649628ab6ce5503fd51b..bafdd957b8c37a17d709df4e9fd8917078cb3dee 100644 --- a/src/index.js +++ b/src/index.js @@ -3,8 +3,12 @@ const { log, addData, hydrateAndFilter, + errors, cozyClient } = require('cozy-konnector-libs') + +const getAccountId = require('./helpers/getAccountId') + const moment = require('moment') const rp = require('request-promise') require('moment-timezone') @@ -28,14 +32,20 @@ const baseUrl = 'https://gw.hml.api.enedis.fr' * the account information come from ./konnector-dev-config.json file * cozyParameters are static parameters, independents from the account. Most often, it can be a * secret api key. + * @param {Object} fields + * @param {string} fields.access_token - a google access token + * @param {string} fields.refresh_token - a google refresh token + * @param {Object} cozyParameters - cozy parameters + * @param {boolean} doRetry - whether we should use the refresh token or not */ -async function start(fields) { +async function start(fields, cozyParameters, doRetry = true) { + log('info', 'Starting the enedis konnector') + const accountId = getAccountId() try { const { access_token } = fields // const { oauth_callback_results } = fields // const usage_point_id = oauth_callback_results.usage_point_id const usage_point_id = 22516914714270 - log('info', 'Fetching enedis daily data') const fetchedDailyData = await getDailyData(access_token, usage_point_id) log('info', 'Process enedis daily data') @@ -62,7 +72,36 @@ async function start(fields) { log('info', 'No consent or data for load curve') } } catch (err) { - log('error', err.message) + if (err.statusCode === 403 || err.code === 403) { + if (!fields.refresh_token) { + log('info', 'no refresh token found') + throw errors.USER_ACTION_NEEDED_OAUTH_OUTDATED + } else if (doRetry) { + log('info', 'asking refresh from the stack') + let body + try { + body = await cozyClient.fetchJSON( + 'POST', + `/accounts/enedis-konnector/${accountId}/refresh` + ) + } catch (err) { + log('info', `Error during refresh ${err.message}`) + throw errors.USER_ACTION_NEEDED_OAUTH_OUTDATED + } + + log('info', 'refresh response') + log('info', JSON.stringify(body)) + fields.access_token = body.attributes.oauth.access_token + return start(fields, cozyParameters, false) + } + + log('error', `Error during authentication: ${err.message}`) + throw errors.VENDOR_DOWN + } else { + log('error', 'caught an unexpected error') + log('error', err.message) + throw errors.VENDOR_DOWN + } } } @@ -86,12 +125,8 @@ async function getDailyData(token, usagePointID) { Authorization: 'Bearer ' + token } } - try { - const response = await rp(dataRequest) - return response - } catch (error) { - throw error - } + const response = await rp(dataRequest) + return response } /** @@ -114,12 +149,8 @@ async function getLoadData(token, usagePointID) { Authorization: 'Bearer ' + token } } - try { - const response = await rp(dataRequest) - return response - } catch (error) { - throw error - } + const response = await rp(dataRequest) + return response } /**