Created
May 5, 2024 23:04
-
-
Save Lukas1h/ce7d74009ef74a0a226b4e0f1fad93bf to your computer and use it in GitHub Desktop.
Source Code for ShrekBot on BeReal. Very messy.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fs from 'fs/promises'; | |
import * as readline from "readline" | |
import axios from "axios"; | |
import sharp from 'sharp'; | |
import moment from 'moment'; | |
import getHeaders from 'happy-headers'; | |
var args = process.argv.slice(2); | |
//78 | |
let oldToken = await fs.readFile("token.txt") | |
// | |
console.log(oldToken.toString()) | |
let tokens = { | |
access_token: null, | |
refresh_token: oldToken.toString(), | |
token_expiration:1714494844192 | |
} | |
tokens = await getTokens(tokens) | |
tokens.token_expiration=1714494844192 | |
console.log(JSON.stringify(tokens)) | |
if (tokens.access_token == null || tokens.access_token == ""){ | |
console.log("Failed to get tokens.") | |
} | |
await fs.writeFile("token.txt",tokens.refresh_token) | |
console.log(` | |
1. Upload BeReal | |
2. Get friends | |
3. React to all friends of friends. | |
`) | |
let choice = args[0] || (await prompt("What do you want to do?\n> ")) | |
if(choice == "1"){//Upload. | |
function getRandomIntAsString(min, max) { | |
const randomInt = Math.floor(Math.random() * (max - min + 1)) + min; | |
return randomInt.toString().padStart(3, '0'); | |
} | |
let videoNum = await prompt("What video number? ") //4 | |
console.log("Uploading...") | |
const fileBuffer = await fs.readFile(`./media/shreak-split/video-${videoNum}.mp4`); | |
const image1Buffer = await fs.readFile(`./media/stils/output_${getRandomIntAsString(8,80)}.png`); | |
const image2Buffer = await fs.readFile(`./media/stils/output_${getRandomIntAsString(8,80)}.png`); | |
async function uploadPost(tokens){ | |
let token = tokens.access_token | |
let randomDate = moment().utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'); | |
await axios.get(`https://mobile.bereal.com/api/bereal/moments/last/${"us-central"}`) | |
.then(response => { | |
let dateA = moment(response.data.startDate, "YYYY-MM-DDTHH:mm:ss.SSSZ"); | |
let dateB = moment(response.data.endDate, "YYYY-MM-DDTHH:mm:ss.SSSZ"); | |
let diff = dateB.diff(dateA); | |
let randomMillis = Math.random() * diff; | |
randomDate = dateA.add(randomMillis, 'milliseconds').utc().format("YYYY-MM-DDTHH:mm:ss.SSS[Z]"); | |
}) | |
let {visibility, isLate, retakes, region } = { | |
visibility:"friends", | |
isLate:false, | |
region:"us-central", | |
retakeCounter:"1", | |
} | |
// btsb64 = btsb64.replace(/^data:(image|application)\/(png|webp|jpeg|jpg|gif|svg\+xml|octet-stream);base64,/, ''); | |
// let sharp_primary = Buffer.from(primaryb64, 'base64'); | |
// let sharp_secondary = Buffer.from(secondaryb64, 'base64'); | |
let primary_image_buffer = image1Buffer | |
let secondary_image_buffer = image2Buffer | |
let sharp_primary = await sharp(primary_image_buffer).toBuffer(); | |
let sharp_secondary = await sharp(secondary_image_buffer).toBuffer(); | |
let sharp_bts = fileBuffer | |
const primary_mime_type = (await sharp(sharp_primary).metadata()).format; | |
const secondary_mime_type = (await sharp(sharp_secondary).metadata()).format; | |
if (primary_mime_type != 'webp') { | |
sharp_primary = await sharp(sharp_primary).toFormat('webp').toBuffer(); | |
} | |
if (secondary_mime_type != 'webp') { | |
sharp_secondary = await sharp(sharp_secondary).toFormat('webp').toBuffer(); | |
} | |
let uploadRes = await axios.get('https://mobile.bereal.com/api/content/posts/multi-format-upload-url?mimeTypes=image/webp&mimeTypes=video/mp4', { | |
headers: { | |
'Authorization': `Bearer ${token}`, | |
...getHeaders() | |
} | |
}); | |
// let uploadRes = await axios.get('https://mobile.bereal.com/api/content/posts/upload-url?mimeType=image/webp', { | |
// headers: { | |
// 'Authorization': `Bearer ${token}`, | |
// ...getHeaders() | |
// } | |
// }); | |
// let btsUploadResponce = await axios.get('https://mobile.bereal.com/api/content/posts/multi-format-upload-url?mimeTypes=image/webp&mimeTypes=video%2Fmp4', { | |
// headers: { | |
// 'Authorization': `Bearer ${token}`, | |
// ...getHeaders() | |
// } | |
// }); | |
console.log(uploadRes.data) | |
// return | |
let [primaryRes, btsRes, secondaryRes] = uploadRes.data.data; | |
let primaryHeaders = { | |
...primaryRes.headers, | |
'Authorization': `Bearer ${token}`, | |
...getHeaders() | |
}; | |
let btsHeaders = { | |
...btsRes.headers, | |
'Authorization': `Bearer ${token}`, | |
...getHeaders() | |
}; | |
let secondaryHeaders = { | |
...secondaryRes.headers, | |
'Authorization': `Bearer ${token}`, | |
...getHeaders() | |
}; | |
await Promise.all([ | |
axios.put(primaryRes.url, sharp_primary, { headers: primaryHeaders }), | |
axios.put(btsRes.url, sharp_bts, { headers: btsHeaders }), | |
axios.put(secondaryRes.url, sharp_secondary, { headers: secondaryHeaders }) | |
// axios.put(secondaryRes.url, sharp_secondary, { headers: secondaryHeaders }) | |
]); | |
let postData = { | |
isLate: isLate, | |
retakeCounter: 1, | |
takenAt: randomDate, | |
visibility: [visibility], | |
backCamera: { | |
bucket: primaryRes.bucket, | |
height: 1500, | |
width: 2000, | |
path: primaryRes.path, | |
}, | |
frontCamera: { | |
bucket: secondaryRes.bucket, | |
height: 1500, | |
width: 2000, | |
path: secondaryRes.path, | |
}, | |
btsMedia: { | |
bucket: btsRes.bucket, | |
height: 1500, | |
width: 2000, | |
path: btsRes.path, | |
"mediaType": "video" | |
}, | |
postType:'bts', | |
// "caption": "Built by @lukas__with__a__k", | |
// caption:`Day ${videoNum+1} of Shrek!`, | |
// tags:["@lukas__with__a__k"] | |
// Ajouter la location | |
}; | |
let postResponse = await axios.post('https://mobile.bereal.com/api/content/posts', postData, { | |
headers: { | |
'Authorization': `Bearer ${token}`, | |
...getHeaders() | |
}, | |
}); | |
// console.log(postResponse.data.id) | |
// let id = postResponse.data.id | |
// console.log(`https://mobile.bereal.com/api/content/posts/upload-bts?postId=${id}`) | |
// let btsUploadResponce = await axios.get(`https://mobile.bereal.com/api/content/posts/upload-bts?postId=bKANiPObYIANfvUXxyBZp`, { | |
// headers: { | |
// 'Authorization': `Bearer ${token}`, | |
// ...getHeaders() | |
// } | |
// }); | |
// console.log(btsUploadResponce) | |
return postResponse.data | |
} | |
let feed = await uploadPost(tokens) | |
console.log(feed) | |
} | |
if(choice == "2"){//Friends amount. | |
let feed = await getFriends(tokens) | |
console.log("You have "+feed.length+" friends.") | |
} | |
if(choice == "3"){//Friend request all friends of friends. | |
console.log("Sending to all friends...") | |
let feed = await getFof(tokens) | |
// console.log(feed) | |
for (let post of feed){ | |
// console.log(post) | |
try{ | |
let friendRes = await sendRealmoji(tokens,post) | |
console.log(friendRes.emoji) | |
}catch{ | |
console.log("Unable to sendRealmoji") | |
} | |
try{ | |
let friendRes = await makeFriend(tokens,post.user.id) | |
console.log("makeFriend") | |
}catch{ | |
console.log("Unable to makeFriend") | |
} | |
} | |
} | |
// if(choice == "4"){//Send request to ID | |
// // let id = await prompt("What id? ") | |
// let friends = await getFriendsFeed(tokens) | |
// console.log(friendRes) | |
// } | |
//nYKBjKNiVIQAVUjrUhX4gezsZJy2 | |
//riend-request | |
async function sendRealmoji(tokens,post){ | |
let postData = { | |
"userId": "5NxjaUNsz9boxqsJ2k7rbDnxKj63", | |
"source": "contact", | |
} | |
// DmASCoC8ldBOGnE3-PG3t | |
//uHvn528MxbVgGzqV1pN9p | |
//DF45PEfPuAPcpdNzQYewW5XW9VW2 | |
// console.log(post) | |
let postId = post.id | |
let userId = post.user.id | |
let postResponse = await axios.put(`https://mobile.bereal.com/api/content/realmojis?postId=${postId}&postUserId=${userId}`, { | |
emoji: "😍", | |
}, { | |
headers: { | |
Authorization: `Bearer ${tokens.access_token}`, | |
...getHeaders() | |
}, | |
}) | |
return postResponse.data | |
} | |
async function makeFriend(tokens,id){ | |
let postData = { | |
"userId": id, | |
"source": "contact", | |
} | |
// DmASCoC8ldBOGnE3-PG3t | |
//uHvn528MxbVgGzqV1pN9p | |
//DF45PEfPuAPcpdNzQYewW5XW9VW2 | |
// console.log(post) | |
let postResponse = await axios.post(`https://mobile.bereal.com/api/relationships/friend-requests`,postData, { | |
headers: { | |
Authorization: `Bearer ${tokens.access_token}`, | |
...getHeaders() | |
}, | |
}) | |
return postResponse.data | |
} | |
async function getFof(tokens,next = ""){ | |
const refresh = await fetch('https://mobile.bereal.com/api/feeds/friends-of-friends' + next, { | |
method: 'GET', | |
headers: { | |
'Accept': '*/*', | |
'User-Agent': 'BeReal/8586 CFNetwork/1240.0.4 Darwin/20.6.0', | |
'x-ios-bundle-identifier': 'AlexisBarreyat.BeReal', | |
'Content-Type': 'application/json', | |
"authorization":`Bearer ${tokens.access_token}`, | |
} | |
}); | |
const refreshJSON = await refresh.json() | |
let friends = refreshJSON.data.map((post)=>{ | |
return post | |
}) | |
// console.log("fetched ",friends.length,refreshJSON.data) | |
if(refreshJSON.next){ | |
console.log("getting next field",refreshJSON.next) | |
let morefriends = await getFriends(tokens,"?page="+refreshJSON.next) | |
friends = friends.concat(morefriends) | |
} | |
return friends | |
} | |
async function getFriends(tokens,next = ""){ | |
const refresh = await fetch('https://mobile.bereal.com/api/relationships/friends' + next, { | |
method: 'GET', | |
headers: { | |
'Accept': '*/*', | |
'User-Agent': 'BeReal/8586 CFNetwork/1240.0.4 Darwin/20.6.0', | |
'x-ios-bundle-identifier': 'AlexisBarreyat.BeReal', | |
'Content-Type': 'application/json', | |
"authorization":`Bearer ${tokens.access_token}`, | |
} | |
}); | |
const refreshJSON = await refresh.json() | |
let friends = refreshJSON.data | |
// console.log("fetched ",friends.length,refreshJSON.data) | |
if(refreshJSON.next){ | |
console.log("getting next field",refreshJSON.next) | |
let morefriends = await getFriends(tokens,"?page="+refreshJSON.next) | |
friends = friends.concat(morefriends) | |
} | |
return friends | |
} | |
//TODO: Save and load tokens. | |
async function getTokens(tokens){ | |
const refresh = await fetch('https://auth.bereal.team/token?grant_type=refresh_token', { | |
method: 'POST', | |
headers: { | |
'Accept': '*/*', | |
'User-Agent': 'BeReal/8586 CFNetwork/1240.0.4 Darwin/20.6.0', | |
'x-ios-bundle-identifier': 'AlexisBarreyat.BeReal', | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({ | |
'grant_type': 'refresh_token', | |
'client_id': 'ios', | |
'client_secret': '962D357B-B134-4AB6-8F53-BEA2B7255420', | |
'refresh_token': tokens.refresh_token | |
}) | |
}); | |
// console.log(await refresh.text()) | |
const refreshJSON = await refresh.json() | |
console.log("Token: ",refreshJSON.refresh_token) | |
return refreshJSON | |
} | |
/*{ | |
user: { | |
id: 'zDI59atGstgMs38hjJxZJk01hth2', | |
username: 'shrek_bot', | |
profilePicture: null, | |
type: 'USER' | |
}, | |
primary: { | |
height: 1500, | |
width: 2000, | |
url: 'https://cdn-us1.bereal.network/Photos/zDI59atGstgMs38hjJxZJk01hth2/post/Kg9TxcKI_FUoGbel.webp' | |
}, | |
primaryPlaceholder: null, | |
secondary: { | |
height: 1500, | |
width: 2000, | |
url: 'https://cdn-us1.bereal.network/Photos/zDI59atGstgMs38hjJxZJk01hth2/post/jG4y1y5Mdp9N-9Py.webp' | |
}, | |
secondaryPlaceholder: null, | |
isLate: false, | |
isMain: false, | |
lateInSeconds: 0, | |
moment: { id: 'OIiaOigmvJcoOh5gZlrTl', region: 'us-central' }, | |
id: 'HWtQYMoBVi4yJC0Ht4p8m', | |
location: null, | |
caption: null, | |
retakeCounter: 1, | |
comments: { sample: [], total: 0 }, | |
realmojis: { sample: [], total: 0 }, | |
screenshots: { sample: [], total: 0 }, | |
tags: [], | |
createdAt: '2024-04-28T04:06:39.698Z', | |
takenAt: '2024-04-27T21:28:08.470Z', | |
postedAt: '2024-04-28T04:06:39.698Z', | |
origin: null, | |
postType: 'default', | |
postNumber: 0, | |
visibility: [ 'friends' ], | |
canDelete: true, | |
streakLength: 1 | |
}*/ | |
function prompt(query) { | |
const rl = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout, | |
}); | |
return new Promise(resolve => rl.question(query, ans => { | |
rl.close(); | |
resolve(ans); | |
})) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment