fix(api/searchMusic): Use Deezer's light gateway

Improves search results by about 100%
This commit is contained in:
Namkhai B 2022-04-11 11:29:39 -05:00
parent 44ba642931
commit 92c8263559
No known key found for this signature in database
GPG Key ID: 87920A3B2A811186
4 changed files with 45 additions and 3 deletions

View File

@ -137,7 +137,7 @@ test('SEARCH TRACK, ALBUM & ARTIST', async (t) => {
const QUERY = 'Eminem'; const QUERY = 'Eminem';
const response = await api.searchMusic(QUERY, ['TRACK', 'ALBUM', 'ARTIST'], 1); const response = await api.searchMusic(QUERY, ['TRACK', 'ALBUM', 'ARTIST'], 1);
t.is(response.QUERY, QUERY.toLowerCase()); t.is(response.QUERY, QUERY);
t.truthy(response.TRACK.count > 0); t.truthy(response.TRACK.count > 0);
t.truthy(response.ALBUM.count > 0); t.truthy(response.ALBUM.count > 0);
t.truthy(response.ARTIST.count > 0); t.truthy(response.ARTIST.count > 0);

View File

@ -1,4 +1,4 @@
import {request, requestGet, requestPublicApi} from './request'; import {request, requestLight, requestGet, requestPublicApi} from './request';
import type { import type {
albumType, albumType,
trackType, trackType,
@ -113,7 +113,7 @@ type searchTypesProp = 'ALBUM' | 'ARTIST' | 'TRACK' | 'PLAYLIST' | 'RADIO' | 'SH
* @param {Number} nb number of items to fetch * @param {Number} nb number of items to fetch
*/ */
export const searchMusic = (query: string, types: searchTypesProp[] = ['TRACK'], nb = 15): Promise<searchType> => export const searchMusic = (query: string, types: searchTypesProp[] = ['TRACK'], nb = 15): Promise<searchType> =>
request({query, nb, types}, 'mobile_suggest'); requestLight({query, start: 0, nb, suggest: true, artist_suggest: true, top_tracks: true}, 'deezer.pageSearch');
/** /**
* Get details about current user * Get details about current user

View File

@ -26,6 +26,32 @@ export const request = async (body: object, method: string) => {
throw new Error(errorMessage); throw new Error(errorMessage);
}; };
/**
* Make POST requests to deezer api
* @param {Object} body post body
* @param {String} method request method
*/
export const requestLight = async (body: object, method: string) => {
const cacheKey = method + ':' + Object.entries(body).join(':');
const cache = lru.get(cacheKey);
if (cache) {
return cache;
}
const {
data: {error, results},
} = await axios.post<any>('https://www.deezer.com/ajax/gw-light.php', body, {
params: {method, api_version: '1.0'},
});
if (Object.keys(results).length > 0) {
lru.set(cacheKey, results);
return results;
}
const errorMessage = Object.entries(error).join(', ');
throw new Error(errorMessage);
};
/** /**
* Make GET requests to deezer public api * Make GET requests to deezer public api
* @param {String} method request method * @param {String} method request method

View File

@ -28,6 +28,19 @@ const instance = axios.create({
}, },
}); });
const getApiToken = async (): Promise<string> => {
const {data} = await instance.get<any>('https://www.deezer.com/ajax/gw-light.php', {
params: {
method: 'deezer.getUserData',
api_version: '1.0',
api_token: 'null',
},
});
instance.defaults.params.sid = data.results.SESSION_ID;
instance.defaults.params.api_token = data.results.checkForm;
return data.results.checkForm;
};
export const initDeezerApi = async (arl: string): Promise<string> => { export const initDeezerApi = async (arl: string): Promise<string> => {
if (arl.length !== 192) { if (arl.length !== 192) {
throw new Error(`Invalid arl. Length should be 192 characters. You have provided ${arl.length} characters.`); throw new Error(`Invalid arl. Length should be 192 characters. You have provided ${arl.length} characters.`);
@ -50,6 +63,9 @@ instance.interceptors.response.use(async (response: Record<string, any>) => {
} else if (response.data.error.code === 4) { } else if (response.data.error.code === 4) {
await delay.range(1000, 1500); await delay.range(1000, 1500);
return await instance(response.config); return await instance(response.config);
} else if (response.data.error.GATEWAY_ERROR) {
getApiToken();
return await instance(response.config);
} }
} }