Browse Source

Layer 143

Invoice links
master
Eduard Kuzmenko 2 years ago
parent
commit
30fd544802
  1. 5
      src/components/chat/bubbles.ts
  2. 84
      src/components/popups/payment.ts
  3. 6
      src/components/popups/paymentShipping.ts
  4. 289
      src/layer.d.ts
  5. 55
      src/lib/appManagers/appImManager.ts
  6. 31
      src/lib/appManagers/appPaymentsManager.ts
  7. 13
      src/lib/appManagers/internalLink.ts
  8. 2
      src/lib/mtproto/schema.ts
  9. 8
      src/lib/richTextProcessor/wrapUrl.ts
  10. 4
      src/scripts/in/schema.json
  11. 2
      src/scripts/out/schema.json

5
src/components/chat/bubbles.ts

@ -1486,7 +1486,10 @@ export default class ChatBubbles {
return; return;
} }
new PopupPayment(message as Message.message); new PopupPayment(
message as Message.message,
await this.managers.appPaymentsManager.getInputInvoiceByPeerId(message.peerId, message.mid)
);
return; return;
} }

84
src/components/popups/payment.ts

@ -23,7 +23,7 @@ import { formatPhoneNumber } from "../../helpers/formatPhoneNumber";
import paymentsWrapCurrencyAmount from "../../helpers/paymentsWrapCurrencyAmount"; import paymentsWrapCurrencyAmount from "../../helpers/paymentsWrapCurrencyAmount";
import ScrollSaver from "../../helpers/scrollSaver"; import ScrollSaver from "../../helpers/scrollSaver";
import tsNow from "../../helpers/tsNow"; import tsNow from "../../helpers/tsNow";
import { AccountTmpPassword, InputPaymentCredentials, LabeledPrice, Message, MessageMedia, PaymentRequestedInfo, PaymentSavedCredentials, PaymentsPaymentForm, PaymentsPaymentReceipt, PaymentsValidatedRequestedInfo, PostAddress, ShippingOption } from "../../layer"; import { AccountTmpPassword, InputInvoice, InputPaymentCredentials, LabeledPrice, Message, MessageMedia, PaymentRequestedInfo, PaymentSavedCredentials, PaymentsPaymentForm, PaymentsPaymentReceipt, PaymentsValidatedRequestedInfo, PostAddress, ShippingOption } from "../../layer";
import I18n, { i18n, LangPackKey, _i18n } from "../../lib/langPack"; import I18n, { i18n, LangPackKey, _i18n } from "../../lib/langPack";
import { ApiError } from "../../lib/mtproto/apiManager"; import { ApiError } from "../../lib/mtproto/apiManager";
import wrapEmojiText from "../../lib/richTextProcessor/wrapEmojiText"; import wrapEmojiText from "../../lib/richTextProcessor/wrapEmojiText";
@ -99,10 +99,13 @@ export function PaymentButton(options: {
export type PaymentsCredentialsToken = {type: 'card', token?: string, id?: string}; export type PaymentsCredentialsToken = {type: 'card', token?: string, id?: string};
export default class PopupPayment extends PopupElement { export default class PopupPayment extends PopupElement {
private currency: string;
private tipButtonsMap: Map<number, HTMLElement>; private tipButtonsMap: Map<number, HTMLElement>;
constructor(private message: Message.message) { constructor(
private message: Message.message,
private inputInvoice: InputInvoice,
private paymentForm?: PaymentsPaymentForm | PaymentsPaymentReceipt
) {
super('popup-payment', { super('popup-payment', {
closable: true, closable: true,
overlayClosable: true, overlayClosable: true,
@ -139,22 +142,31 @@ export default class PopupPayment extends PopupElement {
langPackKey: 'PaymentInfoHint', langPackKey: 'PaymentInfoHint',
langPackArguments: [ langPackArguments: [
paymentsWrapCurrencyAmount(getTotalTotal(), currency), paymentsWrapCurrencyAmount(getTotalTotal(), currency),
wrapEmojiText(mediaInvoice.title) wrapEmojiText(title)
] ]
}); });
}; };
this.listenerSetter.add(rootScope)('payment_sent', ({peerId, mid}) => { let {paymentForm, message} = this;
if(this.message.peerId === peerId && this.message.mid === mid) {
onConfirmed();
}
});
const {message} = this; if(message) {
const mediaInvoice = message.media as MessageMedia.messageMediaInvoice; this.listenerSetter.add(rootScope)('payment_sent', ({peerId, mid}) => {
if(message.peerId === peerId && message.mid === mid) {
onConfirmed();
}
});
}
_i18n(this.title, mediaInvoice.receipt_msg_id ? 'PaymentReceipt' : 'PaymentCheckout'); const mediaInvoice = message?.media as MessageMedia.messageMediaInvoice;
if(mediaInvoice.pFlags.test) { const isReceipt = mediaInvoice ? !!mediaInvoice.receipt_msg_id : paymentForm._ === 'payments.paymentReceipt';
const isTest = mediaInvoice ? mediaInvoice.pFlags.test : paymentForm.invoice.pFlags.test;
const photo = mediaInvoice ? mediaInvoice.photo : paymentForm.photo;
const title = mediaInvoice ? mediaInvoice.title : paymentForm.title;
const description = mediaInvoice ? mediaInvoice.description : paymentForm.description;
_i18n(this.title, isReceipt ? 'PaymentReceipt' : 'PaymentCheckout');
if(isTest) {
this.title.append(' (Test)'); this.title.append(' (Test)');
} }
@ -168,11 +180,11 @@ export default class PopupPayment extends PopupElement {
details.classList.add(detailsClassName); details.classList.add(detailsClassName);
let photoEl: HTMLElement; let photoEl: HTMLElement;
if(mediaInvoice.photo) { if(photo) {
photoEl = document.createElement('div'); photoEl = document.createElement('div');
photoEl.classList.add(detailsClassName + '-photo', 'media-container-cover'); photoEl.classList.add(detailsClassName + '-photo', 'media-container-cover');
wrapPhoto({ wrapPhoto({
photo: mediaInvoice.photo, photo: photo,
container: photoEl, container: photoEl,
boxWidth: 100, boxWidth: 100,
boxHeight: 100, boxHeight: 100,
@ -182,27 +194,27 @@ export default class PopupPayment extends PopupElement {
} }
const linesClassName = detailsClassName + '-lines'; const linesClassName = detailsClassName + '-lines';
const lines = document.createElement('div'); const linesEl = document.createElement('div');
lines.classList.add(linesClassName); linesEl.classList.add(linesClassName);
const title = document.createElement('div'); const titleEl = document.createElement('div');
title.classList.add(linesClassName + '-title'); titleEl.classList.add(linesClassName + '-title');
const description = document.createElement('div'); const descriptionEl = document.createElement('div');
description.classList.add(linesClassName + '-description'); descriptionEl.classList.add(linesClassName + '-description');
const botName = document.createElement('div'); const botName = document.createElement('div');
botName.classList.add(linesClassName + '-bot-name'); botName.classList.add(linesClassName + '-bot-name');
lines.append(title, description, botName); linesEl.append(titleEl, descriptionEl, botName);
setInnerHTML(title, wrapEmojiText(mediaInvoice.title)); setInnerHTML(titleEl, wrapEmojiText(title));
setInnerHTML(description, wrapEmojiText(mediaInvoice.description)); setInnerHTML(descriptionEl, wrapEmojiText(description));
const peerTitle = new PeerTitle(); const peerTitle = new PeerTitle();
botName.append(peerTitle.element); botName.append(peerTitle.element);
details.append(lines); details.append(linesEl);
itemEl.append(details); itemEl.append(details);
this.scrollable.append(itemEl); this.scrollable.append(itemEl);
@ -211,16 +223,17 @@ export default class PopupPayment extends PopupElement {
const preloader = putPreloader(preloaderContainer, true); const preloader = putPreloader(preloaderContainer, true);
this.scrollable.container.append(preloaderContainer); this.scrollable.container.append(preloaderContainer);
let paymentForm: PaymentsPaymentForm | PaymentsPaymentReceipt; const inputInvoice = this.inputInvoice;
const isReceipt = !!mediaInvoice.receipt_msg_id; if(!paymentForm) {
if(isReceipt) paymentForm = await this.managers.appPaymentsManager.getPaymentReceipt(message.peerId, mediaInvoice.receipt_msg_id);
if(isReceipt) paymentForm = await this.managers.appPaymentsManager.getPaymentReceipt(message.peerId, mediaInvoice.receipt_msg_id); else paymentForm = await this.managers.appPaymentsManager.getPaymentForm(inputInvoice);
else paymentForm = await this.managers.appPaymentsManager.getPaymentForm(message.peerId, message.mid); this.paymentForm = paymentForm;
}
let savedInfo = (paymentForm as PaymentsPaymentForm).saved_info || (paymentForm as PaymentsPaymentReceipt).info; let savedInfo = (paymentForm as PaymentsPaymentForm).saved_info || (paymentForm as PaymentsPaymentReceipt).info;
const savedCredentials = (paymentForm as PaymentsPaymentForm).saved_credentials; const savedCredentials = (paymentForm as PaymentsPaymentForm).saved_credentials;
let [lastRequestedInfo, passwordState, providerPeerTitle] = await Promise.all([ let [lastRequestedInfo, passwordState, providerPeerTitle] = await Promise.all([
!isReceipt && savedInfo && this.managers.appPaymentsManager.validateRequestedInfo(message.peerId, message.mid, savedInfo), !isReceipt && savedInfo && this.managers.appPaymentsManager.validateRequestedInfo(inputInvoice, savedInfo),
savedCredentials && this.managers.passwordManager.getState(), savedCredentials && this.managers.passwordManager.getState(),
wrapPeerTitle({peerId: paymentForm.provider_id.toPeerId()}) wrapPeerTitle({peerId: paymentForm.provider_id.toPeerId()})
]); ]);
@ -236,7 +249,7 @@ export default class PopupPayment extends PopupElement {
}; };
const {invoice} = paymentForm; const {invoice} = paymentForm;
const currency = this.currency = invoice.currency; const currency = invoice.currency;
const makeLabel = () => { const makeLabel = () => {
const labelEl = document.createElement('div'); const labelEl = document.createElement('div');
@ -326,7 +339,7 @@ export default class PopupPayment extends PopupElement {
}; };
const tipsLabel = makeLabel(); const tipsLabel = makeLabel();
_i18n(tipsLabel.left, mediaInvoice.receipt_msg_id ? 'PaymentTip' : 'PaymentTipOptional'); _i18n(tipsLabel.left, isReceipt ? 'PaymentTip' : 'PaymentTipOptional');
const input = document.createElement('input'); const input = document.createElement('input');
input.type = 'tel'; input.type = 'tel';
// const input: HTMLElement = document.createElement('div'); // const input: HTMLElement = document.createElement('div');
@ -555,7 +568,7 @@ export default class PopupPayment extends PopupElement {
if(!isReceipt) { if(!isReceipt) {
onShippingAddressClick = (focus) => { onShippingAddressClick = (focus) => {
new PopupPaymentShipping(paymentForm as PaymentsPaymentForm, message, focus).addEventListener('finish', ({shippingAddress, requestedInfo}) => { new PopupPaymentShipping(paymentForm as PaymentsPaymentForm, inputInvoice, focus).addEventListener('finish', ({shippingAddress, requestedInfo}) => {
lastRequestedInfo = requestedInfo; lastRequestedInfo = requestedInfo;
savedInfo = (paymentForm as PaymentsPaymentForm).saved_info = shippingAddress; savedInfo = (paymentForm as PaymentsPaymentForm).saved_info = shippingAddress;
setShippingInfo(shippingAddress); setShippingInfo(shippingAddress);
@ -721,8 +734,7 @@ export default class PopupPayment extends PopupElement {
try { try {
const paymentResult = await this.managers.appPaymentsManager.sendPaymentForm( const paymentResult = await this.managers.appPaymentsManager.sendPaymentForm(
message.peerId, inputInvoice,
message.mid,
(paymentForm as PaymentsPaymentForm).form_id, (paymentForm as PaymentsPaymentForm).form_id,
lastRequestedInfo?.id, lastRequestedInfo?.id,
lastShippingOption?.id, lastShippingOption?.id,

6
src/components/popups/paymentShipping.ts

@ -8,7 +8,7 @@ import PopupElement from ".";
import { attachClickEvent } from "../../helpers/dom/clickEvent"; import { attachClickEvent } from "../../helpers/dom/clickEvent";
import placeCaretAtEnd from "../../helpers/dom/placeCaretAtEnd"; import placeCaretAtEnd from "../../helpers/dom/placeCaretAtEnd";
import toggleDisability from "../../helpers/dom/toggleDisability"; import toggleDisability from "../../helpers/dom/toggleDisability";
import { Message, PaymentRequestedInfo, PaymentsPaymentForm, PaymentsValidatedRequestedInfo } from "../../layer"; import { InputInvoice, Message, PaymentRequestedInfo, PaymentsPaymentForm, PaymentsValidatedRequestedInfo } from "../../layer";
import getServerMessageId from "../../lib/appManagers/utils/messageId/getServerMessageId"; import getServerMessageId from "../../lib/appManagers/utils/messageId/getServerMessageId";
import { ApiError } from "../../lib/mtproto/apiManager"; import { ApiError } from "../../lib/mtproto/apiManager";
import matchEmail from "../../lib/richTextProcessor/matchEmail"; import matchEmail from "../../lib/richTextProcessor/matchEmail";
@ -31,7 +31,7 @@ export default class PopupPaymentShipping extends PopupElement<{
}> { }> {
constructor( constructor(
private paymentForm: PaymentsPaymentForm, private paymentForm: PaymentsPaymentForm,
private message: Message.message, private inputInvoice: InputInvoice,
private focus?: ShippingFocusField private focus?: ShippingFocusField
) { ) {
super('popup-payment popup-payment-shipping', { super('popup-payment popup-payment-shipping', {
@ -143,7 +143,7 @@ export default class PopupPaymentShipping extends PopupElement<{
}; };
try { try {
const requestedInfo = await this.managers.appPaymentsManager.validateRequestedInfo(this.message.peerId, this.message.mid, data, saveCheckboxField?.checked); const requestedInfo = await this.managers.appPaymentsManager.validateRequestedInfo(this.inputInvoice, data, saveCheckboxField?.checked);
this.dispatchEvent('finish', { this.dispatchEvent('finish', {
shippingAddress: data, shippingAddress: data,

289
src/layer.d.ts vendored

@ -498,6 +498,8 @@ export namespace User {
apply_min_photo?: true, apply_min_photo?: true,
fake?: true, fake?: true,
bot_attach_menu?: true, bot_attach_menu?: true,
premium?: true,
attach_menu_enabled?: true,
}>, }>,
id: string | number, id: string | number,
access_hash?: string | number, access_hash?: string | number,
@ -964,6 +966,9 @@ export namespace MessageMedia {
export type messageMediaDocument = { export type messageMediaDocument = {
_: 'messageMediaDocument', _: 'messageMediaDocument',
flags?: number, flags?: number,
pFlags?: Partial<{
nopremium?: true,
}>,
document?: Document, document?: Document,
ttl_seconds?: number ttl_seconds?: number
}; };
@ -1109,6 +1114,10 @@ export namespace MessageAction {
export type messageActionPaymentSentMe = { export type messageActionPaymentSentMe = {
_: 'messageActionPaymentSentMe', _: 'messageActionPaymentSentMe',
flags?: number, flags?: number,
pFlags?: Partial<{
recurring_init?: true,
recurring_used?: true,
}>,
currency: string, currency: string,
total_amount: string | number, total_amount: string | number,
payload: Uint8Array, payload: Uint8Array,
@ -1119,8 +1128,14 @@ export namespace MessageAction {
export type messageActionPaymentSent = { export type messageActionPaymentSent = {
_: 'messageActionPaymentSent', _: 'messageActionPaymentSent',
flags?: number,
pFlags?: Partial<{
recurring_init?: true,
recurring_used?: true,
}>,
currency: string, currency: string,
total_amount: string | number total_amount: string | number,
invoice_slug?: string
}; };
export type messageActionPhoneCall = { export type messageActionPhoneCall = {
@ -1990,7 +2005,7 @@ export namespace MessagesFilter {
/** /**
* @link https://core.telegram.org/type/Update * @link https://core.telegram.org/type/Update
*/ */
export type Update = Update.updateNewMessage | Update.updateMessageID | Update.updateDeleteMessages | Update.updateUserTyping | Update.updateChatUserTyping | Update.updateChatParticipants | Update.updateUserStatus | Update.updateUserName | Update.updateUserPhoto | Update.updateNewEncryptedMessage | Update.updateEncryptedChatTyping | Update.updateEncryption | Update.updateEncryptedMessagesRead | Update.updateChatParticipantAdd | Update.updateChatParticipantDelete | Update.updateDcOptions | Update.updateNotifySettings | Update.updateServiceNotification | Update.updatePrivacy | Update.updateUserPhone | Update.updateReadHistoryInbox | Update.updateReadHistoryOutbox | Update.updateWebPage | Update.updateReadMessagesContents | Update.updateChannelTooLong | Update.updateChannel | Update.updateNewChannelMessage | Update.updateReadChannelInbox | Update.updateDeleteChannelMessages | Update.updateChannelMessageViews | Update.updateChatParticipantAdmin | Update.updateNewStickerSet | Update.updateStickerSetsOrder | Update.updateStickerSets | Update.updateSavedGifs | Update.updateBotInlineQuery | Update.updateBotInlineSend | Update.updateEditChannelMessage | Update.updateBotCallbackQuery | Update.updateEditMessage | Update.updateInlineBotCallbackQuery | Update.updateReadChannelOutbox | Update.updateDraftMessage | Update.updateReadFeaturedStickers | Update.updateRecentStickers | Update.updateConfig | Update.updatePtsChanged | Update.updateChannelWebPage | Update.updateDialogPinned | Update.updatePinnedDialogs | Update.updateBotWebhookJSON | Update.updateBotWebhookJSONQuery | Update.updateBotShippingQuery | Update.updateBotPrecheckoutQuery | Update.updatePhoneCall | Update.updateLangPackTooLong | Update.updateLangPack | Update.updateFavedStickers | Update.updateChannelReadMessagesContents | Update.updateContactsReset | Update.updateChannelAvailableMessages | Update.updateDialogUnreadMark | Update.updateMessagePoll | Update.updateChatDefaultBannedRights | Update.updateFolderPeers | Update.updatePeerSettings | Update.updatePeerLocated | Update.updateNewScheduledMessage | Update.updateDeleteScheduledMessages | Update.updateTheme | Update.updateGeoLiveViewed | Update.updateLoginToken | Update.updateMessagePollVote | Update.updateDialogFilter | Update.updateDialogFilterOrder | Update.updateDialogFilters | Update.updatePhoneCallSignalingData | Update.updateChannelMessageForwards | Update.updateReadChannelDiscussionInbox | Update.updateReadChannelDiscussionOutbox | Update.updatePeerBlocked | Update.updateChannelUserTyping | Update.updatePinnedMessages | Update.updatePinnedChannelMessages | Update.updateChat | Update.updateGroupCallParticipants | Update.updateGroupCall | Update.updatePeerHistoryTTL | Update.updateChatParticipant | Update.updateChannelParticipant | Update.updateBotStopped | Update.updateGroupCallConnection | Update.updateBotCommands | Update.updatePendingJoinRequests | Update.updateBotChatInviteRequester | Update.updateMessageReactions | Update.updateAttachMenuBots | Update.updateWebViewResultSent | Update.updateBotMenuButton | Update.updateSavedRingtones | Update.updateNewDiscussionMessage | Update.updateDeleteDiscussionMessages | Update.updateChannelReload; export type Update = Update.updateNewMessage | Update.updateMessageID | Update.updateDeleteMessages | Update.updateUserTyping | Update.updateChatUserTyping | Update.updateChatParticipants | Update.updateUserStatus | Update.updateUserName | Update.updateUserPhoto | Update.updateNewEncryptedMessage | Update.updateEncryptedChatTyping | Update.updateEncryption | Update.updateEncryptedMessagesRead | Update.updateChatParticipantAdd | Update.updateChatParticipantDelete | Update.updateDcOptions | Update.updateNotifySettings | Update.updateServiceNotification | Update.updatePrivacy | Update.updateUserPhone | Update.updateReadHistoryInbox | Update.updateReadHistoryOutbox | Update.updateWebPage | Update.updateReadMessagesContents | Update.updateChannelTooLong | Update.updateChannel | Update.updateNewChannelMessage | Update.updateReadChannelInbox | Update.updateDeleteChannelMessages | Update.updateChannelMessageViews | Update.updateChatParticipantAdmin | Update.updateNewStickerSet | Update.updateStickerSetsOrder | Update.updateStickerSets | Update.updateSavedGifs | Update.updateBotInlineQuery | Update.updateBotInlineSend | Update.updateEditChannelMessage | Update.updateBotCallbackQuery | Update.updateEditMessage | Update.updateInlineBotCallbackQuery | Update.updateReadChannelOutbox | Update.updateDraftMessage | Update.updateReadFeaturedStickers | Update.updateRecentStickers | Update.updateConfig | Update.updatePtsChanged | Update.updateChannelWebPage | Update.updateDialogPinned | Update.updatePinnedDialogs | Update.updateBotWebhookJSON | Update.updateBotWebhookJSONQuery | Update.updateBotShippingQuery | Update.updateBotPrecheckoutQuery | Update.updatePhoneCall | Update.updateLangPackTooLong | Update.updateLangPack | Update.updateFavedStickers | Update.updateChannelReadMessagesContents | Update.updateContactsReset | Update.updateChannelAvailableMessages | Update.updateDialogUnreadMark | Update.updateMessagePoll | Update.updateChatDefaultBannedRights | Update.updateFolderPeers | Update.updatePeerSettings | Update.updatePeerLocated | Update.updateNewScheduledMessage | Update.updateDeleteScheduledMessages | Update.updateTheme | Update.updateGeoLiveViewed | Update.updateLoginToken | Update.updateMessagePollVote | Update.updateDialogFilter | Update.updateDialogFilterOrder | Update.updateDialogFilters | Update.updatePhoneCallSignalingData | Update.updateChannelMessageForwards | Update.updateReadChannelDiscussionInbox | Update.updateReadChannelDiscussionOutbox | Update.updatePeerBlocked | Update.updateChannelUserTyping | Update.updatePinnedMessages | Update.updatePinnedChannelMessages | Update.updateChat | Update.updateGroupCallParticipants | Update.updateGroupCall | Update.updatePeerHistoryTTL | Update.updateChatParticipant | Update.updateChannelParticipant | Update.updateBotStopped | Update.updateGroupCallConnection | Update.updateBotCommands | Update.updatePendingJoinRequests | Update.updateBotChatInviteRequester | Update.updateMessageReactions | Update.updateAttachMenuBots | Update.updateWebViewResultSent | Update.updateBotMenuButton | Update.updateSavedRingtones | Update.updateTranscribedAudio | Update.updateNewDiscussionMessage | Update.updateDeleteDiscussionMessages | Update.updateChannelReload;
export namespace Update { export namespace Update {
export type updateNewMessage = { export type updateNewMessage = {
@ -2224,6 +2239,7 @@ export namespace Update {
flags?: number, flags?: number,
pFlags?: Partial<{ pFlags?: Partial<{
masks?: true, masks?: true,
emojis?: true,
}>, }>,
order: Array<string | number> order: Array<string | number>
}; };
@ -2698,6 +2714,18 @@ export namespace Update {
_: 'updateSavedRingtones' _: 'updateSavedRingtones'
}; };
export type updateTranscribedAudio = {
_: 'updateTranscribedAudio',
flags?: number,
pFlags?: Partial<{
pending?: true,
}>,
peer: Peer,
msg_id: number,
transcription_id: string | number,
text: string
};
export type updateNewDiscussionMessage = { export type updateNewDiscussionMessage = {
_: 'updateNewDiscussionMessage', _: 'updateNewDiscussionMessage',
message?: Message message?: Message
@ -2936,6 +2964,7 @@ export namespace DcOption {
tcpo_only?: true, tcpo_only?: true,
cdn?: true, cdn?: true,
static?: true, static?: true,
this_port_only?: true,
}>, }>,
id: number, id: number,
ip_address: string, ip_address: string,
@ -2961,6 +2990,7 @@ export namespace Config {
revoke_pm_inbox?: true, revoke_pm_inbox?: true,
blocked_mode?: true, blocked_mode?: true,
pfs_enabled?: true, pfs_enabled?: true,
force_try_ipv6?: true,
}>, }>,
date: number, date: number,
expires: number, expires: number,
@ -3141,7 +3171,7 @@ export namespace EncryptedFile {
_: 'encryptedFile', _: 'encryptedFile',
id: string | number, id: string | number,
access_hash: string | number, access_hash: string | number,
size: number, size: string | number,
dc_id: number, dc_id: number,
key_fingerprint: number key_fingerprint: number
}; };
@ -3928,7 +3958,7 @@ export namespace ReceivedNotifyMessage {
/** /**
* @link https://core.telegram.org/type/ExportedChatInvite * @link https://core.telegram.org/type/ExportedChatInvite
*/ */
export type ExportedChatInvite = ExportedChatInvite.chatInviteExported; export type ExportedChatInvite = ExportedChatInvite.chatInviteExported | ExportedChatInvite.chatInvitePublicJoinRequests;
export namespace ExportedChatInvite { export namespace ExportedChatInvite {
export type chatInviteExported = { export type chatInviteExported = {
@ -3949,6 +3979,10 @@ export namespace ExportedChatInvite {
requested?: number, requested?: number,
title?: string title?: string
}; };
export type chatInvitePublicJoinRequests = {
_: 'chatInvitePublicJoinRequests'
};
} }
/** /**
@ -4036,6 +4070,7 @@ export namespace StickerSet {
masks?: true, masks?: true,
animated?: true, animated?: true,
videos?: true, videos?: true,
emojis?: true,
}>, }>,
installed_date?: number, installed_date?: number,
id: string | number, id: string | number,
@ -4090,10 +4125,13 @@ export type BotInfo = BotInfo.botInfo;
export namespace BotInfo { export namespace BotInfo {
export type botInfo = { export type botInfo = {
_: 'botInfo', _: 'botInfo',
user_id: string | number, flags?: number,
description: string, user_id?: string | number,
commands: Array<BotCommand>, description?: string,
menu_button: BotMenuButton description_photo?: Photo,
description_document?: Document,
commands?: Array<BotCommand>,
menu_button?: BotMenuButton
}; };
} }
@ -5273,6 +5311,10 @@ export namespace MessagesFeaturedStickers {
export type messagesFeaturedStickers = { export type messagesFeaturedStickers = {
_: 'messages.featuredStickers', _: 'messages.featuredStickers',
flags?: number,
pFlags?: Partial<{
premium?: true,
}>,
hash: string | number, hash: string | number,
count: number, count: number,
sets: Array<StickerSetCovered>, sets: Array<StickerSetCovered>,
@ -5802,11 +5844,13 @@ export namespace Invoice {
flexible?: true, flexible?: true,
phone_to_provider?: true, phone_to_provider?: true,
email_to_provider?: true, email_to_provider?: true,
recurring?: true,
}>, }>,
currency: string, currency: string,
prices: Array<LabeledPrice>, prices: Array<LabeledPrice>,
max_tip_amount?: string | number, max_tip_amount?: string | number,
suggested_tip_amounts?: Array<string | number> suggested_tip_amounts?: Array<string | number>,
recurring_terms_url?: string
}; };
} }
@ -5966,6 +6010,9 @@ export namespace PaymentsPaymentForm {
}>, }>,
form_id: string | number, form_id: string | number,
bot_id: string | number, bot_id: string | number,
title: string,
description: string,
photo?: WebDocument,
invoice: Invoice, invoice: Invoice,
provider_id: string | number, provider_id: string | number,
url: string, url: string,
@ -6234,6 +6281,10 @@ export type PhoneConnection = PhoneConnection.phoneConnection | PhoneConnection.
export namespace PhoneConnection { export namespace PhoneConnection {
export type phoneConnection = { export type phoneConnection = {
_: 'phoneConnection', _: 'phoneConnection',
flags?: number,
pFlags?: Partial<{
tcp?: true,
}>,
id: string | number, id: string | number,
ip: string, ip: string,
ipv6: string, ipv6: string,
@ -6881,7 +6932,7 @@ export type FileHash = FileHash.fileHash;
export namespace FileHash { export namespace FileHash {
export type fileHash = { export type fileHash = {
_: 'fileHash', _: 'fileHash',
offset: number, offset: string | number,
limit: number, limit: number,
hash: Uint8Array hash: Uint8Array
}; };
@ -6954,7 +7005,7 @@ export namespace SecureFile {
_: 'secureFile', _: 'secureFile',
id: string | number, id: string | number,
access_hash: string | number, access_hash: string | number,
size: number, size: string | number,
dc_id: number, dc_id: number,
date: number, date: number,
file_hash: Uint8Array, file_hash: Uint8Array,
@ -8333,7 +8384,7 @@ export namespace PaymentsBankCardData {
/** /**
* @link https://core.telegram.org/type/DialogFilter * @link https://core.telegram.org/type/DialogFilter
*/ */
export type DialogFilter = DialogFilter.dialogFilter; export type DialogFilter = DialogFilter.dialogFilter | DialogFilter.dialogFilterDefault;
export namespace DialogFilter { export namespace DialogFilter {
export type dialogFilter = { export type dialogFilter = {
@ -8359,6 +8410,10 @@ export namespace DialogFilter {
peerId?: PeerId, peerId?: PeerId,
folder_id?: number folder_id?: number
}; };
export type dialogFilterDefault = {
_: 'dialogFilterDefault'
};
} }
/** /**
@ -9199,6 +9254,9 @@ export namespace SponsoredMessage {
export type sponsoredMessage = { export type sponsoredMessage = {
_: 'sponsoredMessage', _: 'sponsoredMessage',
flags?: number, flags?: number,
pFlags?: Partial<{
recommended?: true,
}>,
random_id: Uint8Array, random_id: Uint8Array,
from_id?: Peer, from_id?: Peer,
chat_invite?: ChatInvite, chat_invite?: ChatInvite,
@ -9407,6 +9465,7 @@ export namespace AvailableReaction {
flags?: number, flags?: number,
pFlags?: Partial<{ pFlags?: Partial<{
inactive?: true, inactive?: true,
premium?: true,
}>, }>,
reaction: string, reaction: string,
title: string, title: string,
@ -9549,9 +9608,11 @@ export namespace AttachMenuBot {
flags?: number, flags?: number,
pFlags?: Partial<{ pFlags?: Partial<{
inactive?: true, inactive?: true,
has_settings?: true,
}>, }>,
bot_id: string | number, bot_id: string | number,
short_name: string, short_name: string,
peer_types: Array<AttachMenuPeerType>,
icons: Array<AttachMenuBotIcon> icons: Array<AttachMenuBotIcon>
}; };
} }
@ -9705,6 +9766,98 @@ export namespace AccountSavedRingtone {
}; };
} }
/**
* @link https://core.telegram.org/type/AttachMenuPeerType
*/
export type AttachMenuPeerType = AttachMenuPeerType.attachMenuPeerTypeSameBotPM | AttachMenuPeerType.attachMenuPeerTypeBotPM | AttachMenuPeerType.attachMenuPeerTypePM | AttachMenuPeerType.attachMenuPeerTypeChat | AttachMenuPeerType.attachMenuPeerTypeBroadcast;
export namespace AttachMenuPeerType {
export type attachMenuPeerTypeSameBotPM = {
_: 'attachMenuPeerTypeSameBotPM'
};
export type attachMenuPeerTypeBotPM = {
_: 'attachMenuPeerTypeBotPM'
};
export type attachMenuPeerTypePM = {
_: 'attachMenuPeerTypePM'
};
export type attachMenuPeerTypeChat = {
_: 'attachMenuPeerTypeChat'
};
export type attachMenuPeerTypeBroadcast = {
_: 'attachMenuPeerTypeBroadcast'
};
}
/**
* @link https://core.telegram.org/type/InputInvoice
*/
export type InputInvoice = InputInvoice.inputInvoiceMessage | InputInvoice.inputInvoiceSlug;
export namespace InputInvoice {
export type inputInvoiceMessage = {
_: 'inputInvoiceMessage',
peer: InputPeer,
msg_id: number
};
export type inputInvoiceSlug = {
_: 'inputInvoiceSlug',
slug: string
};
}
/**
* @link https://core.telegram.org/type/payments.ExportedInvoice
*/
export type PaymentsExportedInvoice = PaymentsExportedInvoice.paymentsExportedInvoice;
export namespace PaymentsExportedInvoice {
export type paymentsExportedInvoice = {
_: 'payments.exportedInvoice',
url: string
};
}
/**
* @link https://core.telegram.org/type/messages.TranscribedAudio
*/
export type MessagesTranscribedAudio = MessagesTranscribedAudio.messagesTranscribedAudio;
export namespace MessagesTranscribedAudio {
export type messagesTranscribedAudio = {
_: 'messages.transcribedAudio',
flags?: number,
pFlags?: Partial<{
pending?: true,
}>,
transcription_id: string | number,
text: string
};
}
/**
* @link https://core.telegram.org/type/help.PremiumPromo
*/
export type HelpPremiumPromo = HelpPremiumPromo.helpPremiumPromo;
export namespace HelpPremiumPromo {
export type helpPremiumPromo = {
_: 'help.premiumPromo',
status_text: string,
status_entities: Array<MessageEntity>,
video_sections: Array<string>,
videos: Array<Document>,
currency: string,
monthly_amount: string | number,
users: Array<User>
};
}
export interface ConstructorDeclMap { export interface ConstructorDeclMap {
'error': Error.error, 'error': Error.error,
'inputPeerEmpty': InputPeer.inputPeerEmpty, 'inputPeerEmpty': InputPeer.inputPeerEmpty,
@ -10688,6 +10841,19 @@ export interface ConstructorDeclMap {
'notificationSoundRingtone': NotificationSound.notificationSoundRingtone, 'notificationSoundRingtone': NotificationSound.notificationSoundRingtone,
'account.savedRingtone': AccountSavedRingtone.accountSavedRingtone, 'account.savedRingtone': AccountSavedRingtone.accountSavedRingtone,
'account.savedRingtoneConverted': AccountSavedRingtone.accountSavedRingtoneConverted, 'account.savedRingtoneConverted': AccountSavedRingtone.accountSavedRingtoneConverted,
'attachMenuPeerTypeSameBotPM': AttachMenuPeerType.attachMenuPeerTypeSameBotPM,
'attachMenuPeerTypeBotPM': AttachMenuPeerType.attachMenuPeerTypeBotPM,
'attachMenuPeerTypePM': AttachMenuPeerType.attachMenuPeerTypePM,
'attachMenuPeerTypeChat': AttachMenuPeerType.attachMenuPeerTypeChat,
'attachMenuPeerTypeBroadcast': AttachMenuPeerType.attachMenuPeerTypeBroadcast,
'chatInvitePublicJoinRequests': ExportedChatInvite.chatInvitePublicJoinRequests,
'inputInvoiceMessage': InputInvoice.inputInvoiceMessage,
'inputInvoiceSlug': InputInvoice.inputInvoiceSlug,
'payments.exportedInvoice': PaymentsExportedInvoice.paymentsExportedInvoice,
'updateTranscribedAudio': Update.updateTranscribedAudio,
'messages.transcribedAudio': MessagesTranscribedAudio.messagesTranscribedAudio,
'dialogFilterDefault': DialogFilter.dialogFilterDefault,
'help.premiumPromo': HelpPremiumPromo.helpPremiumPromo,
'messageEntityEmoji': MessageEntity.messageEntityEmoji, 'messageEntityEmoji': MessageEntity.messageEntityEmoji,
'messageEntityHighlight': MessageEntity.messageEntityHighlight, 'messageEntityHighlight': MessageEntity.messageEntityHighlight,
'messageEntityLinebreak': MessageEntity.messageEntityLinebreak, 'messageEntityLinebreak': MessageEntity.messageEntityLinebreak,
@ -11073,7 +11239,7 @@ export type UploadGetFile = {
precise?: boolean, precise?: boolean,
cdn_supported?: boolean, cdn_supported?: boolean,
location: InputFileLocation, location: InputFileLocation,
offset: number, offset: string | number,
limit: number limit: number
}; };
@ -11216,7 +11382,9 @@ export type AccountSetPrivacy = {
}; };
export type AccountDeleteAccount = { export type AccountDeleteAccount = {
reason: string flags?: number,
reason: string,
password?: InputCheckPasswordSRP
}; };
export type AccountGetAccountTTL = { export type AccountGetAccountTTL = {
@ -11493,12 +11661,13 @@ export type MessagesSearchGlobal = {
export type MessagesReorderStickerSets = { export type MessagesReorderStickerSets = {
flags?: number, flags?: number,
masks?: boolean, masks?: boolean,
emojis?: boolean,
order: Array<string | number> order: Array<string | number>
}; };
export type MessagesGetDocumentByHash = { export type MessagesGetDocumentByHash = {
sha256: Uint8Array, sha256: Uint8Array,
size: number, size: string | number,
mime_type: string mime_type: string
}; };
@ -11680,6 +11849,7 @@ export type MessagesClearRecentStickers = {
export type MessagesGetArchivedStickers = { export type MessagesGetArchivedStickers = {
flags?: number, flags?: number,
masks?: boolean, masks?: boolean,
emojis?: boolean,
offset_id: string | number, offset_id: string | number,
limit: number limit: number
}; };
@ -11797,8 +11967,7 @@ export type UploadGetWebFile = {
export type PaymentsGetPaymentForm = { export type PaymentsGetPaymentForm = {
flags?: number, flags?: number,
peer: InputPeer, invoice: InputInvoice,
msg_id: number,
theme_params?: DataJSON theme_params?: DataJSON
}; };
@ -11810,16 +11979,14 @@ export type PaymentsGetPaymentReceipt = {
export type PaymentsValidateRequestedInfo = { export type PaymentsValidateRequestedInfo = {
flags?: number, flags?: number,
save?: boolean, save?: boolean,
peer: InputPeer, invoice: InputInvoice,
msg_id: number,
info: PaymentRequestedInfo info: PaymentRequestedInfo
}; };
export type PaymentsSendPaymentForm = { export type PaymentsSendPaymentForm = {
flags?: number, flags?: number,
form_id: string | number, form_id: string | number,
peer: InputPeer, invoice: InputInvoice,
msg_id: number,
requested_info_id?: string, requested_info_id?: string,
shipping_option_id?: string, shipping_option_id?: string,
credentials: InputPaymentCredentials, credentials: InputPaymentCredentials,
@ -11941,7 +12108,7 @@ export type PhoneSaveCallDebug = {
export type UploadGetCdnFile = { export type UploadGetCdnFile = {
file_token: Uint8Array, file_token: Uint8Array,
offset: number, offset: string | number,
limit: number limit: number
}; };
@ -11994,7 +12161,7 @@ export type ChannelsGetAdminLog = {
export type UploadGetCdnFileHashes = { export type UploadGetCdnFileHashes = {
file_token: Uint8Array, file_token: Uint8Array,
offset: number offset: string | number
}; };
export type MessagesSendScreenshotNotification = { export type MessagesSendScreenshotNotification = {
@ -12100,7 +12267,7 @@ export type MessagesSearchStickerSets = {
export type UploadGetFileHashes = { export type UploadGetFileHashes = {
location: InputFileLocation, location: InputFileLocation,
offset: number offset: string | number
}; };
export type HelpGetTermsOfServiceUpdate = { export type HelpGetTermsOfServiceUpdate = {
@ -12187,7 +12354,7 @@ export type AccountInitTakeoutSession = {
message_megagroups?: boolean, message_megagroups?: boolean,
message_channels?: boolean, message_channels?: boolean,
files?: boolean, files?: boolean,
file_max_size?: number file_max_size?: string | number
}; };
export type AccountFinishTakeoutSession = { export type AccountFinishTakeoutSession = {
@ -13136,7 +13303,8 @@ export type MessagesRequestWebView = {
url?: string, url?: string,
start_param?: string, start_param?: string,
theme_params?: DataJSON, theme_params?: DataJSON,
reply_to_msg_id?: number reply_to_msg_id?: number,
send_as?: InputPeer
}; };
export type MessagesProlongWebView = { export type MessagesProlongWebView = {
@ -13145,7 +13313,8 @@ export type MessagesProlongWebView = {
peer: InputPeer, peer: InputPeer,
bot: InputUser, bot: InputUser,
query_id: string | number, query_id: string | number,
reply_to_msg_id?: number reply_to_msg_id?: number,
send_as?: InputPeer
}; };
export type MessagesRequestSimpleWebView = { export type MessagesRequestSimpleWebView = {
@ -13199,6 +13368,61 @@ export type BotsSetBotGroupDefaultAdminRights = {
admin_rights: ChatAdminRights admin_rights: ChatAdminRights
}; };
export type PhoneSaveCallLog = {
peer: InputPhoneCall,
file: InputFile
};
export type ChannelsToggleJoinToSend = {
channel: InputChannel,
enabled: boolean
};
export type ChannelsToggleJoinRequest = {
channel: InputChannel,
enabled: boolean
};
export type PaymentsExportInvoice = {
invoice_media: InputMedia
};
export type MessagesTranscribeAudio = {
peer: InputPeer,
msg_id: number
};
export type MessagesRateTranscribedAudio = {
peer: InputPeer,
msg_id: number,
transcription_id: string | number,
good: boolean
};
export type PaymentsAssignAppStoreTransaction = {
flags?: number,
restore?: boolean,
receipt: Uint8Array
};
export type PaymentsAssignPlayMarketTransaction = {
purchase_token: string
};
export type PaymentsCanPurchasePremium = {
};
export type HelpGetPremiumPromo = {
};
export type PaymentsRequestRecurringPayment = {
user_id: InputUser,
recurring_init_charge: string,
invoice_media: InputMedia
};
export interface MethodDeclMap { export interface MethodDeclMap {
'invokeAfterMsg': {req: InvokeAfterMsg, res: any}, 'invokeAfterMsg': {req: InvokeAfterMsg, res: any},
'invokeAfterMsgs': {req: InvokeAfterMsgs, res: any}, 'invokeAfterMsgs': {req: InvokeAfterMsgs, res: any},
@ -13634,5 +13858,16 @@ export interface MethodDeclMap {
'account.uploadRingtone': {req: AccountUploadRingtone, res: Document}, 'account.uploadRingtone': {req: AccountUploadRingtone, res: Document},
'bots.setBotBroadcastDefaultAdminRights': {req: BotsSetBotBroadcastDefaultAdminRights, res: boolean}, 'bots.setBotBroadcastDefaultAdminRights': {req: BotsSetBotBroadcastDefaultAdminRights, res: boolean},
'bots.setBotGroupDefaultAdminRights': {req: BotsSetBotGroupDefaultAdminRights, res: boolean}, 'bots.setBotGroupDefaultAdminRights': {req: BotsSetBotGroupDefaultAdminRights, res: boolean},
'phone.saveCallLog': {req: PhoneSaveCallLog, res: boolean},
'channels.toggleJoinToSend': {req: ChannelsToggleJoinToSend, res: Updates},
'channels.toggleJoinRequest': {req: ChannelsToggleJoinRequest, res: Updates},
'payments.exportInvoice': {req: PaymentsExportInvoice, res: PaymentsExportedInvoice},
'messages.transcribeAudio': {req: MessagesTranscribeAudio, res: MessagesTranscribedAudio},
'messages.rateTranscribedAudio': {req: MessagesRateTranscribedAudio, res: boolean},
'payments.assignAppStoreTransaction': {req: PaymentsAssignAppStoreTransaction, res: Updates},
'payments.assignPlayMarketTransaction': {req: PaymentsAssignPlayMarketTransaction, res: Updates},
'payments.canPurchasePremium': {req: PaymentsCanPurchasePremium, res: boolean},
'help.getPremiumPromo': {req: HelpGetPremiumPromo, res: HelpPremiumPromo},
'payments.requestRecurringPayment': {req: PaymentsRequestRecurringPayment, res: Updates},
} }

55
src/lib/appManagers/appImManager.ts

@ -24,7 +24,7 @@ import { MOUNT_CLASS_TO } from '../../config/debug';
import appNavigationController from '../../components/appNavigationController'; import appNavigationController from '../../components/appNavigationController';
import AppPrivateSearchTab from '../../components/sidebarRight/tabs/search'; import AppPrivateSearchTab from '../../components/sidebarRight/tabs/search';
import I18n, { i18n, join, LangPackKey } from '../langPack'; import I18n, { i18n, join, LangPackKey } from '../langPack';
import { ChatFull, ChatInvite, ChatParticipant, ChatParticipants, SendMessageAction } from '../../layer'; import { ChatFull, ChatInvite, ChatParticipant, ChatParticipants, Message, SendMessageAction } from '../../layer';
import { hslaStringToHex } from '../../helpers/color'; import { hslaStringToHex } from '../../helpers/color';
import PeerTitle from '../../components/peerTitle'; import PeerTitle from '../../components/peerTitle';
import PopupPeer from '../../components/popups/peer'; import PopupPeer from '../../components/popups/peer';
@ -89,6 +89,7 @@ import getFilesFromEvent from '../../helpers/files/getFilesFromEvent';
import apiManagerProxy from '../mtproto/mtprotoworker'; import apiManagerProxy from '../mtproto/mtprotoworker';
import wrapPeerTitle from '../../components/wrappers/peerTitle'; import wrapPeerTitle from '../../components/wrappers/peerTitle';
import appRuntimeManager from './appRuntimeManager'; import appRuntimeManager from './appRuntimeManager';
import PopupPayment from '../../components/popups/payment';
export const CHAT_ANIMATION_GROUP = 'chat'; export const CHAT_ANIMATION_GROUP = 'chat';
@ -486,6 +487,20 @@ export class AppImManager extends EventListenerBase<{
} }
}); });
// * t.me/invoice/asdasdad
// * t.me/$asdasdad
this.addAnchorListener<{pathnameParams: ['invoice', string] | string}>({
name: 'invoice',
callback: ({pathnameParams}) => {
const link: InternalLink = {
_: INTERNAL_LINK_TYPE.INVOICE,
slug: pathnameParams.length > 1 ? pathnameParams[1] : pathnameParams[0].slice(1)
};
this.processInternalLink(link);
}
});
// Support old t.me/joinchat/asd and new t.me/+asd // Support old t.me/joinchat/asd and new t.me/+asd
this.addAnchorListener<{pathnameParams: ['joinchat', string]}>({ this.addAnchorListener<{pathnameParams: ['joinchat', string]}>({
name: 'joinchat', name: 'joinchat',
@ -619,6 +634,19 @@ export class AppImManager extends EventListenerBase<{
} }
}); });
this.addAnchorListener<{
uriParams: {
slug: string
}
}>({
name: 'invoice',
protocol: 'tg',
callback: ({uriParams}) => {
const link = this.makeLink(INTERNAL_LINK_TYPE.INVOICE, uriParams);
this.processInternalLink(link);
}
});
['joinchat' as const, 'join' as const].forEach((name) => { ['joinchat' as const, 'join' as const].forEach((name) => {
this.addAnchorListener<{ this.addAnchorListener<{
uriParams: { uriParams: {
@ -841,6 +869,29 @@ export class AppImManager extends EventListenerBase<{
break; break;
} }
case INTERNAL_LINK_TYPE.INVOICE: {
this.managers.appPaymentsManager.getInputInvoiceBySlug(link.slug).then((inputInvoice) => {
this.managers.appPaymentsManager.getPaymentForm(inputInvoice).then((paymentForm) => {
// const message: Message.message = {
// _: 'message',
// date: 0,
// id: 0,
// peerId: 0,
// peer_id: undefined,
// message: '',
// media: {
// _: 'messageMediaInvoice',
// currency: paymentForm.invoice.currency,
// description: paymentForm.description,
// }
// };
new PopupPayment(undefined, inputInvoice, paymentForm);
});
});
break;
}
default: { default: {
this.log.warn('Not supported internal link:', link); this.log.warn('Not supported internal link:', link);
break; break;
@ -858,7 +909,7 @@ export class AppImManager extends EventListenerBase<{
private addAnchorListener<Params extends {pathnameParams?: any, uriParams?: any}>(options: { private addAnchorListener<Params extends {pathnameParams?: any, uriParams?: any}>(options: {
name: 'showMaskedAlert' | 'execBotCommand' | 'searchByHashtag' | 'addstickers' | 'im' | name: 'showMaskedAlert' | 'execBotCommand' | 'searchByHashtag' | 'addstickers' | 'im' |
'resolve' | 'privatepost' | 'addstickers' | 'voicechat' | 'joinchat' | 'join', 'resolve' | 'privatepost' | 'addstickers' | 'voicechat' | 'joinchat' | 'join' | 'invoice',
protocol?: 'tg', protocol?: 'tg',
callback: (params: Params, element?: HTMLAnchorElement) => boolean | any, callback: (params: Params, element?: HTMLAnchorElement) => boolean | any,
noPathnameParams?: boolean, noPathnameParams?: boolean,

31
src/lib/appManagers/appPaymentsManager.ts

@ -4,15 +4,29 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE * https://github.com/morethanwords/tweb/blob/master/LICENSE
*/ */
import { InputPaymentCredentials, PaymentRequestedInfo, PaymentsPaymentForm } from "../../layer"; import { InputInvoice, InputPaymentCredentials, PaymentRequestedInfo, PaymentsPaymentForm } from "../../layer";
import { AppManager } from "./manager"; import { AppManager } from "./manager";
import getServerMessageId from "./utils/messageId/getServerMessageId"; import getServerMessageId from "./utils/messageId/getServerMessageId";
export default class AppPaymentsManager extends AppManager { export default class AppPaymentsManager extends AppManager {
public getPaymentForm(peerId: PeerId, mid: number) { public getInputInvoiceBySlug(slug: string): InputInvoice.inputInvoiceSlug {
return this.apiManager.invokeApi('payments.getPaymentForm', { return {
_: 'inputInvoiceSlug',
slug
};
}
public getInputInvoiceByPeerId(peerId: PeerId, mid: number): InputInvoice.inputInvoiceMessage {
return {
_: 'inputInvoiceMessage',
peer: this.appPeersManager.getInputPeerById(peerId), peer: this.appPeersManager.getInputPeerById(peerId),
msg_id: getServerMessageId(mid) msg_id: getServerMessageId(mid)
};
}
public getPaymentForm(invoice: InputInvoice) {
return this.apiManager.invokeApi('payments.getPaymentForm', {
invoice
}).then((paymentForm) => { }).then((paymentForm) => {
this.appUsersManager.saveApiUsers(paymentForm.users); this.appUsersManager.saveApiUsers(paymentForm.users);
@ -31,18 +45,16 @@ export default class AppPaymentsManager extends AppManager {
}); });
} }
public validateRequestedInfo(peerId: PeerId, mid: number, info: PaymentRequestedInfo, save?: boolean) { public validateRequestedInfo(invoice: InputInvoice, info: PaymentRequestedInfo, save?: boolean) {
return this.apiManager.invokeApi('payments.validateRequestedInfo', { return this.apiManager.invokeApi('payments.validateRequestedInfo', {
save, save,
peer: this.appPeersManager.getInputPeerById(peerId), invoice,
msg_id: getServerMessageId(mid),
info info
}); });
} }
public sendPaymentForm( public sendPaymentForm(
peerId: PeerId, invoice: InputInvoice,
mid: number,
formId: PaymentsPaymentForm['form_id'], formId: PaymentsPaymentForm['form_id'],
requestedInfoId: string, requestedInfoId: string,
shippingOptionId: string, shippingOptionId: string,
@ -51,8 +63,7 @@ export default class AppPaymentsManager extends AppManager {
) { ) {
return this.apiManager.invokeApi('payments.sendPaymentForm', { return this.apiManager.invokeApi('payments.sendPaymentForm', {
form_id: formId, form_id: formId,
peer: this.appPeersManager.getInputPeerById(peerId), invoice,
msg_id: getServerMessageId(mid),
requested_info_id: requestedInfoId, requested_info_id: requestedInfoId,
shipping_option_id: shippingOptionId, shipping_option_id: shippingOptionId,
credentials, credentials,

13
src/lib/appManagers/internalLink.ts

@ -10,10 +10,11 @@ export enum INTERNAL_LINK_TYPE {
STICKER_SET, STICKER_SET,
JOIN_CHAT, JOIN_CHAT,
VOICE_CHAT, VOICE_CHAT,
USER_PHONE_NUMBER USER_PHONE_NUMBER,
INVOICE
}; };
export type InternalLink = InternalLink.InternalLinkMessage | InternalLink.InternalLinkPrivatePost | InternalLink.InternalLinkStickerSet | InternalLink.InternalLinkJoinChat | InternalLink.InternalLinkVoiceChat | InternalLink.InternalLinkUserPhoneNumber; export type InternalLink = InternalLink.InternalLinkMessage | InternalLink.InternalLinkPrivatePost | InternalLink.InternalLinkStickerSet | InternalLink.InternalLinkJoinChat | InternalLink.InternalLinkVoiceChat | InternalLink.InternalLinkUserPhoneNumber | InternalLink.InternalLinkInvoice;
export namespace InternalLink { export namespace InternalLink {
export interface InternalLinkMessage { export interface InternalLinkMessage {
@ -56,6 +57,11 @@ export namespace InternalLink {
_: INTERNAL_LINK_TYPE.USER_PHONE_NUMBER, _: INTERNAL_LINK_TYPE.USER_PHONE_NUMBER,
phone: string phone: string
} }
export interface InternalLinkInvoice {
_: INTERNAL_LINK_TYPE.INVOICE,
slug: string
}
} }
export type InternalLinkTypeMap = { export type InternalLinkTypeMap = {
@ -64,5 +70,6 @@ export type InternalLinkTypeMap = {
[INTERNAL_LINK_TYPE.STICKER_SET]: InternalLink.InternalLinkStickerSet, [INTERNAL_LINK_TYPE.STICKER_SET]: InternalLink.InternalLinkStickerSet,
[INTERNAL_LINK_TYPE.JOIN_CHAT]: InternalLink.InternalLinkJoinChat, [INTERNAL_LINK_TYPE.JOIN_CHAT]: InternalLink.InternalLinkJoinChat,
[INTERNAL_LINK_TYPE.VOICE_CHAT]: InternalLink.InternalLinkVoiceChat, [INTERNAL_LINK_TYPE.VOICE_CHAT]: InternalLink.InternalLinkVoiceChat,
[INTERNAL_LINK_TYPE.USER_PHONE_NUMBER]: InternalLink.InternalLinkUserPhoneNumber [INTERNAL_LINK_TYPE.USER_PHONE_NUMBER]: InternalLink.InternalLinkUserPhoneNumber,
[INTERNAL_LINK_TYPE.INVOICE]: InternalLink.InternalLinkInvoice
}; };

2
src/lib/mtproto/schema.ts

File diff suppressed because one or more lines are too long

8
src/lib/richTextProcessor/wrapUrl.ts

@ -18,6 +18,12 @@ export default function wrapUrl(url: string, unsafe?: number | boolean): {url: s
url = 'tg://unsafe_url?url=' + encodeURIComponent(url); url = 'tg://unsafe_url?url=' + encodeURIComponent(url);
} else */if((tgMeMatch = url.match(/^(?:https?:\/\/)?t(?:elegram)?\.me\/(.+)/))) { } else */if((tgMeMatch = url.match(/^(?:https?:\/\/)?t(?:elegram)?\.me\/(.+)/))) {
const fullPath = tgMeMatch[1]; const fullPath = tgMeMatch[1];
const path = fullPath.split('/');
if(path[0] && path[0][0] === '$' && path[0].length > 1) {
onclick = 'invoice';
return {url, onclick};
}
// second regexp is for phone numbers (t.me/+38050...) // second regexp is for phone numbers (t.me/+38050...)
if(/^\W/.test(fullPath) && !PHONE_NUMBER_REG_EXP.test(fullPath)) { if(/^\W/.test(fullPath) && !PHONE_NUMBER_REG_EXP.test(fullPath)) {
@ -25,11 +31,11 @@ export default function wrapUrl(url: string, unsafe?: number | boolean): {url: s
return {url, onclick}; return {url, onclick};
} }
const path = fullPath.split('/');
switch(path[0]) { switch(path[0]) {
case 'joinchat': case 'joinchat':
case 'addstickers': case 'addstickers':
case 'voicechat': case 'voicechat':
case 'invoice':
onclick = path[0]; onclick = path[0];
break; break;

4
src/scripts/in/schema.json

File diff suppressed because one or more lines are too long

2
src/scripts/out/schema.json

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save