Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: Cannot read property 'clientId' of undefined #15

Open
sarmadfolio3 opened this issue Feb 10, 2022 · 7 comments
Open

TypeError: Cannot read property 'clientId' of undefined #15

sarmadfolio3 opened this issue Feb 10, 2022 · 7 comments

Comments

@sarmadfolio3
Copy link

When trying to invoke the getApplicationToken function with proper credentials it throws an error in the console TypeError: Cannot read property 'clientId' of undefined.

Framwork: NestJs with TypeScript

@dhruvxylisys
Copy link

dhruvxylisys commented Feb 24, 2022

@sarmadfolio3, I have also got the same error of clinetId undefined, I have passed "env" : "SANDBOX" in EbayAuthToken object and resolved an error, please try it

const EbayAuthToken = require("ebay-oauth-nodejs-client");
    const ebayAuthToken = new EbayAuthToken({
         clientId:---Your client id---,
         env: "SANDBOX",
         clientSecret: ---Your Client secret id---
         redirectUri: ---Your redirect URL---
    });
    let token = await ebayAuthToken.getApplicationToken("SANDBOX");
    token = JSON.parse(token)

@joeymigs
Copy link

Having the same issue here.

@b5414
Copy link

b5414 commented Dec 25, 2023

same

@b5414
Copy link

b5414 commented Dec 25, 2023

const ebayAuthToken = new EbayAuthToken({
	clientId: 'clientId_clientId_clientId',
	clientSecret: 'clientSecret_clientSecret_clientSecret',
	redirectUri: 'redirectUri_redirectUri_redirectUri',
	env: 'SANDBOX',
});

const response = await ebayAuthToken.getApplicationToken('SANDBOX');
const token = JSON.parse(response).access_token;

// or
const token = await ebayAuthToken.getApplicationToken('SANDBOX').then(JSON.parse).then(({access_token})=>access_token);

// or
const token = await ebayAuthToken.getApplicationToken('SANDBOX').then((r)=>JSON.parse(r).access_token);

// or
const {access_token: token} = await ebayAuthToken.getApplicationToken('SANDBOX').then(JSON.parse);

@Goldziher
Copy link

same issue.

It works when I use env: "SANDBOX". But when i switch to using the production credentials (clientId, clientSecret and redirectUri) and switch to using env: "PRODUCTION", it repeats the issue.

Any chance for some maintainer attention?

@nonInfelix
Copy link

any solution?

@Goldziher
Copy link

any solution?

I'm posting the client I ended up writing:

import { InvocationContext } from '@azure/functions';
import EbayAuthToken from 'ebay-oauth-nodejs-client';

import { HttpMethod } from '@/constants/generic.js';
import {
	EbayBrowseItemsErrorResponse,
	EbayBrowseItemsSuccessResponse,
} from '@/ebay/types.js';
import { parseEbayResponse } from '@/ebay/utils.js';
import { FindProductsParameters } from '@/types.js';
import { loadEnv } from '@/utils/env.js';
import { ConfigurationError } from '@/utils/errors.js';
import { fetcher } from '@/utils/fetcher.js';

const EBAY_AFFILIATE_HEADER = 'X-EBAY-C-ENDUSERCTX';
const EBAY_MARKETPLACE_HEADER = 'X-EBAY-C-MARKETPLACE-ID';
const EBAY_BROWSE_API_ITEMS_SUMMARY_ENDPOINT =
	'/buy/browse/v1/item_summary/search';
const EBAY_API_BASE_URL_PRODUCTION = 'https://api.ebay.com';
const EBAY_API_BASE_URL_SANDBOX = 'https://api.sandbox.ebay.com';

const isErrResponse = (
	value:
		| EbayBrowseItemsErrorResponse
		| EbayBrowseItemsSuccessResponse
		| Record<string, never>,
): value is EbayBrowseItemsErrorResponse => Reflect.has(value, 'warnings');

const isSuccessResponse = (
	value: EbayBrowseItemsSuccessResponse | Record<string, never>,
): value is EbayBrowseItemsSuccessResponse =>
	Reflect.has(value, 'itemSummaries');

export class EbayClient {
	private readonly auth: EbayAuthToken;
	private readonly baseUrl: string;
	private readonly ebayCampaignId: string;
	private readonly ebayEnv: 'PRODUCTION' | 'SANDBOX';

	private apiAccessToken: { expiration: number; value: string } | null = null;

	constructor() {
		const ebayEnv = (this.ebayEnv = loadEnv<'PRODUCTION' | 'SANDBOX'>(
			'EBAY_ENV',
		));

		this.ebayCampaignId = loadEnv('EBAY_CAMPAIGN_ID');

		const clientSecret = loadEnv(`EBAY_${ebayEnv}_CLIENT_SECRET`);
		const clientId = loadEnv(`EBAY_${ebayEnv}_CLIENT_ID`);
		const redirectUri = loadEnv(`EBAY_${ebayEnv}_REDIRECT_URI`);

		this.auth = new EbayAuthToken({
			clientId,
			clientSecret,
			env: ebayEnv,
			redirectUri,
		});

		this.baseUrl =
			ebayEnv === 'PRODUCTION'
				? EBAY_API_BASE_URL_PRODUCTION
				: EBAY_API_BASE_URL_SANDBOX;
	}

	async getToken() {
		if (
			this.apiAccessToken &&
			this.apiAccessToken.expiration < Date.now()
		) {
			return this.apiAccessToken.value;
		}

		const encodedToken = await this.auth.getApplicationToken(this.ebayEnv);
		const { access_token, expires_in } = JSON.parse(encodedToken) as {
			access_token: string;
			expires_in: number;
			token_type: string;
		};

		this.apiAccessToken = {
			expiration: Date.now() + expires_in * 1000,
			value: access_token,
		};

		return access_token;
	}

	async search(
		context: InvocationContext,
		{
			keywords,
			minPrice,
			maxPrice,
			allowRefurbished,
		}: FindProductsParameters,
	) {
		const filters = [
			'deliveryCountry:US',
			'buyingOptions:{FIXED_PRICE}',
			// see: https://developer.ebay.com/devzone/finding/callref/Enums/conditionIdList.html
			`conditionIds:{1000|1500${allowRefurbished ? '|2000|2010|2020|2030|2500' : ''}}`,
		];

		if (minPrice ?? maxPrice) {
			filters.push(
				'priceCurrency:USD',
				minPrice === undefined
					? `price:[..${maxPrice}]`
					: maxPrice === undefined
						? `price:[${minPrice}]`
						: `price:[${minPrice}..${maxPrice}]`,
			);
		}

		const queryParams = {
			auto_correct: 'KEYWORD',
			fieldgroups: 'EXTENDED,MATCHING_ITEMS',
			filter: filters.join(','),
			limit: '25',
			// the keyword combinations have an OR relation
			// see: https://developer.ebay.com/api-docs/buy/browse/resources/item_summary/methods/search
			q: `(${keywords.join(', ')})`,
		};

		const response = await fetcher<
			| EbayBrowseItemsSuccessResponse
			| EbayBrowseItemsErrorResponse
			| Record<string, never>
		>({
			headers: {
				Authorization: `Bearer ${await this.getToken()}`,
				[EBAY_AFFILIATE_HEADER]: `affiliateCampaignId=${this.ebayCampaignId}`,
				[EBAY_MARKETPLACE_HEADER]: 'EBAY_US',
			},
			method: HttpMethod.Get,
			queryParams,
			url: this.baseUrl + EBAY_BROWSE_API_ITEMS_SUMMARY_ENDPOINT,
		});

		if (isErrResponse(response)) {
			context.warn('ebay warnings', response.warnings);
			throw new ConfigurationError(
				'ebay API returned warnings',
				response.warnings,
			);
		}

		if (isSuccessResponse(response)) {
			return parseEbayResponse(response);
		}

		return null;
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants