async function sendNewCrossPollination()

in projects/deliberation_at_scale/packages/orchestrator/src/tasks/enrichVoteCheck.ts [502:570]


async function sendNewCrossPollination(options: SendCrossPollinationOptions) {
    const { roomId, topicId, helpers, attemptSendBotMessage, beforeSend } = options;
    const room = await getRoomById(roomId);
    const outcomes = await getOutcomesByRoomId(roomId);
    const skippedOutcomeIds = flat(outcomes?.map((outcome) => [outcome.id, outcome.original_outcome_id]) ?? []);
    const { data: candidateOutcomes } = await supabaseClient
        .from('outcomes')
        .select()
        .not('id', 'in', `(${skippedOutcomeIds.join(',')})`)
        .in('type', ['milestone', 'consensus', 'seed_statement'])
        .or(`topic_id.eq.${topicId},topic_id.is.null`)
        .eq('active', true)
        .limit(200);
    const candidateOutcome = draw(candidateOutcomes ?? []);
    const candidateOutcomeId = candidateOutcome?.id;
    const candidateOutcomeContent = candidateOutcome?.content;
    const timeSinceRoomStartedMs = Math.abs(dayjs().diff(dayjs(room?.created_at), 'ms'));
    const newestOutcome = outcomes?.[0];
    const timeSinceLastOutcomeMs = Math.abs(dayjs().diff(dayjs(newestOutcome?.created_at), 'ms'));

    if (newestOutcome && timeSinceLastOutcomeMs < NEW_CROSS_POLLINATION_COOLDOWN_MS) {
        return;
    }

    // guard: make sure there is an outcome
    if (!candidateOutcomeId || !candidateOutcomeContent) {
        helpers.logger.info(`Could not find an candidate outcome for room ${roomId}.`);

        if (timeSinceRoomStartedMs > TIMEKEEPING_MOMENTS[0]) {
            await attemptSendBotMessage({
                roomId,
                content: t`Unfortunately, no new statements could be found. You can continue the discussion if you want or join others in a new conversation!`,
                sendOnce: true,
                scope: 'room',
            });
        } else {
            await attemptSendBotMessage({
                roomId,
                content: t`No new statements could be found, Sorry! You can continue the conversation here or move on to the next conversation!`,
                sendOnce: true,
                scope: 'room',
            });
        }
        return;
    }

    helpers.logger.info(`Sending new cross pollination for room ${roomId} with outcome ${candidateOutcomeId} and content ${candidateOutcomeContent}...`);

    // NOTE: force this one because it is an important message
    await beforeSend?.();
    await attemptSendBotMessage({
        roomId,
        content: getNewCrossPollinationMessageContent(candidateOutcomeContent),
        force: true,
    });
    await waitFor(NEW_OUTCOME_AFTER_OUTCOME_INTRODUCTION_MS);
    const { data: newOutcomes } = await supabaseClient
        .from('outcomes')
        .insert({
            content: candidateOutcomeContent,
            type: 'cross_pollination',
            room_id: roomId,
            original_outcome_id: candidateOutcomeId,
        })
        .select();
    const newOutcome = newOutcomes?.[0];

    return newOutcome;
}