• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cofacts / rumors-line-bot / 4584107391

pending completion
4584107391

Pull #347

github

GitHub
Merge d294faa44 into 9a40a195b
Pull Request #347: Implement AI reply

436 of 497 branches covered (87.73%)

Branch coverage included in aggregate %.

16 of 16 new or added lines in 3 files covered. (100.0%)

958 of 1026 relevant lines covered (93.37%)

11.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.88
/src/webhook/handlers/askingArticleSubmissionConsent.js
1
import { t } from 'ttag';
2
import ga from 'src/lib/ga';
3
import gql from 'src/lib/gql';
4
import { getArticleURL } from 'src/lib/sharedUtils';
5
import {
6
  POSTBACK_YES,
7
  POSTBACK_NO,
8
  ManipulationError,
9
  createTextMessage,
10
  createCommentBubble,
11
  createArticleShareBubble,
12
  createNotificationSettingsBubble,
13
  getLineContentProxyURL,
14
  createAIReply,
15
} from './utils';
16
import UserSettings from 'src/database/models/userSettings';
17
import UserArticleLink from 'src/database/models/userArticleLink';
18

19
export default async function askingArticleSubmissionConsent(params) {
20
  let { data, state, event, userId, replies } = params;
6✔
21

22
  const visitor = ga(userId, state, data.searchedText);
6✔
23

24
  switch (event.input) {
6✔
25
    default:
26
      throw new ManipulationError(t`Please choose from provided options.`);
1✔
27

28
    case POSTBACK_NO:
29
      visitor.event({ ec: 'Article', ea: 'Create', el: 'No' });
1✔
30
      replies = [
1✔
31
        createTextMessage({
32
          text: t`The message has not been reported and won’t be fact-checked. Thanks anyway!`,
33
        }),
34
      ];
35
      state = '__INIT__';
1✔
36
      break;
1✔
37

38
    case POSTBACK_YES: {
39
      visitor.event({ ec: 'Article', ea: 'Create', el: 'Yes' });
4✔
40
      const isTextArticle = data.searchedText && !data.messageId;
4✔
41
      let article;
42
      if (isTextArticle) {
4✔
43
        const result = await gql`
3✔
44
          mutation ($text: String!) {
45
            CreateArticle(text: $text, reference: { type: LINE }) {
46
              id
47
            }
48
          }
49
        `({ text: data.searchedText }, { userId });
50
        article = result.data.CreateArticle;
3✔
51
      } else {
52
        if (!data.messageId) {
1!
53
          // Should not be here
54
          throw new Error('No message ID found, cannot submit message.');
×
55
        }
56

57
        const proxyUrl = getLineContentProxyURL(data.messageId);
1✔
58
        const result = await gql`
1✔
59
          mutation ($mediaUrl: String!, $articleType: ArticleTypeEnum!) {
60
            CreateMediaArticle(
61
              mediaUrl: $mediaUrl
62
              articleType: $articleType
63
              reference: { type: LINE }
64
            ) {
65
              id
66
            }
67
          }
68
        `(
69
          { mediaUrl: proxyUrl, articleType: data.messageType.toUpperCase() },
70
          { userId }
71
        );
72
        article = result.data.CreateMediaArticle;
1✔
73
      }
74

75
      await UserArticleLink.createOrUpdateByUserIdAndArticleId(
4✔
76
        userId,
77
        article.id
78
      );
79

80
      // Create new session, make article submission button expire after submission
81
      data.sessionId = Date.now();
4✔
82

83
      const articleUrl = getArticleURL(article.id);
4✔
84
      const articleCreatedMsg = t`Your submission is now recorded at ${articleUrl}`;
4✔
85
      const { allowNewReplyUpdate } = await UserSettings.findOrInsertByUserId(
4✔
86
        userId
87
      );
88

89
      let maybeAIReplies = [
4✔
90
        createTextMessage({
91
          text: t`In the meantime, you can:`,
92
        }),
93
      ];
94

95
      if (isTextArticle) {
4✔
96
        const aiReply = await createAIReply(article.id, userId);
3✔
97
        if (aiReply) {
3!
98
          maybeAIReplies = [
3✔
99
            createTextMessage({
100
              text: '這篇文章尚待查核中,請先不要相信這篇文章。\n以下是機器人初步分析此篇訊息的結果,希望能帶給你一些想法。',
101
            }),
102
            {
103
              type: 'text',
104
              text: aiReply,
105
            },
106
            createTextMessage({
107
              text: '讀完以上機器人的自動分析後,您可以:',
108
            }),
109
          ];
110
        }
111
      }
112

113
      replies = [
4✔
114
        {
115
          type: 'flex',
116
          altText: t`The message has now been recorded at Cofacts for volunteers to fact-check. Thank you for submitting!`,
117
          contents: {
118
            type: 'bubble',
119
            body: {
120
              type: 'box',
121
              layout: 'vertical',
122
              contents: [
123
                {
124
                  type: 'text',
125
                  wrap: true,
126
                  text: t`The message has now been recorded at Cofacts for volunteers to fact-check. Thank you for submitting!`,
127
                },
128
                {
129
                  type: 'button',
130
                  action: {
131
                    type: 'uri',
132
                    label: t`View reported message`,
133
                    uri: articleUrl,
134
                  },
135
                  margin: 'md',
136
                },
137
              ],
138
            },
139
          },
140
        },
141
        ...maybeAIReplies,
142
        {
143
          type: 'flex',
144
          altText: articleCreatedMsg,
145
          contents: {
146
            type: 'carousel',
147
            contents: [
148
              createCommentBubble(article.id),
149
              // Ask user to turn on notification if the user did not turn it on
150
              //
151
              process.env.NOTIFY_METHOD &&
6✔
152
                !allowNewReplyUpdate &&
153
                createNotificationSettingsBubble(),
154
              createArticleShareBubble(articleUrl),
155
            ].filter((m) => m),
12✔
156
          },
157
        },
158
      ];
159
      state = '__INIT__';
4✔
160
    }
161
  }
162

163
  visitor.send();
5✔
164
  return { data, event, userId, replies };
5✔
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc