Skip to content

Commit

Permalink
refactor(webhook): type yes/no postback handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
MrOrz committed Nov 19, 2023
1 parent ac02f02 commit 27cd8f4
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 22 deletions.
27 changes: 22 additions & 5 deletions src/webhook/handlers/askingArticleSource.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { t } from 'ttag';
import { Message } from '@line/bot-sdk';
import { z } from 'zod';
import ga from 'src/lib/ga';
import { ChatbotPostbackHandler } from 'src/types/chatbotState';

import {
POSTBACK_YES,
Expand All @@ -12,14 +15,26 @@ import {
} from './utils';

import { TUTORIAL_STEPS } from './tutorial';
import { ChatbotPostbackHandler } from 'src/types/chatbotState';
import { Message } from '@line/bot-sdk';


Check failure on line 19 in src/webhook/handlers/askingArticleSource.ts

View workflow job for this annotation

GitHub Actions / install-and-test

Delete `⏎`
const inputSchema = z.enum([POSTBACK_NO, POSTBACK_YES]);

/** Postback input type for ASKING_ARTICLE_SOURCE state handler */
export type Input = z.infer<typeof inputSchema>;

const askingArticleSource: ChatbotPostbackHandler = async ({
data,
postbackData: { state, input },
postbackData: { state, input: postbackInput },
userId,
}) => {
let input: Input;
try {
input = inputSchema.parse(postbackInput);
} catch (e) {
console.error('[choosingReply]', e);
throw new ManipulationError(t`Please choose from provided options.`);
}

let replies: Message[] = [];

const visitor = ga(
Expand All @@ -29,8 +44,10 @@ const askingArticleSource: ChatbotPostbackHandler = async ({
);

switch (input) {
default:
throw new ManipulationError(t`Please choose from provided options.`);
default: {
// Exhaustive check
return input satisfies never;
}

case POSTBACK_NO:
replies = [
Expand Down
38 changes: 27 additions & 11 deletions src/webhook/handlers/askingArticleSubmissionConsent.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { t } from 'ttag';
import { Message } from '@line/bot-sdk';
import { z } from 'zod';

import { ChatbotPostbackHandler } from 'src/types/chatbotState';
import ga from 'src/lib/ga';
import gql from 'src/lib/gql';
import { getArticleURL } from 'src/lib/sharedUtils';
import UserSettings from 'src/database/models/userSettings';
import UserArticleLink from 'src/database/models/userArticleLink';
import {
ArticleTypeEnum,
SubmitMediaArticleUnderConsentMutation,
SubmitMediaArticleUnderConsentMutationVariables,
SubmitTextArticleUnderConsentMutation,
SubmitTextArticleUnderConsentMutationVariables,
} from 'typegen/graphql';

import {
POSTBACK_YES,
POSTBACK_NO,
Expand All @@ -16,25 +27,29 @@ import {
getLineContentProxyURL,
createAIReply,
} from './utils';
import UserSettings from 'src/database/models/userSettings';
import UserArticleLink from 'src/database/models/userArticleLink';
import {
ArticleTypeEnum,
SubmitMediaArticleUnderConsentMutation,
SubmitMediaArticleUnderConsentMutationVariables,
SubmitTextArticleUnderConsentMutation,
SubmitTextArticleUnderConsentMutationVariables,
} from 'typegen/graphql';

const inputSchema = z.enum([POSTBACK_NO, POSTBACK_YES]);

/** Postback input type for ASKING_ARTICLE_SUBMISSION_CONSENT state handler */
export type Input = z.infer<typeof inputSchema>;

function uppercase<T extends string>(s: T) {
return s.toUpperCase() as Uppercase<T>;
}

const askingArticleSubmissionConsent: ChatbotPostbackHandler = async ({
data,
postbackData: { state, input },
postbackData: { state, input: postbackInput },
userId,
}) => {
let input: Input;
try {
input = inputSchema.parse(postbackInput);
} catch (e) {
console.error('[askingArticleSubmissionConsnet]', e);
throw new ManipulationError(t`Please choose from provided options.`);
}

const visitor = ga(
userId,
state,
Expand All @@ -45,7 +60,8 @@ const askingArticleSubmissionConsent: ChatbotPostbackHandler = async ({

switch (input) {
default:
throw new ManipulationError(t`Please choose from provided options.`);
// Exhaustive check
return input satisfies never;

case POSTBACK_NO:
visitor.event({ ec: 'Article', ea: 'Create', el: 'No' });
Expand Down
21 changes: 15 additions & 6 deletions src/webhook/handlers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import type {
} from '@line/bot-sdk';
import { t, msgid, ngettext } from 'ttag';
import GraphemeSplitter from 'grapheme-splitter';

import gql from 'src/lib/gql';
import { getArticleURL, createTypeWords } from 'src/lib/sharedUtils';
import { sign } from 'src/lib/jwt';
import { ChatbotState, PostbackActionData } from 'src/types/chatbotState';

import type {
CreateHighlightContentsHighlightFragment,
Expand All @@ -21,26 +25,31 @@ import type {
CreateAiReplyMutation,
CreateAiReplyMutationVariables,
} from 'typegen/graphql';
import { getArticleURL, createTypeWords } from 'src/lib/sharedUtils';
import { sign } from 'src/lib/jwt';
import { ChatbotState, PostbackActionData } from 'src/types/chatbotState';

import type { Input as ChoosingReplyInput } from './choosingReply';
import type { Input as AskingArticleSourceInput } from './askingArticleSource';
import type { Input as AskingArticleSubmissionConsentInput } from './askingArticleSubmissionConsent';

const splitter = new GraphemeSplitter();

/**
* Maps ChatbotState to the postback action data
*/
type StateInputMap = {
__INIT__: string;
TUTORIAL: string;
CHOOSING_ARTICLE: string;
CHOOSING_REPLY: ChoosingReplyInput;
ASKING_ARTICLE_SOURCE: string;
ASKING_ARTICLE_SUBMISSION_CONSENT: string;
ASKING_ARTICLE_SOURCE: AskingArticleSourceInput;
ASKING_ARTICLE_SUBMISSION_CONSENT: AskingArticleSubmissionConsentInput;
Error: unknown;
};

/**
* Generate a postback action with a payload that the state handler can process properly.
*
* @param label - Postback action button text, max 20 words
* @param input - Input when pressed
* @param input - Input when pressed. The format must match the postback data type for that state.
* @param displayText - Text to display in chat window.
* @param sessionId - Current session ID
* @param state - the state that processes the postback
Expand Down

0 comments on commit 27cd8f4

Please sign in to comment.