From f84da0dce8b20af89c974456234f477e987e872e Mon Sep 17 00:00:00 2001 From: alina sireneva Date: Sat, 1 Jun 2024 16:44:05 +0300 Subject: [PATCH] feat(core): fact checks --- packages/core/src/highlevel/client.ts | 15 +++++ packages/core/src/highlevel/methods.ts | 1 + .../core/src/highlevel/methods/_imports.ts | 1 + .../methods/messages/get-fact-check.ts | 32 ++++++++++ .../highlevel/types/messages/fact-check.ts | 59 +++++++++++++++++++ .../src/highlevel/types/messages/index.ts | 1 + .../src/highlevel/types/messages/message.ts | 15 +++++ 7 files changed, 124 insertions(+) create mode 100644 packages/core/src/highlevel/methods/messages/get-fact-check.ts create mode 100644 packages/core/src/highlevel/types/messages/fact-check.ts diff --git a/packages/core/src/highlevel/client.ts b/packages/core/src/highlevel/client.ts index 9e18afc1..4559d1f0 100644 --- a/packages/core/src/highlevel/client.ts +++ b/packages/core/src/highlevel/client.ts @@ -134,6 +134,7 @@ import { ForwardMessageOptions, forwardMessages, forwardMessagesById } from './m import { getAllScheduledMessages } from './methods/messages/get-all-scheduled-messages.js' import { getCallbackQueryMessage } from './methods/messages/get-callback-query-message.js' import { getDiscussionMessage } from './methods/messages/get-discussion-message.js' +import { getFactCheck } from './methods/messages/get-fact-check.js' import { getHistory, GetHistoryOffset } from './methods/messages/get-history.js' import { getMessageByLink } from './methods/messages/get-message-by-link.js' import { getMessageGroup } from './methods/messages/get-message-group.js' @@ -277,6 +278,7 @@ import { DeleteMessageUpdate, DeleteStoryUpdate, Dialog, + FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, @@ -3277,6 +3279,16 @@ export interface TelegramClient extends ITelegramClient { * @param message ID of the channel post */ getDiscussionMessage(params: InputMessageId): Promise + + /** + * Get fact check information for one or more messages in a chat + * + * **Available**: 👤 users only + * + * @param chatId Chat where the messages are located + * @param msgIds One or more message IDs + */ + getFactCheck(chatId: InputPeerLike, msgIds: MaybeArray): Promise<(FactCheck | null)[]> /** * Get chat history. * @@ -5910,6 +5922,9 @@ TelegramClient.prototype.getCallbackQueryMessage = function (...args) { TelegramClient.prototype.getDiscussionMessage = function (...args) { return getDiscussionMessage(this._client, ...args) } +TelegramClient.prototype.getFactCheck = function (...args) { + return getFactCheck(this._client, ...args) +} TelegramClient.prototype.getHistory = function (...args) { return getHistory(this._client, ...args) } diff --git a/packages/core/src/highlevel/methods.ts b/packages/core/src/highlevel/methods.ts index e8d1f361..1f96e19f 100644 --- a/packages/core/src/highlevel/methods.ts +++ b/packages/core/src/highlevel/methods.ts @@ -132,6 +132,7 @@ export { forwardMessages } from './methods/messages/forward-messages.js' export { getAllScheduledMessages } from './methods/messages/get-all-scheduled-messages.js' export { getCallbackQueryMessage } from './methods/messages/get-callback-query-message.js' export { getDiscussionMessage } from './methods/messages/get-discussion-message.js' +export { getFactCheck } from './methods/messages/get-fact-check.js' export type { GetHistoryOffset } from './methods/messages/get-history.js' export { getHistory } from './methods/messages/get-history.js' export { getMessageByLink } from './methods/messages/get-message-by-link.js' diff --git a/packages/core/src/highlevel/methods/_imports.ts b/packages/core/src/highlevel/methods/_imports.ts index 9540f2b0..bd6f1405 100644 --- a/packages/core/src/highlevel/methods/_imports.ts +++ b/packages/core/src/highlevel/methods/_imports.ts @@ -45,6 +45,7 @@ import { DeleteMessageUpdate, DeleteStoryUpdate, Dialog, + FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, diff --git a/packages/core/src/highlevel/methods/messages/get-fact-check.ts b/packages/core/src/highlevel/methods/messages/get-fact-check.ts new file mode 100644 index 00000000..321b86e0 --- /dev/null +++ b/packages/core/src/highlevel/methods/messages/get-fact-check.ts @@ -0,0 +1,32 @@ +import { MaybeArray } from '../../../types/utils.js' +import { ITelegramClient } from '../../client.types.js' +import { InputPeerLike } from '../../types/index.js' +import { FactCheck } from '../../types/messages/fact-check.js' +import { resolvePeer } from '../users/resolve-peer.js' + +// @available=user +/** + * Get fact check information for one or more messages in a chat + * + * @param chatId Chat where the messages are located + * @param msgIds One or more message IDs + */ +export async function getFactCheck( + client: ITelegramClient, + chatId: InputPeerLike, + msgIds: MaybeArray, +): Promise<(FactCheck | null)[]> { + const res = await client.call({ + _: 'messages.getFactCheck', + peer: await resolvePeer(client, chatId), + msgId: Array.isArray(msgIds) ? msgIds : [msgIds], + }) + + return res.map((x) => { + if (x.hash.isZero()) { + return null + } + + return new FactCheck(x) + }) +} diff --git a/packages/core/src/highlevel/types/messages/fact-check.ts b/packages/core/src/highlevel/types/messages/fact-check.ts new file mode 100644 index 00000000..24ab5682 --- /dev/null +++ b/packages/core/src/highlevel/types/messages/fact-check.ts @@ -0,0 +1,59 @@ +import { tl } from '@mtcute/tl' + +import { makeInspectable } from '../../utils/inspectable.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { MessageEntity } from './message-entity.js' + +/** + * Describes a fact-check added to the message by an independent checker + */ +export class FactCheck { + constructor(readonly raw: tl.RawFactCheck) {} + + /** + * Text of the fact-check + */ + get text(): string { + return this.raw.text?.text ?? '' + } + + /** + * Entities contained in the fact-check text + */ + get entities(): MessageEntity[] { + const entities: MessageEntity[] = [] + + if (this.raw.text?.entities) { + for (const ent of this.raw.text.entities) { + entities.push(new MessageEntity(ent, this.raw.text.text)) + } + } + + return entities + } + + /** + * Country for which the fact-check is relevant + */ + get country(): string | null { + return this.raw.country ?? null + } + + /** + * Whether this information might be outdated + * and should be re-fetched manually + */ + get shouldRecheck(): boolean { + return this.raw.needCheck! + } + + /** + * Hash of the fact-check + */ + get hash(): tl.Long { + return this.raw.hash + } +} + +memoizeGetters(FactCheck, ['entities']) +makeInspectable(FactCheck) diff --git a/packages/core/src/highlevel/types/messages/index.ts b/packages/core/src/highlevel/types/messages/index.ts index 488d1086..fb09b82a 100644 --- a/packages/core/src/highlevel/types/messages/index.ts +++ b/packages/core/src/highlevel/types/messages/index.ts @@ -1,5 +1,6 @@ export * from './dialog.js' export * from './draft-message.js' +export * from './fact-check.js' export * from './input-message-id.js' export * from './message.js' export * from './message-action.js' diff --git a/packages/core/src/highlevel/types/messages/message.ts b/packages/core/src/highlevel/types/messages/message.ts index ad71dc28..c2763ad1 100644 --- a/packages/core/src/highlevel/types/messages/message.ts +++ b/packages/core/src/highlevel/types/messages/message.ts @@ -12,6 +12,7 @@ import { Chat } from '../peers/chat.js' import { parsePeer, Peer } from '../peers/peer.js' import { PeersIndex } from '../peers/peers-index.js' import { User } from '../peers/user.js' +import { FactCheck } from './fact-check.js' import { _messageActionFromTl, MessageAction } from './message-action.js' import { MessageEntity } from './message-entity.js' import { MessageForwardInfo } from './message-forward.js' @@ -462,6 +463,9 @@ export class Message { return this.raw._ === 'message' && !this.raw.noforwards } + /** + * Reactions added to this message, if any + */ get reactions(): MessageReactions | null { if (this.raw._ === 'messageService' || !this.raw.reactions) { return null @@ -470,6 +474,16 @@ export class Message { return new MessageReactions(this.raw.id, getMarkedPeerId(this.raw.peerId), this.raw.reactions, this._peers) } + /** + * Information about fact-check added to the message, if any + */ + get factCheck(): FactCheck | null { + if (this.raw._ === 'messageService') return null + if (!this.raw.factcheck || this.raw.factcheck.hash.isZero()) return null + + return new FactCheck(this.raw.factcheck) + } + /** * Generated permalink to this message, only for groups and channels * @@ -499,5 +513,6 @@ memoizeGetters(Message, [ 'media', 'markup', 'reactions', + 'factCheck', ]) makeInspectable(Message, ['isScheduled'], ['link'])