Skip to content

Instantly share code, notes, and snippets.

@DeclanChidlow
Created March 11, 2026 06:46
Show Gist options
  • Select an option

  • Save DeclanChidlow/2d32761a5819cfeb873a739cb9f81a86 to your computer and use it in GitHub Desktop.

Select an option

Save DeclanChidlow/2d32761a5819cfeb873a739cb9f81a86 to your computer and use it in GitHub Desktop.
Script to fetch current status from imood and update Stoat and GitHub status.
const STOAT_TOKEN = process.env.STOAT_TOKEN;
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
const IMOOD_EMAIL = process.env.IMOOD_EMAIL;
const faceEmojiMap = {
0: ":smiley:",
1: ":frowning_face:",
2: ":rage:",
3: ":neutral_face:",
4: ":no_mouth:",
5: ":innocent:",
6: ":upside_down_face:",
7: ":confused:",
8: ":flushed:",
9: ":mage:",
10: ":nauseated_face:",
11: ":smiling_imp:",
12: ":sleepy:",
13: ":us:",
14: ":relieved:",
15: ":clown_face:",
16: ":smirk:",
17: ":skull:",
18: ":cat:",
19: ":face_with_diagonal_mouth:",
20: ":heart:",
21: ":robot:",
22: ":heart_eyes:",
23: ":wink:",
24: ":cry:",
25: ":vampire:",
26: ":alien:",
27: ":cold_face:",
28: ":rainbow:",
29: ":yum:",
30: ":nerd_face:",
31: ":imp:",
32: ":imp:",
};
function extractTag(xml, tag) {
const openCloseRegex = new RegExp(`<${tag}>(.*?)</${tag}>`);
const match = xml.match(openCloseRegex);
if (match) return match[1];
const selfClosingRegex = new RegExp(`<${tag}\\s*/>`);
if (selfClosingRegex.test(xml)) return "";
return null;
}
async function fetchMood() {
const res = await fetch(`https://xml.imood.org/query.cgi?email=${IMOOD_EMAIL}`);
const xml = await res.text();
const base = extractTag(xml, "base") || "";
const personal = extractTag(xml, "personal") || "";
const face = extractTag(xml, "face") || "";
let statusText;
if (personal) {
statusText = personal;
} else if (base) {
statusText = `Feeling ${base}`;
} else {
statusText = "Feeling neutral";
}
const emoji = faceEmojiMap[face] || ":thought_balloon:";
return { statusText, emoji };
}
async function updateStoat(statusText) {
const res = await fetch("https://api.stoat.chat/users/@me", {
method: "PATCH",
headers: {
"Content-Type": "application/json",
"x-session-token": STOAT_TOKEN,
},
body: JSON.stringify({
status: {
text: statusText,
},
}),
});
if (!res.ok) {
console.error("❌ Failed to update Stoat status:", await res.text());
} else {
console.log("✅ Stoat status updated to:", statusText);
}
}
async function updateGitHub(statusText, emoji) {
const query = `
mutation($emoji: String!, $message: String!) {
changeUserStatus(input: {emoji: $emoji, message: $message}) {
status {
message
emoji
}
}
}
`;
const res = await fetch("https://api.github.com/graphql", {
method: "POST",
headers: {
"Authorization": `Bearer ${GITHUB_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query,
variables: { emoji, message: statusText },
}),
});
const data = await res.json();
if (data.errors) {
console.error("❌ Failed to update GitHub status:", JSON.stringify(data.errors));
} else {
console.log(`✅ GitHub status updated to: ${emoji} ${statusText}`);
}
}
async function main() {
console.log("Fetching mood from imood...");
const { statusText, emoji } = await fetchMood();
console.log(`Mood parsed: text="${statusText}", emoji="${emoji}"`);
await Promise.all([updateStoat(statusText), updateGitHub(statusText, emoji)]);
console.log("Done!");
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment