API timeline - one entire week - api

I'm new to API and Twitter
I managed to retrieve the 'normal' 20 Tweets (Status)
Is there a way to retrieve a whole week at once?
Or do I have to write a code that permanently calls 20 Tweets and append each after the other?

You can get whole week of tweet by Get User's lookup Tweet V2 API
OR
Get timeline for user by V1.1 API
Tweet User's lookup V2
GET /2/users/{user id}/tweets
get tweet time line by V1.1 API
GET statuses/user_timeline
I will demo both with Mr. Tweet by Postman.
#1 Get access token in here
This token support both V2 and V1.1 API call.
#2 Get Tweets one week by v2
https://api.twitter.com/2/users/44196397/tweets?max_results=20&start_time=2023-01-18T00:00:01Z&end_time=2023-01-25T00:00:01Z
If you want to more detail information for each tweet.
Add attribute option in here by Adding query parameters(like a like count, create at and so on)
#3 Get timeline, 20 Tweets by v1.1
Timeline API Two methods in here
https://api.twitter.com/2/users/:id/timelines/reverse_chronological
OR
https://api.twitter.com/2/users/:id/tweets
Demo for get tweet with 2nd methods
https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=elonmusk&count=20
Both API needs access token assignment
Both API can be programming by node.js or Python languages.
const axios = require('axios')
const API_KEY = '<your API Key>'
const API_KEY_SECRET = '<your API Secret>'
const getToken = async () => {
try {
const resp = await axios.post(
url = 'https://api.twitter.com/oauth2/token',
data = '',
config = {
params: {
'grant_type': 'client_credentials'
},
auth: {
username: API_KEY,
password: API_KEY_SECRET
}
}
);
return Promise.resolve(resp.data.access_token);
} catch (err) {
console.error(err)
return Promise.reject(err)
}
};
const getUserId = async (username, token) => {
try {
const resp = await axios.get(
url = `https://api.twitter.com/2/users/by/username/${username}`,
config = {
headers: {
'Accept-Encoding': 'application/json',
'Authorization': `Bearer ${token}`,
}
}
);
// { data: { id: '44196397', name: 'Elon Musk', username: 'elonmusk' } }
return Promise.resolve(resp.data.data.id)
} catch (err) {
return Promise.reject(err)
}
};
const getTweetTimeline = async (user_id, start_date, end_date, token) => {
try {
const tweets = [];
let index = 1
let next_token = 'start'
while (next_token != null) {
let url = `https://api.twitter.com/2/users/${user_id}/tweets?start_time=${start_date}&end_time=${end_date}&tweet.fields=created_at&max_results=20`
if (next_token != 'start') {
url = `https://api.twitter.com/2/users/${user_id}/tweets?start_time=${start_date}&end_time=${end_date}&tweet.fields=created_at&max_results=20&pagination_token=${next_token}`
}
const resp = await axios.get(
url = url,
config = {
headers: {
'Accept-Encoding': 'application/json',
'Authorization': `Bearer ${token}`,
}
}
);
for(const item of resp.data.data) {
tweets.push({
index : index,
created_at: item.created_at,
text: item.text,
id : item.id
})
index = index + 1
}
next_token = resp.data.meta.next_token
}
return Promise.resolve(tweets)
} catch (err) {
console.error(err)
return Promise.reject(err)
}
}
getToken()
.then(token => {
console.log(token);
getUserId('elonmusk', token)
.then(user_id => {
getTweetTimeline(user_id,'2023-02-05T00:00:00Z','2023-02-11T23:59:59Z', token)
.then(tweets => {
for(const tweet of tweets) {
console.log(tweet)
}
})
.catch(error => {
console.log(error.message);
});
})
.catch(error => {
console.log(error.message);
});
})
.catch(error => {
console.log(error.message);
});
Result
node get-tweet.js > result.json

Related

How to use Spotify 30sec previews with Expo React native app

I have been trying to use the Spotify API in my expo app but every tutorial or wrapper I find doesn't seem to work.
I would specifically like to access the 30-second song previews and track/song searching features.
If anyone could provide some guidance or point me towards a working demo of any kind that would be awesome.
Thanks!
Found parts of the solution in https://docs.expo.dev/guides/authentication/#spotify
const discovery = {
authorizationEndpoint: 'https://accounts.spotify.com/authorize',
tokenEndpoint: 'https://accounts.spotify.com/api/token',
};
var client_id = ''; // Your client id
var client_secret = ''; // Your secret
export default function spotifyLogin(props) {
const [request, response, promptAsync] = useAuthRequest(
{
clientId: '',
scopes: ['user-read-email', 'user-read-playback-state', 'playlist-modify-public','playlist-modify-private','playlist-modify-public','playlist-read-private','user-read-recently-played'],
// In order to follow the "Authorization Code Flow" to fetch token after authorizationEndpoint
// this must be set to false
usePKCE: false,
redirectUri: makeRedirectUri({
//scheme: 'your.app'
}),
},
discovery
);
React.useEffect(() => {
if (response?.type === 'success') {
const { code } = response.params;
//save code to local storage
props.saveLogin(code)
}
}, [response]);
return (
<Button
disabled={!request}
title="Login"
onPress={() => {
promptAsync();
}}
/>
);
}
export const getFirstTokenData = async (code) => {
var dataToSend = {
code: code,
redirect_uri: makeRedirectUri(),
grant_type: 'authorization_code'};
//making data to send on server
var formBody = [];
for (var key in dataToSend) {
var encodedKey = encodeURIComponent(key);
var encodedValue = encodeURIComponent(dataToSend[key]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
//POST request
var response = await fetch('https://accounts.spotify.com/api/token', {
method: 'POST', //Request Type
body: formBody, //post body
headers: {
//Header Defination
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')),
},
})
try{
return await response.json()
}catch (error){
console.log(error)
}
}
export const getRefreshTokenData = async (refreshToken) => {
console.log(refreshToken)
console.log(refreshToken + " going in for refresh")
var dataToSend = {
refresh_token : refreshToken,
grant_type: 'refresh_token'};
//making data to send on server
var formBody = [];
for (var key in dataToSend) {
var encodedKey = encodeURIComponent(key);
var encodedValue = encodeURIComponent(dataToSend[key]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
//POST request
var response = await fetch('https://accounts.spotify.com/api/token', {
method: 'POST', //Request Type
body: formBody, //post body
headers: {
//Header Defination
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')),
},
})
try{
return await response.json()
}catch (error){
console.log(error)
}
}
The above takes care of auth and getting refresh tokens, below takes care of searching for a track. To get 30 second previews there is a preview property in the return data for getTrack()
const apiPrefix = 'https://api.spotify.com/v1';
export default async ({
offset,
limit,
q,
token,
}) => {
const uri = `${apiPrefix}/search?type=track&limit=${limit}&offset=${offset}&q=${encodeURIComponent(q)}`;
console.log('search begin, uri =', uri, 'token =', token);
const res = await fetch(uri, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
}
});
const json = await res.json();
//console.log('search got json', json);
if (!res.ok) {
return [];
}
return json
// const {
// tracks: {
// items,
// }
// } = json;
// // const items = json.tracks.items;
// return items.map(item => ({
// id: item.id,
// title: item.name,
// imageUri: item.album.images
// ? item.album.images[0].url
// : undefined
// }));
console.log('search end');
};
export const getTrack = async(trackID, token) => {
const uri = `${apiPrefix}/tracks/${trackID}?market=ES`;
const res = await fetch(uri, {
method: 'GET',
headers: {
// Accept: `application/json`,
// Content-Type: `application/json`,
Authorization: `Bearer ${token}`,
}
});
const json = await res.json();
//console.log('search got json', json);
if (!res.ok) {
return [];
}
return json
}
Once upon a time, I worked on a similar application as a test. It's a bit outdated, but I believe Spotify has not changed its API much in the meantime.
Hope this caa help
https://github.com/kubanac95/spotify-test

RN "TypeError: Network request failed" - production - random

I know some questions about the subject has been opened here and there, but my issue is different :
all the other ones appear in dev mode, in my case it's in production,
a very big percentage of requests pass, a few of them is TypeError: Network request failed - but sometimes for critical requests
it's random, not always the same request. Sometimes it passes, sometimes not.
it appears to three on my projects, one is on AWS the other one on Clever-Cloud, both are projects between 1000 and 5000 users, servers are quite too big for what they do - I think I removed the risk of a server fault. Even if... I can reproduce locally when I don't start the api locally. So it's like the api is not responding, but as I said, I don't think so.
I have no clue where to dig anymore...
I can give you my API.js service file, maybe you'll find what's wrong ?
import URI from 'urijs';
import { Platform } from 'react-native';
import NetInfo from '#react-native-community/netinfo';
import { getUserToken, wipeData } from '../utils/data';
import { SCHEME, MW_API_HOST } from '../config';
import deviceInfoModule from 'react-native-device-info';
import { capture } from '../utils/sentry';
const unauthorisedHandler = (navigation) => {
wipeData();
navigation.reset({ index: 0, routes: [{ name: 'Auth' }] });
};
const checkNetwork = async (test = false) => {
const isConnected = await NetInfo.fetch().then((state) => state.isConnected);
if (!isConnected || test) {
await new Promise((res) => setTimeout(res, 1500));
return false;
}
return true;
};
class ApiService {
host = MW_API_HOST;
scheme = SCHEME;
getUrl = (path, query) => {
return new URI().host(this.host).scheme(this.scheme).path(path).setSearch(query).toString();
};
execute = async ({ method = 'GET', path = '', query = {}, headers = {}, body = null }) => {
try {
const config = {
method,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
appversion: deviceInfoModule.getBuildNumber(),
appdevice: Platform.OS,
currentroute: this.navigation?.getCurrentRoute?.()?.name,
...headers,
},
body: body ? JSON.stringify(body) : null,
};
const url = this.getUrl(path, query);
console.log('url: ', url);
const canFetch = await checkNetwork();
if (!canFetch) return;
let response;
// To try to avoid mysterious `TypeError: Network request failed` error
// that throws an error directly
// we try catch and try one more time.
try {
response = await fetch(url, config);
} catch (e) {
if (e?.toString().includes('Network request failed')) {
// try again
await new Promise((res) => setTimeout(res, 250));
console.log('try again because Network request failed');
response = await fetch(url, config);
} else {
throw e;
}
}
if (!response.ok) {
if (response.status === 401) {
const token = await getUserToken();
if (token) unauthorisedHandler(API.navigation);
return response;
}
}
if (response.json) return await response.json();
return response;
} catch (e) {
capture(e, { extra: { method, path, query, headers, body } });
return { ok: false, error: "Sorry, an error occured, technical team has been warned." };
}
};
executeWithToken = async ({ method = 'GET', path = '', query = {}, headers = {}, body = null }) => {
const token = await getUserToken();
if (token) headers.Authorization = token;
return this.execute({ method, path, query, headers, body });
};
get = async (args) => this.executeWithToken({ method: 'GET', ...args });
post = async (args) => this.executeWithToken({ method: 'POST', ...args });
put = async (args) => this.executeWithToken({ method: 'PUT', ...args });
delete = async (args) => this.executeWithToken({ method: 'DELETE', ...args });
}
const API = new ApiService();
export default API;
Talking with experts here and there, it seems that it's normal : internet network is not 100% reliable, so sometimes, request fail, for a reason that we can't anticipate (tunnel, whatever).
I ended up using fetch-retry and I still have a few of those, but much less !

Make a get request until a response comes from a request post vue js

I should upload file in my vue.js app. When I browse a file, I make post request and until I get a response, I need to make get request every 2 seconds for example. How can I do this?
uploadFile(event) {
this.isLoadingProcess = true;
console.log(this.isLoadingProcess);
let data = new FormData();
this.file = event.target.files[0];
data.append('name', 'uploaded-file');
data.append('file', event.target.files[0]);
const options = {
headers: {
'Content-Type': event.target.files[0].type,
},
onUploadProgress: function (progressEvent) {
const {loaded, total} = progressEvent;
let percentCompleted = Math.floor((loaded * 100) / total);
//console.log(percentCompleted);
if (percentCompleted !== 100) {
axios.get(url, {data: progressId})
.then(response => {
this.progress = response.data.progress;
// console.log(this.progress);
console.log(response.data.progress);
})
}
},
};
axios.post(
url,
data,
options
)
.then(response => {
console.log(response);
})
.finally(()=> {
this.isLoadingProcess = false;
})
what about this?
It asks api about update more than every 2 seconds, but It's better for my opinion in case, when endpoint isn't available
var processTimeoutFunction = null;
function checkProgress() {
axios.get('ckeck-process', ...).then(response => {
if (response.processIsActive) {
processTimeoutFunction = setTimeout(() => checkProgress(), 2000);
} else {
clearTimeout(processTimeoutFunction);
this.isLoadingProcess = false;
})
}

How to passing result of http request inside async in ExpressJS?

I have below code
async send(user, data) {
const postData = {
'data': 'john',
'secret': 'secret'
};
const dataJson = JSON.stringify(postData);
const options = {
hostname: 'example.com',
path: '/send',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': dataJson.length
}
};
const req = https.request(options, (res) => {
let data = '';
console.log('Status Code:', res.statusCode);
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Body: ', JSON.parse(data));
});
}).on("error", (err) => {
console.log("Error: ", err.message);
});
req.write(dataJson);
req.end();
//---------------
let postResult = // HERE I WANT TO GET WHAT HTTP POST REQUESTED (e.g dataJson.body?)
//---------------
let result;
try {
result = await this.users.collection('users').updateOne(
{
_id: user
},
{
$set: {
// I WANT TO USE THAT HERE
data1 : postResult,
data2 : data2
}
},
{ maxTimeMS: consts.DB_MAX_TIME_USERS }
);
} catch (err) {
log.error('DB', 'UPDATEFAIL id=%s error=%s', user, err.message);
err.message = 'Database Error, failed to update user';
err.code = 'InternalDatabaseError';
throw err;
}
return { success: true };
}
How to get those data to outside variable?
I almost crazy about this, been searching on google and not found anything
I am using express and native-http to make http request, are there any native-curl maybe?
thank you very much for all the help
Your current code is using callback to retrieve result, so you can initiate data variable to outside callback function
let data = '';
const req = https.request(options, (res) => {
console.log('Status Code:', res.statusCode);
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Body: ', JSON.parse(data));
});
})
And also there are other easier way to make http request with nodejs. you can check axios that support Promise and async/await.
you can use syntax like this with axios
const response = await axios.get('/user?ID=12345');
way more easier.

React Native - FETCH Response is empty - API Status 500 - POST Call

signIn = () => {
//post data to express backend
fetch('http://10.0.2.2:3000/api/v1/auth', {
method: 'POST',
header: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: `login=${this.state.login}&password=${this.state.password}`
})
.then((response) => response.json())
.then ((res => {
if(res.status === 200) {
AsyncStorage.setItem('user', this.state.login);
this.props.navigation.navigate('Authorized')
} else {
alert("Response:", res);
}
}))
.done();
}
The above is for React-Native. And below is the express backend:
router.post('/', function(req,res){
var login= req.body.login;
var password = req.body.password;
var sql = `SELECT * FROM users WHERE username = '${login}' OR number = '${login}' AND password = ${password}`
db.query(sql, function (err, rows, fields) {
if (err) {
res.status(500).send({error: 'Something went wrong!'})
} else {
if(rows.length > 0) {
if (rows[0].password == password) {
res.status(200).send({success: 'Login Successful'})
}
} else {
res.status(404).send({error: 'Email or Password does not match!'})
}
}
})
});
I think there is nothing getting into a response or maybe some other problem which I am unable to figure out the moment.