Skip to content

Commit

Permalink
* Fix webhook send properties for specific channel types
Browse files Browse the repository at this point in the history
* Crosspost messages in Announcement channels
* Create threads in Announcement and Text channels
* Catch errors at post level for granular logging
  • Loading branch information
danthonywalker committed Aug 14, 2023
1 parent e6526d8 commit 2123737
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 29 deletions.
15 changes: 4 additions & 11 deletions src/features/creators/post/database.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ChannelType } from "discord.js";

import { useClient } from "../../../services/postgresql";

import type { CreatorType } from "../constants";
Expand All @@ -9,6 +11,7 @@ export type CreatorSubscription = {
creatorType: CreatorType;
lastContentId: string | null;
creatorChannelId: string;
creatorChannelType: ChannelType;
creatorParentId: string | null;
webhookId: string;
webhookToken: string;
Expand All @@ -33,6 +36,7 @@ export const getCreatorSubscriptions = (guildId: string) =>
c.type as "creatorType",
cp.content_id as "lastContentId",
cc.id as "creatorChannelId",
cc.type as "creatorChannelType",
cc.parent_id as "creatorParentId",
cc.webhook_id as "webhookId",
cc.webhook_token as "webhookToken",
Expand Down Expand Up @@ -90,14 +94,3 @@ export const createCreatorPost = ({
contentId,
]);
});

export const deleteCreatorChannel = (channelId: string) =>
useClient((client) => {
const query = `
delete from creator_channel
where id = $1
`;

const values = [channelId];
return client.query(query, values);
});
65 changes: 47 additions & 18 deletions src/features/creators/post/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import { youtube_v3 } from "@googleapis/youtube";
import PlaylistItemSnippet = youtube_v3.Schema$PlaylistItemSnippet;

import type { Guild } from "discord.js";
import { bold, DiscordAPIError, Events, roleMention } from "discord.js";
import {
bold,
ChannelType,
DiscordAPIError,
Events,
roleMention,
} from "discord.js";
import { compress } from "compress-tag";
import loggerFactory from "pino";

Expand All @@ -11,14 +17,20 @@ import { getThumbnailUrl, getVideoUrl } from "../../../services/youtube";
import sleep from "../../../sleep";

import type { CreatorSubscription } from "./database";
import * as database from "./database";
import * as localDatabase from "./database";
import * as creatorsDatabase from "../database";
import * as youtube from "../youtube";
import { CreatorType } from "../constants";

const logger = loggerFactory({
name: __filename,
});

const database = {
...localDatabase,
...creatorsDatabase,
};

const getWebhook = async ({
creatorChannelId,
webhookId,
Expand All @@ -28,7 +40,7 @@ const getWebhook = async ({
return await discord.fetchWebhook(webhookId, webhookToken);
} catch (error) {
if (error instanceof DiscordAPIError && error.status === 404) {
await database.deleteCreatorChannel(creatorChannelId);
await database.deleteCreatorChannels([creatorChannelId]);
logger.info(error, "GET_WEBHOOK_ERROR");
return undefined;
}
Expand All @@ -46,6 +58,7 @@ const postFromYouTube = async (creatorSubscription: CreatorSubscription) => {
creatorType,
lastContentId,
creatorChannelId,
creatorChannelType,
creatorParentId,
createdAt,
creatorMentionRoleId,
Expand Down Expand Up @@ -85,25 +98,39 @@ const postFromYouTube = async (creatorSubscription: CreatorSubscription) => {
`;

const content = rawContent.substring(0, 2000);
const threadName = `${channelName} - ${title}`.substring(0, 100);
const threadId = creatorParentId === null ? undefined : creatorChannelId;
const threadName = `${channelName} - ${title}`.substring(0, 100);

const webhookThreadName =
creatorChannelType === ChannelType.GuildForum ? threadName : undefined;

const { id } = await webhook.send({
const message = await webhook.send({
avatarURL: getThumbnailUrl(thumbnails),
content,
username: channelName,
threadId,
threadName,
threadName: webhookThreadName,
});

await database.createCreatorPost({
id,
id: message.id,
creatorChannelId,
creatorType,
creatorDomainId,
contentId: videoId,
});

switch (creatorChannelType) {
case ChannelType.GuildAnnouncement:
await message.crosspost();
// falls through
case ChannelType.GuildText:
await message.startThread({ name: threadName });
// falls through
default:
break;
}

return lastContentId !== null;
};

Expand All @@ -117,13 +144,19 @@ const postFromYouTube = async (creatorSubscription: CreatorSubscription) => {

const postInGuild = async ({ id }: Guild) => {
const creatorSubscriptions = await database.getCreatorSubscriptions(id);
const promises = creatorSubscriptions.map((creatorSubscription) => {
const promises = creatorSubscriptions.map(async (creatorSubscription) => {
const { creatorType } = creatorSubscription;
switch (creatorType) {
case CreatorType.YOUTUBE:
return postFromYouTube(creatorSubscription);
default:
throw new Error(creatorType);

try {
switch (creatorType) {
case CreatorType.YOUTUBE:
await postFromYouTube(creatorSubscription);
break;
default:
throw new Error(creatorType);
}
} catch (error) {
logger.error(error, "POSTING_ERROR");
}
});

Expand All @@ -140,10 +173,6 @@ discord.once(Events.ClientReady, async (client) => {
const guilds = guildManager.valueOf();
const promises = guilds.map(postInGuild);

try {
await Promise.all(promises);
} catch (error) {
logger.error(error, "POSTING_ERROR");
}
await Promise.all(promises);
}
});

0 comments on commit 2123737

Please sign in to comment.