/** * @copyright nhcarrigan * @license Naomi's Public License * @author Naomi Carrigan */ interface FacebookErrorResponse { error: { code: number; message: string; type: string; }; } interface FacebookSuccessResponse { id: string; } type FacebookResponse = FacebookErrorResponse | FacebookSuccessResponse; /** * Forwards an announcement to our Facebook Page. * @param content - The main body of the announcement. * @returns A message indicating the success or failure of the operation. */ export const announceOnFacebook = async(content: string): Promise => { if ( process.env.FACEBOOK_PAGE_TOKEN === undefined || process.env.FACEBOOK_PAGE_ID === undefined ) { return "Facebook credentials are not set."; } if (content.trim().length === 0) { return "No content to send to Facebook."; } const pageId = process.env.FACEBOOK_PAGE_ID; const accessToken = process.env.FACEBOOK_PAGE_TOKEN; try { const response = await fetch( `https://graph.facebook.com/v21.0/${pageId}/feed`, { body: new URLSearchParams({ // eslint-disable-next-line @typescript-eslint/naming-convention -- Facebook API requires snake_case. access_token: accessToken, message: content, }), headers: { // eslint-disable-next-line @typescript-eslint/naming-convention -- HTTP header name. "Content-Type": "application/x-www-form-urlencoded", }, method: "POST", }, ); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Fetch does not accept generic. const result = (await response.json()) as FacebookResponse; if ("error" in result) { const errorMessage = result.error.message === "" ? JSON.stringify(result.error) : result.error.message; return `Failed to send message to Facebook. ${errorMessage}`; } if ("id" in result) { return `Successfully sent post to Facebook. Post ID: ${result.id}`; } return `Failed to send message to Facebook. Unexpected response: ${JSON.stringify(result)}`; } catch (error: unknown) { return `Failed to send message to Facebook. ${ error instanceof Error ? error.message : String(error) }`; } };