-
Notifications
You must be signed in to change notification settings - Fork 12
Closed
Description
Get Tweet and Tweets By ID are not returning nearly any of the fields being requested regardless of passing them.
I replaced the entire XDK with a normal fetch and am now receiving the requested data.
This file will give you an idea of exactly how to replicate it by swapping the functions back and uncommenting the import.
// import { Client } from '@xdevplatform/xdk'
const TWEET_FIELDS = {
expansions: [
// 'article.cover_media',
// 'article.media_entities',
'attachments.media_keys',
// 'attachments.media_source_tweet',
// 'attachments.poll_ids',
'author_id',
// 'edit_history_tweet_ids',
'entities.mentions.username',
// 'geo.place_id',
'in_reply_to_user_id',
// 'entities.note.mentions.username',
// 'referenced_tweets.id',
// 'referenced_tweets.id.attachments.media_keys',
// 'referenced_tweets.id.author_id',
],
'tweet.fields': [
// 'article',
'attachments',
'author_id',
// 'card_uri',
'community_id',
// 'context_annotations',
'conversation_id',
'created_at',
// 'display_text_range',
// 'edit_controls',
// 'edit_history_tweet_ids',
'entities',
// 'geo',
'id',
'in_reply_to_user_id',
'lang',
'media_metadata',
// 'non_public_metrics',
// 'note_tweet',
// 'organic_metrics',
'possibly_sensitive',
// 'promoted_metrics',
'public_metrics',
// 'referenced_tweets',
// 'reply_settings',
// 'scopes',
// 'source',
// 'suggested_source_links',
'text',
// 'withheld',
],
'user.fields': [
// 'affiliation',
'confirmed_email',
// 'connection_status',
// 'created_at',
'description',
// 'entities',
'id',
'is_identity_verified',
'location',
// 'most_recent_tweet_id',
'name',
// 'parody',
// 'pinned_tweet_id',
'profile_banner_url',
'profile_image_url',
'protected',
'public_metrics',
// 'receives_your_dm',
// 'subscription',
// 'subscription_type',
'url',
'username',
'verified',
'verified_followers_count',
'verified_type',
// 'withheld',
],
'media.fields': [
'alt_text',
'duration_ms',
'height',
'media_key',
// 'non_public_metrics',
// 'organic_metrics',
'preview_image_url',
// 'promoted_metrics',
'public_metrics',
'type',
'url',
'variants',
'width',
],
// 'place.fields': [
// 'contained_within',
// 'country',
// 'country_code',
// 'full_name',
// 'geo',
// 'id',
// 'name',
// 'place_type',
// ],
//
// 'poll.fields': [
// 'duration_minutes',
// 'end_datetime',
// 'id',
// 'options',
// 'voting_status',
// ],
}
// export function getXClient(bearerToken: string) {
// const config = { bearerToken }
// return new Client(config)
// }
//
// export async function getTweetFromXApi(tweetId: string, bearerToken: string) {
// const client = getXClient(bearerToken)
// return await client.posts.getById(tweetId, TWEET_FIELDS)
// }
//
// export async function getTweetsFromXApi(
// tweetIds: string[],
// bearerToken: string,
// ) {
// const client = getXClient(bearerToken)
// return await client.posts.getByIds(tweetIds, TWEET_FIELDS)
// }
const API_BASE = 'https://api.x.com/2'
function buildQueryParams(fields: Record<string, any>): URLSearchParams {
const params = new URLSearchParams()
// expansions
if (fields.expansions?.length) {
params.append('expansions', fields.expansions.join(','))
}
// tweet.fields, user.fields, media.fields … (any key that ends with ".fields")
for (const [key, value] of Object.entries(fields)) {
if (key.endsWith('.fields') && Array.isArray(value) && value.length) {
params.append(key, value.join(','))
}
}
return params
}
export async function getTweetFromXApi(
tweetId: string,
bearerToken: string,
): Promise<any> {
const url = new URL(`${API_BASE}/tweets/${tweetId}`)
url.search = buildQueryParams(TWEET_FIELDS).toString()
const res = await fetch(url.toString(), {
method: 'GET',
headers: {
Authorization: `Bearer ${bearerToken}`,
'User-Agent': 'X-Fetch-Client/1.0',
},
})
if (!res.ok) {
const err = await res.text()
throw new Error(`X API error ${res.status}: ${err}`)
}
return await res.json()
}
export async function getTweetsFromXApi(
tweetIds: string[],
bearerToken: string,
): Promise<any> {
if (!tweetIds.length) return { data: [] }
const url = new URL(`${API_BASE}/tweets`)
url.searchParams.append('ids', tweetIds.join(',')) // ids=… is required
url.search = buildQueryParams(TWEET_FIELDS).toString() // append the rest
const res = await fetch(url.toString(), {
method: 'GET',
headers: {
Authorization: `Bearer ${bearerToken}`,
'User-Agent': 'X-Fetch-Client/1.0',
},
})
if (!res.ok) {
const err = await res.text()
throw new Error(`X API error ${res.status}: ${err}`)
}
return await res.json()
}Metadata
Metadata
Assignees
Labels
No labels