Skip to content

Instantly share code, notes, and snippets.

@os11k
Last active October 26, 2024 14:36
Show Gist options
  • Save os11k/583b8513b8abe1aa902c3d05f90ac8f7 to your computer and use it in GitHub Desktop.
Save os11k/583b8513b8abe1aa902c3d05f90ac8f7 to your computer and use it in GitHub Desktop.
Retrieve views for last thread
// Define the API URLs and access token
const insightsApiUrlBase = "https://graph.threads.net/v1.0/";
// Function to get the access token from iCloud
async function getAccessToken() {
let fileManager = FileManager.iCloud();
let filePath = fileManager.joinPath(fileManager.documentsDirectory(), "threads_token.txt");
// Check if the file exists
if (!fileManager.fileExists(filePath)) {
console.error("Token file does not exist. Please save the token in iCloud first.");
return null;
}
// Make sure the file is downloaded from iCloud if not already available
if (!fileManager.isFileDownloaded(filePath)) {
await fileManager.downloadFileFromiCloud(filePath);
}
// Read and return the token
let token = fileManager.readString(filePath);
console.log("Access token retrieved:", token);
return token;
}
// Fetch the latest post and its views
async function getLatestPostInsights() {
let accessToken = await getAccessToken(); // Get the token from iCloud
if (!accessToken) {
console.error("No access token found.");
return null;
}
// Define the API URL with the retrieved token
const threadsApiUrl = `https://graph.threads.net/v1.0/me/threads?fields=id,text,views&access_token=${accessToken}`;
try {
// Log the request URL for debugging
console.log("Requesting URL:", threadsApiUrl);
// Make the API request for threads
let request = new Request(threadsApiUrl);
let response = await request.loadJSON();
// Log the raw response for debugging
console.log("Threads API Response:", JSON.stringify(response, null, 2));
// Check for API errors
if (response.error) {
console.error("API Error:", response.error.message);
throw new Error("API Error: " + response.error.message);
}
// Check if response data is empty
if (!response || !response.data || response.data.length === 0) {
console.log("No posts found or response data is empty.");
return {
viewsCount: 0,
postSnippet: "No post data available."
};
}
// Get the latest post (first item in the data array)
const latestPost = response.data[0];
const postId = latestPost.id;
const postText = latestPost.text || "No post text"; // Provide default if text is undefined
// Log the ID of the latest post
console.log("Latest Post ID:", postId);
// Make the API request for insights of the latest post
let insightsRequest = new Request(`${insightsApiUrlBase}${postId}/insights?metric=likes,replies,views&access_token=${accessToken}`);
let insightsResponse = await insightsRequest.loadJSON();
// Log the raw insights response for debugging
console.log("Insights API Response:", JSON.stringify(insightsResponse, null, 2));
// Initialize views count to 0 in case insights data is empty (like with a repost)
let viewsCount = 0;
const viewsMetric = insightsResponse.data.find(metric => metric.name === "views");
// Extract views count if available
if (viewsMetric && viewsMetric.values && viewsMetric.values[0]) {
viewsCount = viewsMetric.values[0].value;
}
// Return the views count and a snippet of the post text
return {
viewsCount: viewsCount,
postSnippet: postText.split("\n")[0] // Get the first line of the post text
};
} catch (error) {
console.error("Error fetching data: " + error);
return {
viewsCount: 0,
postSnippet: "Error or repost - views not available."
};
}
}
// Create the widget
async function createWidget() {
let widget = new ListWidget();
// Fetch the latest post insights
let insights = await getLatestPostInsights();
// Set up the widget display
if (insights !== null) {
widget.addText(insights.postSnippet);
let countText = widget.addText(insights.viewsCount.toString());
countText.font = Font.boldSystemFont(36); // Keep the font size bold for visibility
} else {
widget.addText("Error fetching data.");
}
widget.addSpacer();
widget.setPadding(16, 16, 16, 16);
// Set the widget to refresh every 15 minutes
let nextRefreshDate = new Date();
nextRefreshDate.setMinutes(nextRefreshDate.getMinutes() + 15);
widget.refreshAfterDate = nextRefreshDate;
return widget;
}
// Check if the script is running in widget mode
if (config.runsInWidget) {
// Create and set the widget
let widget = await createWidget();
Script.setWidget(widget);
Script.complete();
} else {
// If not in widget mode, preview the widget
let widget = await createWidget();
widget.presentSmall();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment